首先我們先來看什么是python中的反射?
反射它可以把字符串映射到實例的變量或者實例的方法然后可以去執行調用、修改等操作。它有四個重要的方法:
- getattr 獲取指定字符串名稱的對象屬性
- setattr 為對象設置一個對象
- hasattr 判斷對象是否有對應的對象(字符串)
- delattr 刪除指定屬性
這里我只講2個常用的設置屬性和獲取屬性。
如圖:
定義了一個GetData()類,里面設置了一個類屬性,cookie=None,然后再用setattr函數為對象GetData里面cookie屬性設置了新值,即COOKIE=餅干,最后再用getattr函數取出里面的值。從中可以看出,這是屬性值替換的過程。
上面講了反射的概念,下面來說說實際運用,如何使用反射解決數據依賴問題。
測試目標,登錄成功后,查看我的精品界面。且斷言右上角頭像的學生姓名。具體界面如下圖:
首先要查看我的精品界面,必須登錄。如下圖登錄接口代碼:
首先導入了GetData這個類,然后登錄成功后,判斷如果登錄成功后有cookie就用,setattr(GetData,'cookie',login_res.cookies),給GetData里面的cookie=None的類屬性進行設置新屬性。
要用的時候就用getattr(GetData,'cookie'),取出里面的屬性值。如下圖我的精品頁面傳遞登錄的cookie。
全部代碼如下:
import unittest from API_AUTO.tools.http_request import HttpRequest import re from API_AUTO.tools.get_data import GetData class TestHttp(unittest.TestCase): def setUp(self): pass def test_Normal_login(self): '''正常登錄''' url = 'https://www.ketangpai.com/UserApi/login' data = { "email": "1489088761@qq.com", "password": "A137898", "remember": 0 } headers = { "User-Agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded", } login_res = HttpRequest().http_request('post', url, data, headers,verify=False) if login_res.cookies: '''如果有cookie就進行替換,if后面的條件語句值不為空,即條件成立''' setattr(GetData, 'cookie', login_res.cookies) # 反射 try: self.assertEqual(1, login_res.json()['status'], '登錄失敗') except AssertionError as e: print('登錄錯誤{}'.format(e)) raise e def test_mooc(self): '''我的精品頁面''' url1 = 'https://www.ketangpai.com/Mooc/Mooc/index.html' headers1 = { "Referer": "https: // www.ketangpai.com / Main / index.html", "User-Agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36", } res1 = HttpRequest().http_request('get', url=url1, headers=headers1, cookies=getattr(GetData, 'cookie'),verify=False) #取值 try: pattern = '<img class=.*?\salt=(".*?").*?>' regular = re.search(pattern, res1.text, re.S) self.assertEqual('夏茂傑', eval(regular.group(1)), '進入我的界面失敗') except Exception as e: print('錯誤是{}'.format(e)) raise e def tearDown(self): pass if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(TestHttp("test_Normal_login")) suite.addTest(TestHttp("test_mooc")) runner = unittest.TextTestRunner() runner.run(suite)
登錄獲取token,參數后傳到下個接口的請求頭里面(可以直接復制運行):
import requests import unittest class GetToken(): token = None class TestApi(unittest.TestCase): def test_Login(self): self.login_url = 'http://49.235.92.12:9000/api/v1/login' self.login_data = {"username": "test", "password": "123456"} self.login_header = {"Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", } self.login_res = requests.post(self.login_url, self.login_data, self.login_header) # print(self.login_res.content) print(eval(self.login_res.text)['token']) if self.login_res.text: setattr(GetToken, 'token', self.login_res.text) self.assertEqual(0,eval(self.login_res.text)['code'],'登錄失敗') def test_info(self): self.info_url = 'http://49.235.92.12:9000/info' self.info_header = { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Authorization": 'Token' + ' ' + eval(getattr(GetToken, 'token'))['token'] } self.res = requests.get(url=self.info_url, headers=self.info_header) print(self.res.request.headers['Authorization']) self.assertEqual(0,eval(self.res.text)['code'],'信息獲取失敗') if __name__ == '__main__': unittest.main()
傳遞的請求頭格式為這樣:
Authorization: Token 24d1058ddf3b2492440d4a9b063fe299c9706a36