前面章节我们介绍了fixture的作用,及pytest中自定义测试用例的前置和后置操作,来实现部分用例的前后置。
今天我们来介绍fixture的调用及执行顺序。
1.1 函数/参数引用
将fixture名称作为测试用例函数/方法的参数。首先我们来理解和区分两个概念:
函数引用:测试类中测试方法形参是测试类外被@pytest.fixture()标记的测试函数。
参数引用:测试类中测试方法形参是当前测试类中被@pytest.fixture()标记的方法。
示例代码1:函数引用
"""Pytest单元测试框架fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
class TestLogin:
def test_Login_01(self,logout):
time.sleep = 3
print("------Hello,点我退出\n")
运行结果:
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 17:03 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 2 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------logout
------Hello,点我退出
PASSED
============================== 2 passed in 0.03s ==============================
Process finished with exit code 0
示例代码2:参数引用
import pytest
import time
class TestLogin:
def test_Login_02(self,restart):
time.sleep = 3
print("------Hello,点我重启\n")
@pytest.fixture()
def restart(self):
time.sleep = 3
print("------Hello,test_Login_03\n")
def test_Login_04(self):
time.sleep = 3
print("Hello,I'm 999 ITBrickMover\n")
运行结果:
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 17:04 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 2 items
test_login.py::TestLogin::test_Login_02 ------Hello,test_Login_03
------Hello,点我重启
PASSED
test_login.py::TestLogin::test_Login_04 Hello,I'm 999 ITBrickMover
PASSED
============================== 2 passed in 0.03s ==============================
Process finished with exit code 0
1.2 加装饰器:
@pytest.mark.userfixtures
(fixture.name,…)
(一)测试用例上加装饰器
(1)可以有多个fixture,在有多个fixture参数时,放在底层的先执行,放在上层的后执行。即执行顺序与userfixture放置的上下顺序相反。
示例代码:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
@pytest.mark.usefixtures("logout")
@pytest.mark.usefixtures("login")
class TestLogin:
def test_Login_01(self):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
def test_Login_02(self):
time.sleep = 3
print("------Hello,I'm 997 ITBrickMover\n")
运行结果:先调用login再调用logout
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pychar m/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 21:18 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 3 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------login
------logout
------Hello,I'm 996 ITBrickMover
PASSED
test_login.py::TestLogin::test_Login_02 ------login
------logout
------Hello,I'm 997 ITBrickMover
PASSED
============================== 3 passed in 0.02s ==============================
Process finished with exit code 0
(2)可以有多个fixture,在有多个fixture参数时,放在前面的先执行,放在后面的后执行。即执行顺序与userfixture后面引用的参数顺序对应。
示例代码2:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
class TestLogin:
def test_Login_01(self,logout):
time.sleep = 3
print("------Hello,点我退出\n")
@pytest.mark.usefixtures()
def test_Login_02(self,logout,login):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
运行结果:先调用logout再调用login
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 21:08 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 3 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------logout
------Hello,点我退出
PASSED
test_login.py::TestLogin::test_Login_02 ------logout
------login
------Hello,I'm 996 ITBrickMover
PASSED
============================== 3 passed in 0.02s ==============================
Process finished with exit code 0
(3)同时有装饰器和引用,装饰器先执行。
示例代码:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
@pytest.mark.usefixtures("logout")
class TestLogin:
def test_Login_01(self,login):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
def test_Login_02(self):
time.sleep = 3
print("------Hello,I'm 997 ITBrickMover\n")
运行结果:同时有装饰器和引用,装饰器先执行。
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 22:10 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 3 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------logout
------login
------Hello,I'm 996 ITBrickMover
PASSED
test_login.py::TestLogin::test_Login_02 ------logout
------Hello,I'm 997 ITBrickMover
PASSED
============================== 3 passed in 0.02s ==============================
Process finished with exit code 0
(二)测试类上加装饰器
(1)类中所有测试用例都会调用该fixture
示例代码:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
@pytest.mark.usefixtures("login")
class TestLogin:
def test_Login_01(self):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
def test_Login_02(self,logout):
time.sleep = 3
print("------Hello,I'm 997 ITBrickMover\n")
运行结果:类中所有测试用例都会调用该fixture,同时有装饰器和引用,装饰器先执行。
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 22:43 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 3 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------login
------Hello,I'm 996 ITBrickMover
PASSED
test_login.py::TestLogin::test_Login_02 ------login
------logout
------Hello,I'm 997 ITBrickMover
PASSED
============================== 3 passed in 0.02s ==============================
Process finished with exit code 0
(2)方法和类上都有装饰器,方法上装饰器先执行
示例代码:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
def test_login(login):
print("------test_login")
@pytest.mark.usefixtures("login")
class TestLogin:
def test_Login_01(self):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
@pytest.mark.usefixtures("logout")
def test_Login_02(self):
time.sleep = 3
print("------Hello,I'm 997 ITBrickMover\n")
运行结果:方法和类上都有装饰器,方法上装饰器先执行
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 23:13 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 3 items
test_login.py::test_login ------login
------test_login
PASSED
test_login.py::TestLogin::test_Login_01 ------login
------Hello,I'm 996 ITBrickMover
PASSED
test_login.py::TestLogin::test_Login_02 ------logout
------login
------Hello,I'm 997 ITBrickMover
PASSED
============================== 3 passed in 0.02s ==============================
Process finished with exit code 0
1.3自动适配:fixture设置autouse=True 加装饰器
(1)影响作用域内所有用例
示例代码:
"""Pytest单元测试框架:fixture的使用"""
import pytest
import time
@pytest.fixture()
def login():
print("------login")
@pytest.fixture()
def logout():
print("------logout")
@pytest.fixture(autouse=True)
def test_login(login):
print("------test_login")
class TestLogin:
def test_Login_01(self):
time.sleep = 3
print("------Hello,I'm 996 ITBrickMover\n")
def test_Login_02(self):
time.sleep = 3
print("------Hello,I'm 997 ITBrickMover\n")
运行结果:
D:\project\Pytest\PytestDemo\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path D:\project\Pytest\PytestDemo\scripts\test_login.py
Testing started at 23:30 ...
Launching pytest with arguments D:\project\Pytest\PytestDemo\scripts\test_login.py --no-header --no-summary -q in D:\project\Pytest\PytestDemo\scripts
============================= test session starts =============================
collecting ... collected 2 items
test_login.py::TestLogin::test_Login_01 ------login
------test_login
------Hello,I'm 996 ITBrickMover
PASSED
test_login.py::TestLogin::test_Login_02 ------login
------test_login
------Hello,I'm 997 ITBrickMover
PASSED
============================== 2 passed in 0.02s ==============================
Process finished with exit code 0
本章总结
Fixture是可以通过函数或参数引用,也可以通过加加装饰器@pytest.mark.userfixtures(fixture.name,…)来调用,以及设置自动适配:fixture设置autouse=True的形式来调用。
加装饰器时,可以在测试用例上加装饰器,也可以在测试类上加装饰器。其中,
(一)在测试用例上加装饰器时,调用时遵循以下顺序:
(1)可以有多个fixture,在有多个fixture参数时,放在底层的先执行,放在上层的后执行。即执行顺序与userfixture放置的上下顺序相反。
(2)可以有多个fixture,在有多个fixture参数时,放在前面的先执行,放在后面的后执行。即执行顺序与userfixture后面引用的参数顺序对应。
(3)同时有装饰器和引用,装饰器先执行。
(二)在测试类上加装饰器时,调用时遵循以下顺序:
(1)类中所有测试用例都会调用该fixture。同时有装饰器和引用,装饰器先执行。
(2)方法和类上都有装饰器,方法上装饰器先执行。
行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 759968159,里面有各种测试开发资料和技术可以一起交流哦。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。