转载自 https://blog.csdn.net/liuchunming033/article/details/46501653

pytest 单元测试框架

pytest 是python的一种单元测试框架,与python自带的unitest测试类似,但是比 unittest 更简洁、效率更高。根据pytest官方的介绍,它具有以下特点:

  • 非常容易上手,入门简单、文档丰富
  • 能够支持简单的单元测试复杂的功能测试
  • 支持参数化
  • 执行测试过程中可以将某测试跳过,或者对某些预期失败的case标记成失败
  • 支持重复执行失败的case
  • 支持运行由nose, unittest编写的测试case
  • 具有很多第三方插件,并且可以自定义扩展
  • 方便的和持续集成工具集成

安装

  1. pip install pytest
  2. # 确认
  3. (sysadmin-Cc_I1K2h) D:\projects\pythoncode\sysadmin>py.test --version
  4. This is pytest version 4.6.3, imported from c:\users\lite\.virtualenvs\sysadmin-cc_i1k2h\lib\site-packages\pytest.py

定义实例

我们可以通过下面的实例,看看使用py.test进行测试是多么简单。

  • filename test_xxxx.py
  • 测试函数 test_xxxx()
  1. # content of test_sample.py
  2. def func(x):
  3. return x+1
  4. def test_func():
  5. assert func(3) == 5

这里我们定义了一个被测试函数func,该函数将传递进来的参数加1后返回。我们还定义了一个测试函数 test_func用来对func进行测试。test_func中我们使用基本的断言语言assert来对结果进行验证。

下面来运行这个测试

  1. $ pytest
  2. =========================== test session starts ============================
  3. platform linux -- Python 3.4.1 -- py-1.4.27 -- pytest-2.7.1
  4. rootdir: /tmp/doc-exec-101, inifile:
  5. collected 1 items
  6. test_sample.py F
  7. ================================= FAILURES =================================
  8. _______________________________ test_answer ________________________________
  9. def test_answer():
  10. > assert func(3) == 5
  11. E assert 4 == 5
  12. E + where 4 = func(3)
  13. test_sample.py:5: AssertionError
  14. ========================= 1 failed in 0.01 seconds =========================

执行测试

执行测试的时候,我们只需要在测试文件test_sample所在的目录下,运行py.test即可。

pytest会在当前的目录下,寻找以test开头的文件(即测试文件),找到测试文件之后,进入到测试文件中寻找test_开头的测试函数并执行。

通过上面的测试输出,我们可以看到该测试过程中,一个收集到了一个测试函数,测试结果是失败的(标记为F),并且在FAILURES部分输出了详细的错误信息,帮助我们分析测试原因,我们可以看到”assert func(3) == 5”这条语句出错了,错误的原因是func(3)=4,然后我们断言func(3) 等于 5。

多个测试

当需要编写多个测试样例的时候,我们可以将其放到一个测试类当中,如:

  1. # content of test_class.py
  2. class TestClass:
  3. def test_one(self):
  4. x = "this"
  5. assert 'h' in x
  6. def test_two(self):
  7. x = "hello"
  8. assert hasattr(x, 'check')

我们可以通过执行测试文件的方法,执行上面的测试:

  1. $ pytest -q test_class.py
  2. .F
  3. ================================= FAILURES =================================
  4. ____________________________ TestClass.test_two ____________________________
  5. self = <test_class.TestClass object at 0x7fbf54cf5668>
  6. def test_two(self):
  7. x = "hello"
  8. > assert hasattr(x, 'check')
  9. E assert hasattr('hello', 'check')
  10. test_class.py:8: AssertionError
  11. 1 failed, 1 passed in 0.01 seconds

从测试结果中可以看到,该测试共执行了两个测试样例,一个失败一个成功。同样,我们也看到失败样例的详细信息,和执行过程中的中间结果。

如何编写测试要样例

通过上面2个实例,我们发现编写pytest测试样例非常简单,只需要按照下面的规则:

  • 测试文件以test_开头(以_test结尾也可以)
  • 测试类以Test开头,并且不能带有 init 方法
  • 测试函数以test_开头
  • 断言使用基本的assert即可

如何执行测试样例

执行测试样例的方法很多种,上面第一个实例是直接执行py.test,第二个实例是传递了测试文件给py.test。其实py.test有好多种方法执行测试:

  1. pytest # run all tests below current dir
  2. pytest test_mod.py # run tests in module
  3. pytest somepath # run all tests below somepath
  4. pytest -k stringexpr # only run tests with names that match the
  5. # the "string expression", e.g. "MyClass and not method"
  6. # will select TestMyClass.test_something
  7. # but not TestMyClass.test_method_simple
  8. pytest test_mod.py::test_func # only run tests that match the "node ID",
  9. # e.g "test_mod.py::test_func" will select
  10. # only test_func in test_mod.py

测试报告

pytest可以方便的生成测试报告,即可以生成HTML的测试报告,也可以生成XML格式的测试报告用来与持续集成工具集成。
生成HTML格式报告:

  1. pytest --resultlog=path

生成XML格式的报告:

  1. pytest --junitxml=path

获取帮助信息

  1. pytest --version # shows where pytest was imported from
  2. pytest --fixtures # show available builtin function arguments
  3. pytest -h | --help # show help on command line and config file options

最佳实践

其实对于测试而言,特别是在持续集成环境中,我们的所有测试最好是在虚拟环境中。这样不同的虚拟环境中的测试不会相互干扰的。
由于我们的实际工作中,在同一个Jekins中,运行了好多种不同项目册的测试,因此,各个测试项目运行在各自的虚拟环境中。
将pytest安装在虚拟环境中:
1、将当前目录创建为虚拟环境

  1. virtualenv . # create a virtualenv directory in the current directory
  2. source bin/activate # on unix

2、在虚拟环境中安装pytest:

  1. pip install pytest

使用 pipenv

  1. $ pipenv install pytest --dev

pytest-fixture

fixture

fixture是在测试函数运行前后,由pytest执行的外壳函数;
代码可以定制,满足多变的测试需求

  • 定义传入测试中的数据集,
  • 配置测试前系统的初始状态
  • 为批量测试提供数据源等

fixture是用于将测试胶后进行预备,清理工作的代码分离出核心测试逻辑。
用于分离 测试前后的准备工作与测试核心逻辑

检测顺序:优先搜索该测试所在模块, 然后搜索 conftest.py

放置位置

  • 测试所在模块
  • 当前目录 conftest.py 文件

集成的项目

https://github.com/amisadmin/fastapi_amis_admin
https://github.com/aminalaee/sqladmin
https://github.com/laixintao/iredis