Python pytest

1、前言

Python 测试相关库

  • unittest:内置库,模仿 PyUnit 写的,简洁易用,缺点是比较繁琐。unittest+HTMLTestRunner。
  • nose:测试发现,发现并运行测试。
  • pytest:目前喜欢用这个,写起来很方便,并且很多知名开源项目在用,推荐。
  • mock:替换掉网络调用或者 rpc 请求等

Python 鄙视链:pytest 鄙视 > unittest 鄙视 > robotframework

pytest 是 Python 的第三方单元测试框架,比自带 unittest 更简洁和高效,支持315种以上的插件,同时兼容 unittest 框架。这就使得我们在 unittest 框架迁移到 pytest 框架的时候不需要重写代码

全功能 Python 测试框架:pytest

官网:

pytest 是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:

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

2、pytest安装

1
2
3
4
pip install -U pytest

# 验证安装的版本:
pytest --version

3、pytest框架的约束

3.1、python的命名规则

  1. py文件全部小写,多个英文用_隔开
  2. class名首字母大写,驼峰
  3. 函数和方法名小写,多个英文用_隔开
  4. 全局变量,前面要加global
  5. 常量字母必须全大写,如:AGE_OF_NICK

3.2、pytest的命名规则

  1. 模块名(py文件)必须是以 test_ 开头或者 _test 结尾
  2. 测试类(class)必须以 Test 开头,并且不能带 init 方法,类里的方法必须以 test_ 开头
  3. 测试用例(函数)必须以 test_ 开头

4、pytest的运行方式

4.1、主函数运行

1
2
3
4
5
6
7
import  pytest

def test_01():
print("啥也没有")

if __name__=='__main__':
pytest.main()

main中可使用的参数有:

参数 描述 案例
-v 输出调试信息。如:打印信息 pytest.main([‘-v’,‘testcase/test_one.py’,‘testcase/test_two.py’])
-s 输出更详细的信息,如:文件名、用例名 pytest.main([‘-vs’,‘testcase/test_one.py’,‘testcase/test_two.py’])
-n 多线程或分布式运行测试用例
-x 只要有一个用例执行失败,就停止执行测试 pytest.main([‘-vsx’,‘testcase/test_one.py’])
–maxfail 出现N个测试用例失败,就停止测试 pytest.main([‘-vs’,‘-x=2’,‘testcase/test_one.py’]
–html=report.html 生成测试报告 pytest.main([‘-vs’,‘–html=./report.html’,‘testcase/test_one.py’])
-m 通过标记表达式执行
-k 根据测试用例的部分字符串指定测试用例,可以使用and,or

4.2、命令行运行

文件路径:testcase/test_one.py

1
2
3
def test_a():
print("啥也不是")
assert 1==1

终端输入:pytest ./testcase/test_one.py --html=./report/report.html

参数 描述 案例
-v 输出调试信息。如:打印信息 pytest -x ./testcase/test_one.py
-q 输出简单信息。 pyets -q ./testcase/test_one.py
-s 输出更详细的信息,如:文件名、用例名 pytest -s ./testcase/test_one.py
-n 多线程或分布式运行测试用例(前提安装插件:pytest-xdist)
-x 只要有一个用例执行失败,就停止执行测试 pytest -x ./testcase/test\_one.py
–maxfail 出现N个测试用例失败,就停止测试 pytest --maxfail=2 ./testcase/test_one.py
–html=report.html 生成测试报告 pytest ./testcase/test_one.py --html=./report/report.html
–html=report.html 生成测试报告 pytest ./testcase/test_one.py --html=./report/report.html
-k 根据测试用例的部分字符串指定测试用例,可以使用and,or pytest -k “MyClass and not method”,这条命令会匹配文件名、类名、方法名匹配表达式的用例,这里这条命令会运行 TestMyClass.test_something, 不会执行 TestMyClass.test_method_simple
  1. 单独执行某一个py文件里所有的用例

    1
    pytest test.py
  2. 执行目录下所有用例

    1
    pytest testcase/
  3. 单独执行某个用例,通过 node id 指定测试用例. node id由模块文件名、分隔符、类名、方法名、参数构成,举例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    # 以函数形式的用例
    pytest test_login.py::test_1

    # 运行类
    pytest test_login.py::TestClass

    # 以类形式的用例
    pytest test_login.py::TestClass::test_1

    注意:定义class时,需要以T开头,不然pytest是不会去运行该class的。

  4. 通过标记表达式执行

    1
    pytest -m slow

    这条命令会执行被装饰器 @pytest.mark.slow 装饰的所有测试用例

  5. 通过包执行测试

    1
    pytest --pyargs pkg.testing

    这条命令会自动导入包 pkg.testing,并使用该包所在的目录,执行下面的用例。

4.3、pytest.ini 配置文件方式运行(常用)

不管是 mian 执行方式还是命令执行,最终都会去读取 pytest.ini 文件

在项目的根目录下创建 pytest.ini 文件

1
2
3
4
5
6
7
8
# 用于标志这个文件是pytest的配置文件	
[pytest]
addopts=-vs -m slow --html=./report/report.html # 命令行参数,多个参数之间用空格分隔
testpaths=testcase # 配置搜索参数用例的范围
python_files=test_*.py # 改变默认的文件搜索规则
python_classes=Test* # 改变默认的类搜索规则
python_functions=test_* # 改变默认的测试用例的搜索规则
makerers=smock:冒烟测试用例

pytset.ini 文件尽可能不要出现中文。

pytest 配置文件 pytest.ini

pytest 的配置文件通常放在测试目录下,名称为 pytest.ini,命令行运行时会使用该配置文件中的配置

1
2
3
4
5
6
7
8
9
10
11
12
#配置pytest命令行运行参数
[pytest]
addopts = -s ... # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
testpaths = ./scripts # 当前目录下的scripts文件夹 -可自定义

#配置测试搜索的文件名称
python_files = test*.py
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件 -可自定义配置测试搜索的测试类名
python_classes = Test_*
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类 -可自定义配置测试搜索的测试函数名
python_functions = test_*
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类内,以test_开头的方法 -可自定义

4.4、多进程运行cases

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

安装 pytest-xdist:

1
pip install -U pytest-xdist

运行模式:

1
pytest test_se.py -n NUM

其中NUM填写并发的进程数。

5、Pytest Exit Code 含义清单

  • Exit code 0 所有用例执行完毕,全部通过
  • Exit code 1 所有用例执行完毕,存在Failed的测试用例
  • Exit code 2 用户中断了测试的执行
  • Exit code 3 测试执行过程发生了内部错误
  • Exit code 4 pytest 命令行使用错误
  • Exit code 5 未采集到可用测试用例文件

6、pytest的常用插件

插件列表网址:https://plugincompat.herokuapp.com

包含很多插件包,大家可依据工作的需求选择使用。

7、pytest 中 conftest.py 文件

7.1、conftest.py 的特点

  • pytest 会默认读取 conftest.py 里面的所有 fixture
  • conftest.py 文件名称是固定的,不能改动
  • conftest.py 只对同一个 package 下的所有测试用例生效
  • 不同目录可以有自己的 conftest.py,一个项目中可以有多个 conftest.py
  • 测试用例文件中不需要手动 import conftest.py,pytest 会自动查找

7.2、conftest.py 的示例目录

最顶层的 conftest,一般写全局的 fixture

1
2
3
4
5
6
project
├─ testone
│ ├─ conftest.py

├─ conftest.py # 这里
...

Python pytest
https://flepeng.github.io/021-Python-34-框架-pytest-Python-pytest/
作者
Lepeng
发布于
2021年4月27日
许可协议