python-pytest使用

python-pytest使用

来源:官方文档/其他

大纲:

  1. 安装
  2. 简单实例
    1.   执行过程
  3. 利用pytest实现setUp/teardown
  4. 其他
  5. 接入报告

安装

  pip install -U pytest

  检测:pytest --version

简单实例

  case文件规范:test_*.py

  case规范:可以直接是方法,而非unittest这种需要case为类;当然pytest是支持unittest的case(类不需要继承);方法需要以test*结构

  使用:pytest -q 文件/pytest

  断言:直接使用assert

#test_case.py
import pytest

def fun(x):
return x+1

def test_1():
assert fun(3)==4


执行过程:pytest模块会先找项目文件中test_*.py/*_test.py的文件;然后会从文件中找test*的方法/类,如果case方法中有内置参数,在去 conftest.py配置文件中查找 @pytest.fixture(mondle/class/fucntion):定义的内置方法/类,在将该定义的方法作为参数传递入case方法中
@pytest.fixture(mondle/class/fucntion):其中@pytest.fixture装饰器定义的方法/类类似setUp/teardown定义的方法;然后mondle/class/fucntion表示方法的作用范围
查找内置的固定装置:
pytest --fixtures

利用pytest实现setUp/teardown实例:

在pytest中进行前后置操作,主要是通过固件(fixture)来实现的;下面介绍下固件:

是什么:

  • 固件本质上是一个函数,能在执行待测对象进行时进行前置和后置的操作;在固件函数中,yield前的是进行前置操作的,yield后的是进行后置操作的;

怎么样:

  • 使用@pytest.fixture()装饰器来定义;可直接放置在待测脚本中,为了复用,也可新建一个conftest.py 文件来进行集中管理固件
  • 作用范围:conftest.py文件所在目录,及其子目录
  • 常用参数有三个:别名/作用域/是否自动执行
    • @pytest.fixture(foo="f")  //f是固件函数的别名
    • @pytest.fixture(foo="f",scope='class')    //scope属性定义了作用域的范围;共有四个可选值如下,默认为函数级:
      • function: 函数级,每个测试函数都会执行一次固件;
      • class: 类级别,每个测试类执行一次,所有方法都可以使用;
      • module: 模块级,每个模块执行一次,模块内函数和方法都可使用;
      • session: 会话级,一次测试只执行一次,所有被找到的函数和方法都可用@pytest.fixture(scope='function')
def func_scope():
    pass


@pytest.fixture(scope='module')
def mod_scope():
    pass


@pytest.fixture(scope='session')
def sess_scope():
    pass


@pytest.fixture(scope='class')
def class_scope():
    pass
    • 是否自动执行:pytest.fixture(foo="f",scope='class',autouse=True);如果不自动执行,最方便的是将作用域作为参数传递到待测函数
    • 细致跟踪固件执行,可以使用 --setup-show 选项: 
      pytest --setup-show tests/fixture/test_scope.py::test_multi_scope
    • 使用固件方法1:直接作为参数引入/配置自动执行
      •   def test_multi_scope(sess_scope, mod_scope, func_scope):
            pass
    • 使用固件方法2:使用pytest.mark.usefixture
    • 使用固件方法2:定义固件时,自动配置自动执行
      @pytest.fixture(scope='class')
      def class_scope():
          pass
    • @pytest.mark.usefixtures('class_scope')
      class TestClassScope:
          def test_1(self):
              pass
      
          def test_2(self):
              pass

#conftest.py的内容
import pytest

@pytest.fixture(foo='f',scope="function",autouse=True)
def foo():
print(" function setup")
yield 100  #yield前的是前置操作,后的是后置操作
print(" function teardown")

#test_1540.py的内容
import pytest

def inc(x):
return x + 1

def test_answer_1():
assert inc(3) == 5

def test_answer_2(foo):
print(foo)
assert inc(98) == foo

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

运行pytest

  1. python -m pytest test_*.py
  2. pytest test_*.py
  3. pytest testing/  #运行路径下的所有文件作为case
  4. pytest -k "MyClass and not method"  #运行文件名/类名/方法中含case的对象
  5. pytest test_mod.py::TestClass::test_method  #按节点id来运行case;由于pytest收集的测试集,每个case都有一个固定的nodeid,结构就是文件名::类名::方法名,因此可通过这种方法来调用
  6. pytest --pyargs pkg.testing==pytest testing/ 从包运行
  7. pytest -m slow   #通过标记表达式运行,将运行用@pytest.mark.slow装饰器装饰的所有测试
  8. pytest --trace  #进入python调试器
  9. pytest --durations=10 --durations-min=1.0  #显示1s内最慢的10个执行case
  10. pytest --junitxml=path  #生成可被jenkin读取的配置文件,如要以该配置文件运行可在下方结构中配置
    [pytest]
    junit_suite_name = my_suite(xml配置名称)
  11. 在python代码中运行pytest的case:
    pytest.main()#由于python导入的缓存机制,因此不建议在一个程序中使用多次该调用/pytest.main(["-x", "mytestdir"])#传递选项和参数 /pytest.main(["-x", "mytestdir"])
运行pytest会导致六个不同的退出代码:

退出码0
所有测试均已收集并成功通过

退出代码1
测试已收集并运行,但有些测试失败

退出代码2
测试执行被用户中断

退出代码3
执行测试时发生内部错误

退出代码4
pytest命令行用法错误

退出代码5
没有收集测试

  有时需要对运行状态进行判断,此时需要用到退出码参数,需要先导入:
  from pytest import ExitCode
  其他命令:pytest -h查看环境变量/pytest --help帮助信息/pytest
--fixtures查看内置的固定结构
  
运行case失败后停止:
pytest -x           # stop after first failure(1个case失败停止)
pytest --maxfail=2  # stop after two failures

接入报告

pytest和其他的测试套件一起使用

如nose/unittest

cd <repository>
pip install -e .  # Environment dependent alternatives include
                  # 'python setup.py develop' and 'conda develop'
原文地址:https://www.cnblogs.com/1009gavin/p/14260898.html