Pytest 使用说明
Posted fyly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytest 使用说明相关的知识,希望对你有一定的参考价值。
转自:https://blog.csdn.net/yyang3121/article/details/80624168
1.1安装
pytest是python语言的一个测试的第三方的库,那么我们首先需要-安装它,安装的命令是:
pip install -U pytest
见如下安装该库的执行过程的截图:
安装成功后,我们可以查看它的版本以及是否安装成功,在cmd的命令提示符中,直接输入pytest --version,如果未出现任何的错误,表示安装成功,见截图:
1.2第一个测试运行
OK,如上我们已经安装成功了,下来我们来应用它,通过具体的案例来看pytest的实际应用。我们编写一个简单的函数,并且对该函数进行测试,使用pytest
来查看执行的结果,见案例代码:
#!/usr/bin/env python #-*-coding:utf-8-*- def func(x): return x+1 def test_answer(): assert func(3)==5
我们到该模块的目录下,输入pytest(模块的名字必须是test开头,切记!),见该代码执行的结果,见截图:
见如上的截图,我们看到了执行的结果,该断言执行失败,您可以简单地使用 assert 语句来断言测试期望。pytest 的高级断言内省将智能地报告 assert 表达式的中间值, 从而使
您不必学习其它的断言的方法,OK,我们把代码进行修改下,看断言执行成功的情况,见修改后的代码:
#!/usr/bin/env python #-*-coding:utf-8-*- def func(x): return x+1 def test_answer(): assert func(3)==4
再次执行pytest(模块名称是test_xpytest.py,切记,执行pytest的时候,模块名称最好是test开头的),见执行的截图:
1.3运行多个测试
在一个包中,或者说一个模块的文件中,它是有多个文件的,比如一个包中,pytest它是执行多个以test开头的模块的文件的,我们先来看这种
情况的,我们在一个包中定义二个模块文件,分别是test_first.py,test_second,然后编写测试的代码,我们在该包中,执行pytest,见test_first.py的
代码:
#!/usr/bin/env python #-*-coding:utf-8-*- def func(x): return x+1 def test_answer(): assert func(3)==4
见test_second.py模块的代码:
#!/usr/bin/env python
#-*-coding:utf-8-*-
def add(a,b):
return a+b
def test_sum():
assert add(2,3)==5
见包的模块组织结构,见截图:
我们到该目录下,执行pytest命令,看执行的结果:
依据如上的截图,我们可以看到,执行pytest的命令后,执行了test_first.py,test_second.py模块文件中的代码,切记,pytest执行的时候,只执行test开头的模块,
以及test_开头的函数或者方法,如果我们把test_second.py修改成second.py,执行pytest后,就不会执行second.py文件中的代码了,见修改后的目录结构:
执行pytest,应该只执行test_first.py模块中的代码,见执行的结果截图:
另外,我们在上面强调的,模块中的函数或者方法也是需要test开头的,如果我们把second.py修改成test_second.py,该模块中的代码为如下的,执行pytest后,
也不会执行test_second.py模块的测试代码,见修改后的test_second.py代码:
见执行pytest后它的结果,是只执行test_first.py模块中的测试代码,不会执行test_second.py模块中的测试代码,具体原因上面截图中已经备注,见执行的结果:
如果要断言某些代码来导致异常,可以使用raise来产生,我们来看看如下的代码,见代码:
#!/usr/bin/env python #-*-coding:utf-8-*- import pytest def f(): raise SystemExit(1) def test_mytest(): with pytest.raises(SystemExit): f()
执行pytest见执行的结果:
如果我们要看执行的结果更加简单的信息,执行的命令由pytest修改成pytest -q 或者pytest -q 模块名称,见二种执行的结果方式结果:
1.4执行类中的测试
在上面说过,通过执行pytest执行模块中的函数或者类中的方法,那么我们就来实现执行类中的测试方法,见测试代码:
#!/usr/bin/env python #-*-coding:utf-8-*- import unittest def div(a,b): return a-b class DivTest(unittest.TestCase): def test_div_001(self): self.assertEqual(div(3,2),1) def test_div_002(self): self.assertEqual(div(3,3),0) def test_div_003(self): self.assertEqual(abs(div(2,3)),1)
见执行后的结果:
1.5请求唯一的临时目录
在功能的测试中,也就是说在一个测试的包中,有N个测试模块,但是你只是想执行其中的一个模块,其它的模块不想执行,
那么就可以指定唯一的模块(测试套件)来进行执行,我如下的代码是我们写一个测试的函数,test_tmdir.py的源码为:
#!/usr/bin/env python #-*-coding:utf-8-*- def test_needsfiles(tmpdir): print tmpdir return 0
执行该模块的代码,执行的命令是:pytest -q test_tmpdir.py,见执行后的结果输出:
二、用法和调用
2.1 调用pytest通过python -m pytest
在新的版本中,我们可以python -m pytest来进行调用,比如:
python -m pytest ...
2.2 Possible Exit codes
运行pytest可能导致6种不同的退出执行的方式,分别是:
2.3 pytest信息的获
显示从什么地方导入pytest
显示可用的内置函数参数
2.4分析测试执行持续时间
我们编写一个模块,来执行该模块,看测试执行的时间,模块的代码是为:
#!/usr/bin/env python from __future__ import unicode_literals # -*- coding: utf-8 -*- def test_answser(): assert 3 in [3,4,5]
执行pytest --durations=10看持续执行的时间,见执行的截图:
2.5 创建JUnitXML 格式文件
我们通过pytest --junitxml=path可以创建junit xml的格式文件,执行命令成功后,在当前的目录下创建了path的文件夹,该文件夹中
生成了xml的文件,见执行的命令和执行命令后输出的结果信息:
见当前目录生成的path文件夹以及里面的内容:
2.6 创建 resultlog 格式文件
我们执行pytest --resultlog=path命令后,来查看执行的结果信息以查看path文件的内容,见执行命令后输出的内容:
path文件的内容是:
. test_unit.py::test_answser
2.7 向在线pastebin服务发送测试报告
为每个测试失败的创建一个url,执行的命令是:pytest --pastebin=failed,见执行命令后的截图:
为所有的测试创建url,执行的命令是:pytest --pastebin=all,见执行命令的截图:
在浏览器中访问https://bpaste.net/show/b47d4593b3d7地址,可以看到执行的结果信息,见截图:
我们使用selenium编写一个自动化的测试例子,来看看执行的结果信息,见编写的测试代码:
#/usr/bin/env python #coding:utf-8 def add(a,b): return a+b lit1=[3,4,5,6] def test_add(): assert add(2,3) in lit1 test_add() import unittest from selenium import webdriver class WebTest(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.maximize_window() self.driver.implicitly_wait(30) self.driver.get(‘http://www.bing.com‘) def test_bing_001(self): self.assertEqual(self.driver.title,u‘微软 Bing 搜索 - 国内版‘) def test_bing_002(self): self.assertEqual(self.driver.current_url,‘http://cn.bing.com/‘) def tearDown(self): self.driver.quit()
再次执行pytest --pastebin=all命令,看执行的结果信息,见如下的截图:
在浏览器中打开https://bpaste.net/show/2536d4e3bad2地址,见如下的截图信息:
2.8 禁用插件
如果在使用中不想使用某些插件,可以使用如下的命令禁止使用该插件,命令为:
pytest -p no:doctest
2.9 在python代码中调用pytest
在python的代码中,可以直接调用pytest,比如pytest.main(),我们把如上的代码做了修改,在该代码中加了
pytest的代码,见修改后的代码:
#/usr/bin/env python #coding:utf-8 def add(a,b): return a+b lit1=[3,4,5,6] def test_add(): assert add(2,3) in lit1 test_add() import unittest from selenium import webdriver class WebTest(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.maximize_window() self.driver.implicitly_wait(30) self.driver.get(‘http://www.bing.com‘) def test_bing_001(self): self.assertEqual(self.driver.title,u‘微软 Bing 搜索 - 国内版‘) def test_bing_002(self): self.assertEqual(self.driver.current_url,‘http://cn.bing.com/‘) def tearDown(self): self.driver.quit() import pytest pytest.main()
然后执行该代码,见执行后输出的内容:
C:\\Python27\\python.exe "D:\\Program Files\\JetBrains\\PyCharm 2017.1.5\\helpers\\pycharm\\_jb_unittest_runner.py" --path D:/git/Python/xUnit/test_unit.py Testing started at 11:01 ... Launching unittests with arguments python -m unittest discover -s D:/git/Python/xUnit -p test_unit.py -t D:\\git\\Python\\xUnit in D:\\git\\Python\\xUnit ============================= test session starts ============================= platform win32 -- Python 2.7.11, pytest-3.2.2, py-1.4.34, pluggy-0.4.0 rootdir: D:\\git\\Python\\xUnit, inifile: plugins: allure-adaptor-1.7.8 collected 3 items test_unit.py ... ========================== 3 passed in 14.51 seconds ========================== Ran 2 tests in 15.069s OK Process finished with exit code 0
我们也可以在pytest.main()中加入参数,来看它的执行结果比如我们创建一个模块,编写如下的代码,来看执行的结果,见代码:
#!/usr/bin/env python #-*- coding:utf-8 -*- import pytest class MyPlugin(object): def pytest_sessionfinish(self): print ‘***test run reporting finish‘ pytest.main([‘-qq‘],plugins=[MyPlugin()])
见执行该代码后的结果信息:
C:\\Python27\\python.exe D:/git/Python/xUnit/mytestdir/myinvoke.py ***test run reporting finish
三、测试套件中使用pytest
pytest可以和现有的测试框架集成到一起使用,比如典型的unittest的测试框架,那么什么是测试套件了,测试套件简单的理解就是
测试用例的集合,在一个测试模块或者测试的集合中,需要对这些测试用例进行组织到一起执行,那么就是需要测试套件。该案例在
前面中已经说过,就不再说了。
四、测试中断言的编写和报告
4.1 断言
pytest允许你使用标准的python断言来验证python测试中的期望和值,见如下的测试代码:
#!/usr/bin/env python #-*- coding:utf-8 -*- def f(): return 3 def test_function(): assert f() ==4
使用命令pytest来执行如上的测试代码,来执行的结果截图:
注释:见如上的截图,错误信息程序给出了很明确的信息
4.2 异常的断言
某些时候,可能就会出现引发异常的断言,可以使用pytest作为上下文管理器引发异常,见案例的代码:
#!/usr/bin/env python #-*- coding:utf-8 -*- import pytest def test_zero_division(): with pytest.raises(ZeroDivisionError): 1/0
执行该模块的代码,见执行的输出信息:
如果需要查看实际的异常信息,代码可以这样编写,见编写的代码:
#!/usr/bin/env python #-*- coding:utf-8 -*- import pytest def test_recurson_depth(): with pytest.raises(RuntimeError) as excinfo: def f(): f() f() assert ‘maximum recursion‘ in str(excinfo.value)
#!/usr/bin/env python #-*- coding:utf-8 -*- import pytest def myfunc(): raise ValueError("Exception 123 raised") def test_match(): with pytest.raises(ValueError,match=r‘.*123*.‘): myfunc()
以上是关于Pytest 使用说明的主要内容,如果未能解决你的问题,请参考以下文章
pytest学习和使用15-Pytest用例失败如何重跑?(pytest-rerunfailures的简单使用)