pytest框架---参数化(Parametrize)
pytest.mark.parametrize 是一个“用例复印机 填表机”。pytest.mark.parametrize(case_info,[{user:admin},{user:guest},{user:test}],ids[正常登录,密码错误,账号不存在])deftest_login(self,case_info):...# 写了两个名字 username, passwordpytest.mark.parametrize(username, password,[(admin,123),(guest,456)])deftest_login(username,password):# ⬅️ 这里必须正好有两个形参且名字完全匹配print(username,password)pytest.mark.parametrize 是一个“用例复印机 填表机”。你在装饰器里传入一个列表List列表里有几条数据它就把下面那个测试函数复印出几份独立的副本。每一份副本都会把列表里的对应数据自动填入测试函数的参数中。关键是这些副本在 Pytest 看来是完全不同的测试用例拥有独立的测试结果、独立的执行顺序、独立的失败/通过状态。第一个参数pytest.mark.parametrize(‘password’, 它的第一个参数要加引号pytest.mark.parametrize的第一个参数和test_login中参数名字一样就可以了随便用什么名字只要一样就可以用例名称针对你这段具体的代码如果写 ids 参数用例名称将会是test_login[正常登录]test_login[密码错误]test_login[账号不存在]如果不写 ids 参数Pytest 会自动使用参数值的原始字符串表示repr 作为用例名称。控制台显示的用例名称将会是test_login[{‘user’: ‘admin’}]test_login[{‘user’: ‘guest’}]test_login[{‘user’: ‘test’}]‘case_info’ 和 列表的关系是“遍历赋值”关系Pytest 会遍历 列表把列表里的【每一个元素】依次赋值给【名为 case_info 的参数】每赋值一次就生成并执行一条全新的测试用例第二个参数pytest.mark.parametrize 的第二个参数不一定是列表list它只需要是一个可迭代对象Iterable即可pytest.fixturedefuser_token(request):# ① 定义了一个 Fixture但它多了一个 request 参数usernamerequest.param# ② 从 request 对象中取出参数化传入的值returnget_token(username)# ③ 调用函数把 admin 变成真正的 token 字符串pytest.mark.parametrize(user_token,[admin,guest],indirectTrue)# ④ 关键indirectTruedeftest_api(user_token):# ⑤ 测试函数接收的参数名也叫 user_tokenprint(user_token)# ⑥ 打印的是 token而不是 adminindirectTrue这是理解这段代码的钥匙。如果没有 indirectTruePytest 会直接把 ‘admin’ 和 ‘guest’ 这两个字符串赋值给 test_api 的 user_token 参数打印出来的就是 admin。加了 indirectTrue 后传递路径发生了“转向”普通情况无 indirect数据 ‘admin’ → 直接进入 test_api(user_token)。加上 indirectTrue数据 ‘admin’ → 先进入 pytest.fixture 定义的 user_token(request) 函数 → 经过加工生成 token → 再把加工结果传给 test_api(user_token)。执行流程时间线Pytest 收集阶段扫描到 parametrize发现有一个数据列表 [‘admin’, ‘guest’]且指定了 indirectTrue。查找 FixturePytest 看到参数名是 user_token于是去查找名字叫 user_token 的 Fixture即上面那个被 pytest.fixture 装饰的函数。第 1 轮执行‘admin’Pytest 把 ‘admin’ 塞进 Fixture 的 request.param 中。执行 Fixture 函数体内的代码username request.param此时 username 是 ‘admin’。调用 get_token(‘admin’)假设返回 “token_for_admin_123”。Fixture 把这个 “token_for_admin_123” 返回给 Pytest。执行测试函数Pytest 带着 “token_for_admin_123”调用 test_api(user_token)此时 user_token 的值就是那串长长的 token。打印输出 token_for_admin_123。第 2 轮执行‘guest’重复步骤 3~4但原始数据换成 ‘guest’打印出对应的 guest token。不明白username 是 ‘admin’ 为什么是admin request.param 还有request. 什么为什么 username 是 ‘admin’ 因为 pytest.mark.parametrize 的数据列表里第一个元素就是字符串 ‘admin’Pytest 把它原封不动地塞进了 request.param 里。request. 还有什么 request 是一个内置的“万能上下文对象”除了 .param它还有超级多有用的属性比如 .node、.config、.module 等。