1. 前言

  • 为了提高复用性,我们在写测试用例的时候,会用到不同的fixture,比如:最常见的登录操作,大部分的用例的前置条件都是登录
  • 假设不同的用例想登录不同的测试账号,那么登录 fixture 就不能把账号写死,需要通过传参的方式来完成登录操作

2. 案例一:传单个参数

  1. import pytest
  2. @pytest.fixture()
  3. def login(request):
  4. name = request.param
  5. print(f"== 账号是:{name} ==")
  6. return name
  7. data = ["pyy1", "polo"]
  8. ids = [f"login_test_name is:{name}" for name in data]
  9. @pytest.mark.parametrize("login", data, ids=ids, indirect=True)
  10. def test_name(login):
  11. print(f" 测试用例的登录账号是:{login} ")

2.1 执行结果

  1. collecting ... collected 2 items
  2. 10fixture_request.py::test_name[login_test_name is:pyy1] == 账号是:pyy1 ==
  3. PASSED [ 50%] 测试用例的登录账号是:pyy1
  4. 10fixture_request.py::test_name[login_test_name is:polo] == 账号是:polo ==
  5. PASSED [100%] 测试用例的登录账号是:polo

2.2 知识点

  • 添加 indirect=True 参数是为了把 login 当成一个函数去执行,而不是一个参数,并且将 data 当做参数传入函数
  • def test_name(login) ,这里的 login 是获取 fixture 返回的值

3. 案例二:多个参数

  1. @pytest.fixture()
  2. def logins(request):
  3. param = request.param
  4. print(f"账号是:{param['username']},密码是:{param['pwd']}")
  5. return param
  6. data = [
  7. {"username": "name1", "pwd": "pwd1"},
  8. {"username": "name2", "pwd": "pwd2"},
  9. ]
  10. @pytest.mark.parametrize("logins", data, indirect=True)
  11. def test_name_pwd(logins):
  12. print(f"账号是:{logins['username']},密码是:{logins['pwd']}")

3.1 执行结果

  1. 10fixture_request.py::test_name_pwd[logins0] 账号是:name1,密码是:pwd1
  2. PASSED [ 50%]账号是:name1,密码是:pwd1
  3. 10fixture_request.py::test_name_pwd[logins1] 账号是:name2,密码是:pwd2
  4. PASSED [100%]账号是:name2,密码是:pwd2

3.2 知识点

如果需要传多个参数,需要通过字典去传

4. 案例三:多个fixture(只加一个装饰器)

这种更常用

  1. # 多个fixture
  2. @pytest.fixture(scope="module")
  3. def input_user(request):
  4. user = request.param
  5. print("登录账户:%s" % user)
  6. return user
  7. @pytest.fixture(scope="module")
  8. def input_psw(request):
  9. psw = request.param
  10. print("登录密码:%s" % psw)
  11. return psw
  12. data = [
  13. ("name1", "pwd1"),
  14. ("name2", "pwd2")
  15. ]
  16. @pytest.mark.parametrize("input_user,input_psw", data, indirect=True)
  17. def test_more_fixture(input_user, input_psw):
  18. print("fixture返回的内容:", input_user, input_psw)

4.1 执行结果

  1. 10fixture_request.py::test_more_fixture[name1-pwd1] 登录账户:name1
  2. 登录密码:pwd1
  3. PASSED [ 50%]fixture返回的内容: name1 pwd1
  4. 10fixture_request.py::test_more_fixture[name2-pwd2] 登录账户:name2
  5. 登录密码:pwd2
  6. PASSED [100%]fixture返回的内容: name2 pwd2

5. 案例四:多个fixture(叠加装饰器)

  1. # 多个fixture
  2. @pytest.fixture(scope="function")
  3. def input_user(request):
  4. user = request.param
  5. print("登录账户:%s" % user)
  6. return user
  7. @pytest.fixture(scope="function")
  8. def input_psw(request):
  9. psw = request.param
  10. print("登录密码:%s" % psw)
  11. return psw
  12. name = ["name1", "name2"]
  13. pwd = ["pwd1", "pwd2"]
  14. @pytest.mark.parametrize("input_user", name, indirect=True)
  15. @pytest.mark.parametrize("input_psw", pwd, indirect=True)
  16. def test_more_fixture(input_user, input_psw):
  17. print("fixture返回的内容:", input_user, input_psw)

5.1 执行结果

  1. 10fixture_request.py::test_more_fixture[pwd1-name1] 登录账户:name1
  2. 登录密码:pwd1
  3. PASSED [ 25%]fixture返回的内容: name1 pwd1
  4. 10fixture_request.py::test_more_fixture[pwd1-name2] 登录账户:name2
  5. 登录密码:pwd1
  6. PASSED [ 50%]fixture返回的内容: name2 pwd1
  7. 10fixture_request.py::test_more_fixture[pwd2-name1] 登录账户:name1
  8. 登录密码:pwd2
  9. PASSED [ 75%]fixture返回的内容: name1 pwd2
  10. 10fixture_request.py::test_more_fixture[pwd2-name2] 登录账户:name2
  11. 登录密码:pwd2
  12. PASSED [100%]fixture返回的内容: name2 pwd2

测试用例数=2*2=4条