首先我们先来看什么是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