【Python自动化框架pytest(一)】

时间:2022-12-16 09:59:53

本文介绍pytest简介,pytest安装,pytest的使用(命令),pytest实现前置及后置步骤
下一篇介绍ptest的fixture 的详细用法

一、pytest简介

pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。pytest是一个成熟的全功能的Python测试工具,可以帮助你写出更好的程序,让我们很方便的编写测试用例。适合从简单的单元到复杂的功能测试。有很多的第三方插件可以自定义扩展,并且支持allure。

pytest有以下特点:

  • 简单灵活,容易上手
  • 支持参数化
  • 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动- - 化测试、接口自动化测试(pytest+requests)
  • pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等
  • 测试用例的skip和xfail处理
  • 可以很好的和jenkins集成
  • report框架----allure 也支持了pytest

二、pytest安装

pip命令安装

pip install -U pytest

安装后验证

C:\Users\93439>pytest --version
This is pytest version 5.4.3, imported from e:\liang\tools\python3.7.2\lib\site-packages\pytest\__init__.py

pytest文档
官方文档:​​https://docs.pytest.org/en/latest/contents.html​

在pytest框架中,有如下约束:

文件名以test_*.py文件和*_test.py
以test_开头的函数
以Test开头的类
此时,在执行pytest命令时,会自动从当前目录及子目录中寻找符合上述约束的测试函数来执行。

三、pytest使用

1、 Pytest执行测试用例

测试用例

# @File : test_abc.py
import pytest # 引入pytest包

def test_a(): # test开头的测试函数
print("------->test_a")
assert 1 # 断言成功
def test_b():
print("------->test_b")
assert 0 # 断言失败

if __name__ == '__main__':
pytest.main(["-s", "test_abc.py"]) # 调用pytest的main函数执行测试

2、常用pytest命令

2.1 Pytest -vPytest -vv 显示具体的详情信息,一般显示错误的位置及错误的详细信息

2.2 Pytest --collect-only 收集可执行的案例

2.3 Pytest -k 案例名称 表示运行指定的案例,例如 pytest -k “_002” 表示指定运行含有002案例的测试案例

  • 在test_file01文件中命名为test_001() 在test_file02文件中命名为test_two_001() ,运行的时候编辑命令 pytest -k “_001” 所以它会运行相关名称下的案例

2.4 Pytest -s 等价于 pytest --capture=no 可以捕获print函数的输出

2.5 pytest --last-failed 等价于pytest --lf 只重新运行上次运行失败的用例(或如果没有失败的话会全部跑)

2.6 Pytest --ff 等价于 pytest --failed-first 运行所有测试,但首先运行上次运行失败的测试

2.7 pytest -q等价于Pytest --quiet 可以简化输出信息,与pytest -v对应

2.8 Pytest -m 用户标记名称 该命令的用法是在测试案例前使用 @pytest.mark.mytest 这个mytest就是我自己定义的名称,使用命令时则:pytest -m mytest即可,main函数写法pytest.main(["-s", "test_​​001.py​​","-m=mytest"]),标记执行非指定方法 pytest.main(['-s','文件名','-m=not 标记名'])

【Python自动化框架pytest(一)】


2.9 pytest -x等价于pytest --exitfirst,表示在debug过程中遇到一个fail的案例就停止运行后续的案例

2.10 pytest --maxfail=num 其中num表示运行失败案例的个数,假设,5个案例中1个是失败的,则使用pytest --maxfail=1 则运行到一个失败的案例则后续都不用执行,此时你把值改为2,则会继续运行后续的案例,该命令的意思:允许你案例中,fail案例的个数上限(这个值是大于等于则就会触发)

2.11 运行模块中的指定方法 pytest test_mod.py::TestClass::test_method
main函数写法pytest.main(["-s", "test_mod.py::TestClass::test_method"])

2.12 失败重试
在做接口测试时,有事会遇到503或短时的网络波动,导致case运行失败,而这并非是我们期望的结果,此时可以就可以通过重试运行cases的方式来解决。
安装pytest-rerunfailures:


pip install -U pytest-rerunfailures

命令行:pytest test_se.py --reruns NUM
main函数写法pytest.main(["-s", "test_001.py","-m=mytest","--reruns=2"])

2.13 多进程运行cases
当cases量很多时,运行时间也会变的很长,如果想缩短脚本运行的时长,就可以用多进程来运行。
安装pytest-xdist:


pip install -U pytest-xdist

运行模式:
pytest test_001.py -n NUM 其中NUM填写并发的进程数,
main函数写法pytest.main(["-s", "test_001.py","-n=auto"]),-n=auto根据cpu核心数选择进程数

2.14 Pytest测试报告
pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告。
安装方式:pip install pytest-html

pytest test_001.py --html=report\test_001.html
main函数写法pytest.main(["-s", "test_001.py","--html=report\test_001.html"]),其中report\test_001.html为要保存的测试报告路径和文件名

3、pytest的setup和teardown函数

3.1 函数级别setup()/teardown()

运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown


# file_name: test_002.py

import pytest
class Test_Case:
def setup(self):
print("------->setup_method")
def teardown(self):
print("------->teardown_method")
def test_0001(self): # test开头的测试函数
print("------->test_0001")
assert 1 # 断言成功
def test_0002(self):
print("------->test_0002")
assert 0 # 断言失败

if __name__ == '__main__':
pytest.main(["-s", "test_002.py"])

执行结果:

test_002.py ------->setup_method
------->test_0001
.------->teardown_method
------->setup_method
------->test_0002
F------->teardown_method

可以看出,每个用例执行前都先执行了setup方法,每个用例执行后都执行了teardonw方法。

3.2 类级别setup_class()/teardown_class()

运行于测试类的始末,即:在一个测试类内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。
代码示例:

# file_name: test_002.py

import pytest
class Test_Case:
def setup_class(self):
print("------->setup_method")
def teardown_class(self):
print("------->teardown_method")
def test_0001(self): # test开头的测试函数
print("------->test_0001")
assert 1 # 断言成功
def test_0002(self):
print("------->test_0002")
assert 0 # 断言失败

if __name__ == '__main__':
pytest.main(["-s", "test_002.py"])

输出结果:

test_002.py ------->setup_method
------->test_0001
.------->test_0002
F------->teardown_method

4、pytest的断言

assert xx:判断xx为真

  assert not xx:判断xx不为真

  assert a in b:判断b包含a

  assert a == b:判断a等于b

  assert a !=b:判断a不等于b