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种不同的退出执行的方式,分别是:

退出代码0成功地收集并传递了所有测试
退出代码1测试被收集和运行, 但一些测试失败
退出代码2测试执行被用户中断
退出代码3执行测试时发生内部错误
退出代码 4 pytest 命令行使用错误
退出代码5未收集任何测试

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)
技术图片
excinfo 是一个 ExceptionInfo 实例, 它是围绕实际异常引发的包装。此外, 上下文管理器窗体接受匹配关键字参数以测试正则表达式是否与
异常的字符串表示形式 (如单元中的测试 assertRaisesRegexp 方法),我们见如下的代码实例:
技术图片
#!/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()
技术图片
见如上的代码执行后的结果信息:
技术图片

4.3  利用context-sensitive比较

      在pytest中,也可以使用context-sensitive进行比较,见如下的代码:

技术图片
#!/usr/bin/env python 
#-*- coding:utf-8 -*-

def test_set_comparson():
    set1=set(‘1308‘)
    set2=set(‘8035‘)
    assert  set1==set2
技术图片

执行如上的代码后,见执行的结果信息:

技术图片

以上是关于Pytest 使用说明的主要内容,如果未能解决你的问题,请参考以下文章

pytest学习和使用15-Pytest用例失败如何重跑?(pytest-rerunfailures的简单使用)

python使用pytest+pytest报告

pytest之执行测试pytest.main()的使用

45-pytest-pytest.main()使用

pytest学习和使用17-Pytest如何重复执行用例?(pytest-repeat)

18-pytest-配置文件pytest.ini使用