pytest测试框架学习(一)

pytest测试框架学习(一)

 

一、pytest简介

pytest是一个非常成熟的全功能的Python测试框架。

pytest框架特点:

  • 简单灵活,非常容易上手

  • 支持参数化

  • 支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests)

  • pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等

  • 测试用例的skip和xfail处理

  • 可以与jenkins集成

  • report框架----allure 也支持了pytest

pytest安装

pip install -U pytest

查看版本或查看是否已安装:

 

 

二、小试牛刀

demo1测试通过

import pytest
'''
1、测试方法要以test开头
'''
 def test_testdemo1():
     print(">>>>>test_pass>>>>>>>")
     assert 1 == 1

if __name__ == '__main__':
    pytest.main()
#命令行执行用例文件    
#pytest test_mod.py

============================= test session starts =============================
platform win32 -- Python 3.5.0, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\github\xxx\xxxx
plugins: celery-4.3.0
collected 1 item

test_a1.py .                                                             [100%]

============================== 1 passed in 0.12s ==============================

Process finished with exit code 0    

demo2测试不通过

import pytest
'''
1、测试方法要以test开头
'''
def test_testdemo2():
    print(">>>>>test_fail>>>>>>>")
    assert 1 == 2
if __name__ == '__main__':
    pytest.main()    
============================= test session starts =============================
platform win32 -- Python 3.5.0, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\github\xxxxx\xxxx
plugins: celery-4.3.0
collected 1 item
​
test_a1.py F                                                             [100%]
​
================================== FAILURES ===================================
_______________________________ test_testdemo2 ________________________________
​
    def test_testdemo2():
        print(">>>>>test_fail>>>>>>>")
>       assert 1 == 2
E       assert 1 == 2
​
test_a1.py:24: AssertionError
---------------------------- Captured stdout call -----------------------------
>>>>>test_fail>>>>>>>
=========================== short test summary info ===========================
FAILED test_a1.py::test_testdemo2 - assert 1 == 2
============================== 1 failed in 0.14s ==============================    

三、pytest常用命令

***查看帮助信息***
pytest --version # 查看当前已安装版本
pytest --fixtures #显示内置函数参数
pytest --help     #查看帮助信息
***用例执行控制***
pytest -x             # 遇到失败用例停止测试
pytest --maxfail=2    # 出现2个用例失败终止测试
pytest test_XX.py     # 指定运行的测试文件
pytest test/          # 指定测试目录
pytest -k "MyClass and not method"    #通过关键字表达式过滤需要执行的用例,条命令会匹配文件名、类名、方法名匹配表达式的用例,这里这条命令会运行 TestMyClass.test_1, 不会执行 TestMyClass.test_method_1
​
pytest test_xx.py::test_xxx     #通过 node id 指定测试用例,即执行test_xx.py用例文件的test_xxx方法,nodeid由模块文件名、分隔符、类名、方法名、参数构成
​
pytest -m slow        #通过标记表达式执行,这条命令会执行被装饰器 @pytest.mark.slow 装饰的所有测试用例
​
pytest --pyargs pkg.test   #这条命令会自动导入包 pkg.test,并执行该包所在的目录下面的用例。
pytest test_se.py -s   #-s  加上-s参数可以在运行pytest时将print语句输出到控制台
​

四、pytest实用插件

pytest-xdist

pytest-xdist可以实现多进程运行测试用例,在测试用例比较多的情况下可以有效缩短脚本的测试执行时间。

安装pytest-xdist:
pip install -U pytest-xdist
​
使用pytest-xdist运行测试用例:
pytest test_se.py -n NUM    --NUM为进程数

pytest-html

pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告。

安装pytest-html
pip install pytest-html
​
使用pytest-htm生成测试结果报告
pytest --html=report.html   --执行当前目录下的用例文件
​
指定报告生成的路径
pytest --html=./report/report.html
​
将css样式合并到html里
pytest --html=report.html --self-contained-html

pytest-rerunfailures

pytest-rerunfailures失败用例重跑

命令行参数:--reruns n(重新运行次数),--reruns-delay m(等待运行秒数)

装饰器参数:reruns=n(重新运行次数),reruns_delay=m(等待运行秒数) @pytest.mark.flaky(reruns=5)

安装pytest-rerunfailures
pip install pytest-rerunfailures  
​
pytest --reruns 5 -s        #运行失败的fixture或setup_class也将重新执行
​
pytest -s demo_xxx.py --reruns 5
pytest -s demo_xxx.py --reruns 5  --reruns-delay 1  #重跑之前等待1s

pytest-assume

pytest-assume实现用例的多重校验,虽然assert也可以写多个校验条件,但是前一个条件失败,后面的校验就不会执行,而 pytest-assume断言即使前面一个断言失败,后面的断言也会继续执行。

安装pytest-assume
pip install pytest-assume

pytest-ordering

对于存在上下文依赖的测试,有时候可能需要设定一些特定执行顺序,pytest的ordering插件,就很好的解决了这个问题

安装pytest-ordering
pip  install  pytest-ordering
​
@pytest.mark.run(order=2)
def test_demo1():
    print ("first test")
    assert True
@pytest.mark.run(order=1)
def test_demo2():
    print ("second test")
    assert True
原执行顺序为test_demo1>>test_demo2       
加上@pytest.mark.run(order=X)执行的顺序变为test_demo2>>test_demo1    

五、pytest的setup和teardown函数作用

setup和teardown函数运行于测试方法的开始与结束时,即:运行一次测试函数前调用setup函数,测试结束后调用teardown函数。setup()/teardown()是函数级别的。

import pytest
class TestDemo1:
  def setup(self):
      print("------->setup_method------------")
  def teardown(self):
      print("------->teardown_method----------")
  def test_demo1(self):
      print("------->test_a-----------")
      assert 1
    
platform win32 -- Python 3.5.0, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: E:\PyProject\TestDemo1
collected 1 item                                                                                             
source\testDemo1.py ------->setup_method------------
------->test_a-----------
.------->teardown_method----------
​

六、pytest的setup_module\setup_class和teardown_module\teardown_class函数作用

运行于测试类初始化以及结束时,即:在一个测试内只运行一次setup_class和teardown_class。

def setup_module(self):
    print("=======1111111========")

def teardown_module(self):
    print("=======1111111========")
import pytest
class Test_ABC:
    @classmethod
    def setup_class(self):
       print(">>>>>>setup_class_method>>>>>>>>")

    @classmethod
    def teardown_class(self):
       print(">>>>>>teardown_class_method>>>>>")
    def setup(self):
       print(">>>>>>setup_method>>>>>>")
    def teardown(self):
       print(">>>>>>teardown_method>>>>>>")
    def test_a(self):
       print(">>>>test_a>>>>>")
       assert 1==1
    def test_b(self):
       print(">>>>>test_b>>>>>")
       assert 1==1
platform win32 -- Python 3.5.0, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\github\YZhttprunner\YZhttprunner
plugins: celery-4.3.0
collected 2 items                                                                                                                             

test_a1.py =======setup_module========
>>>>>>setup_class_method>>>>>>>>
>>>>>>setup_method>>>>>>
>>>>test_a>>>>>
.>>>>>>teardown_method>>>>>>
>>>>>>setup_method>>>>>>
>>>>>test_b>>>>>
.>>>>>>teardown_method>>>>>>
>>>>>>teardown_class_method>>>>>
=======teardown_module========

 

七、pytest配置文件

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

#配置pytest命令行运行参数
   [pytest]
    addopts = -s ... # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
    testpaths = ./testcase  # 即当前目录下的testcase文件夹 -可自定义
#配置测试搜索的文件名称
    python_files = test*.py 
#当前目录下的testcase文件夹下,以test开头,以.py结尾的所有文件 -可自定义
配置测试搜索的测试类名
    python_classes = Test_*  
   #当前目录下的testcase文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类 -可自定义
配置测试搜索的测试函数名
  
    python_functions = test_*
#当前目录下的testcase文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类内,以test_开头的方法 -可自定义
 

八、pytest跳过测试用例

1、使用@pytest.mark.skip()装饰测试方法,运行测试时将会跳过该方法不执行。

#跳过测试函数的最简单方法是使用跳过装饰器标记它,可以传递一个可选的原因
@pytest.mark.skip(reason='misunderstood the API')
def test_demo1():
    ....

2、在测试方法中设置强制跳过pytest.skip(reason)

def test_demo1()::
    if not valid_config():
        pytest.skip("unsupported configuration")

3、设置跳过整个模块级别pytest.skip(reason,allow_module_level = True)

import pytest
if not pytest.config.getoption("--custom-flag"):
    pytest.skip("--custom-flag is missing, skipping tests", allow_module_level=True)

4、有条件地跳过某些内容,则可以使用skipif(可以装饰类和方法)

'''
如果当前环境是python3.6以下版本就跳过用例
'''
import sys
@pytest.mark.skipif(sys.version_info < (3,6),
reason="当前python环境版本小于3.6跳过测试用例")
def test_demo1():
    ...
'''
如果当前环境是python3.6以下版本,则跳过该类的所有测试方法
'''
@pytest.mark.skipif(sys.version_info < (3,6),
reason="requires python3.6 or higher")
class TestCalls(object):
    def test_demo1(self):
        "will not be setup or run under 'python3.6' platform"

欢迎大家关注我的订阅号,会定期分享一些关于测试相关的文章,有问题也欢迎一起讨论学习!

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页