pytest测试框架

一、pytest单元测试框架

1.什么是单元测试框架?

单元测试是指在软件开发当中,针对软件的最小单位(函数方法)进行正确性的检查测试。

2.单元测试框架

java:junit和testng

python:unittest和pytest

3.单元测试框架主要做什么?

(1)测试发现:从多个文件里边去找我们的测试用例

(2)测试执行:按照一定的顺序和规则去执行,并生成结果

(3)测试判断:通过断言判断预期结果和实际结果的差距

(4)测试报告:统计测试进度,耗时,通过率,生成测试报告。

二、单元测试框架和自动化测试框架有什么关系

1.作用:

1.提高测试效率,降低维护成本。

2.减少人工干预,提高测试的准确性,增加代码的重用性。

3.核心思想是让不懂代码的人也能过通过这个框架去实现自动化测试。

2.关系:

单元测试框架:只是自动化测试框架种的组成部分之一。

pom设计模式:只是自动化测试框架种的组成部分之一。

数据驱动、关键字驱动、全局配置文件封装、日志监控、selenium,requests二次封装、断言、报告、邮件。。。

三、pytest简介

1.pytest是一个非常成熟的python的单元框架,比unittest更灵活,容易上手。

2.pytest可以和selenium,requests,appium结合实现web自动化,接口自动化,app自动化。

3.pytest可以实现测试用例的跳过以及reruns失败用例重试。

4.pytest可以和allure生成非常美观的测试报告。

5.oytets可以和jenkins持续集成。

6.pytest有很多非常强大的插件,并且这些插件可以实现很多使用的操作。

(1)pytest

(2)pytest-html       生成html格式的自动化测试报告

(3)pytest-xdist       测试用例分布式执行,多cpu分发

(4)pytest-ordering        用于改变测试用例的执行顺序

(5)pytest-rerunfailures       用力失败后重跑

(6)allure-pytest       用于生成美观的测试报告

以上几个插件可以维护到requirements.txt种,通过pip install -r requirements.txt安装插件

四、使用pytest,默认的测试用例的规则以及基础应用

1.模块名必须以test_开头或者_test结尾

2.测试类必须以Test开头,并且不能以init方法

3.测试方法必须要以test开头

五、测试用例的运行方式

1.主函数模式

(1)运行所有:pytest.main()

(2)指定模块:pytest.main(["test_login.py"])     "test_login.py"为文件的路径

(3)指定目录:pytest.main(["目录路径"])

(4)通过nodeid指定用例运行:nodeid由模块名,分隔符,类名,方法名,函数名组成

          pytest.main(["./testcase/test_web.py::TestLogin::test_001"])

2.命令行模式

(1)运行所有:pytest

(2)指定模块:pytest  test_login.py"

(3)指定目录:pytest 目录路径

(4)pytets  ./testcase/test_web.py::TestLogin::test_001

3.通过读取pytest.ini配置文件运行

pytest.ini:是pytest单元测试框架的核心配置文件

位置:一般放在项目的根目录。

编码:必须是ANSI,可以使用notepad++修改编码格式

作用:改变pytest的默认行为

运行的规则:不管是主函数运行模式还是命令行运行模式,都会去读这个配置文件。

文件的内容:(实际运行时最好把中文注释给去掉)

[pytest]

addopts = -vs -m 'smoke or huigui' --html ./report/report.html    #添加的命令符

testpaths = ./test_    #执测试用例的路径

python_files = test_*.py    #执行的文件命名规则

python_classes = Test*     #执行的class类命名规则,前边都有Test

python_functions = test     #执行的类的方法命名规则

markers =
    smoke:冒烟
    huigui:回归          #分类管理,此处维护了可以在用例上打标签

参数详解:

-s:表示输出调试信息,包括print打印的信息

-v:表示显示更详细的信息

-vs:两个蚕食可以一起使用

-n:支持多线程或者分布式运行测试用例。如pytest.main(["-n=2"]),表示两个线程运行

--reruns NUM :失败用例重跑,NUM为重跑的次数,一个用力失败了,一共运行NUM+1次

-x:表示只要一个用例报错,那么测试就会停止。

--maxfail=2  出现两个用例失败就停止

-k:根据测试用例的部分字符串去运行测试用例 pytest.main(["-k="aaa""])

--html ./report/report.html:生成测试报告

--lf:只重新运行上次运行失败的用例

--ff:先执行上次失败的测试后,在执行上次正常的测试用例。

六、测试用例的执行顺序

1.unittest:根据ascII的大小来决定执行的顺序

2.pytest:从上到下依次运行

pytest可以通过给用例添加修饰器来改变默认的顺序

@pytest.mark.run(order=1)
import pytest

class Test1:
    def test_001(self):
        print("用例1")
    @pytest.mark.run(order=1)   #执行顺序改为1
    def test_002(self):
        print("用例2")
    def test_003(self):
        print("用例3")
if __name__ == '__main__':
    pytest.main()

执行结果:

pytest测试框架_第1张图片

 七、分组执行用例

smoke冒烟测试用例分布在各个模块里面,在进行冒烟测试的时候我们需要将这些用例从各个模块中挑选出来,用@pytest.mark.smoke  其中smoke为用户自定义的,写成什么都可以,能表明语义即可。

1.pytest.ini种 写好运行命令以及配置好分类的标签,在addopts中 用-m 来表示需要执行的标记用例,多个用例之间用or连接

pytest测试框架_第2张图片

2. 测试用例打标记

import pytest

class Test1:
    def test_001(self):
        print("用例1")

    @pytest.mark.huigui
    def test_002(self):
        print("用例2")

    @pytest.mark.smoke
    def test_003(self):
        print("用例3")

3.在Terminal中输入pytest执行命令

4.执行结果:只执行了打smoke和huigui标记的用例

pytest测试框架_第3张图片

八、跳过测试用例

1.无条件跳过

@pytest.mark.skip(reason="跳过原因")

2.有条件跳过

@pytest.mark.skipif(条件判断语句,reason="跳过原因")

代码片段:

import pytest

class Test1:
    age =19
    @pytest.mark.skipif(age>18,reason="已经成年")
    def test_001(self):
        print("用例1")

    @pytest.mark.skip(reason="无条件跳过")
    def test_002(self):
        print("用例2")


    def test_003(self):
        print("用例3")

运行结果:

pytest测试框架_第4张图片

九、前后置处理之setup/teardowm,setup_class/teardown_class

跟unittest不同setup跟teardown全都是小写

import pytest


class Test1:
    def setup(self):
        print("每个用例前执行一次")

    def teardown(self):
        print("每个用例后执行一次")
    def setup_class(self):
        print("每个类前执行一次")

    def teardown_class(self):
        print("每个类后执行一次")

    def test_001(self):
        print("用例1")

    def test_002(self):
        print("用例2")

    def test_003(self):
        print("用例3")

执行结果:

pytest测试框架_第5张图片

 十、使用@pytest.fixture()装饰七来实现部分用例的前后置

@pytest.fixture(scope='',params='',autouse='',ids='',name='')

其中:

scope表示的是被@pytest.fixture标记的方法的作用域,function(默认),class,module,package/session

params:参数化,支持列表[],元组(),字典列表[{},{}],字典元组({},{})

autouse=True:自动执行,默认是False

ids:当使用params参数化时,给每一个值设置一个变量名,意义不大

name:给被@pytest.fixture标记的方法取一个别名

import pytest


class Test1:
    @pytest.fixture(scope="function")
    def my_fixture(self):     #用 @pytest.fixture()修饰my_fixture
        print("这里是前置")
        yield     #以yield为分界线,前边属于前置内容,后边属于后置内容
        print("这里是后置")

    def test_001(self,my_fixture):    #用例方法引用my_fixture实现test_001的前后置
        print("用例1")

    def test_002(self):
        print("用例2")

运行结果:

pytest测试框架_第6张图片

 作用域为class:

import pytest


class Test1:
    @pytest.fixture(scope="class",autouse=True)    #scope="class"设置为类的前后置,autouse=True自动执行
    def my_fixture(self):     #用 @pytest.fixture()修饰my_fixture
        print("这里是前置")
        yield     #以yield为分界线,前边属于前置内容,后边属于后置内容
        print("这里是后置")

    def test_001(self):   
        print("用例1")

    def test_002(self):
        print("用例2")

运行结果:

pytest测试框架_第7张图片

参数化:

pytest测试框架_第8张图片 执行结果:

pytest测试框架_第9张图片

 [{},{},{}]格式的参数:pytest测试框架_第10张图片

@pytest.mark.parameterize()方式的参数化,请参考文档Python测试框架pytest(17)参数化parametrize_wangmcn的博客-CSDN博客_python中的parametrize

十一、conftest.py和pytest.fixture()结合使用、

通过conftest.py和pytest.fixture()结合使用实现全局的前置应用 ,比如项目的全局登录,模块的全局处理

conftest.py文件是一个单独存放的一个夹具配置文件,文件名不能修改 ,放在用例的同层级下

可以在不同的py文件里面使用同一个前后置 fixture

conftest.py需要和运行中的用例放到同一层,并且不需要做任何的import导入的操作

 pytest测试框架_第11张图片

 pytest测试框架_第12张图片

 执行效果”

pytest测试框架_第13张图片

 总结:

setup/teardown,setup_class/teardown_class他是作用于所有用例或者所有类

@pytest.fixture()它的作用是既可以部分也可以全部前后置

conftest.py和@pytest.fixture()结合使用,作用域全局的前后置

十二、断言

assert   1==2,msg

十三、pytest结合allure-pytest生成allure测试报告

pytest测试框架_第14张图片

 总结:

先通过 pytest --alluredir ./temp 生成json格式的临时报告。

run.py主程序运行以下代码:

import os
import pytest

if __name__ == '__main__':
    pytest.main()
    os.system("allure generate ./temp -o ./report --clean")

pytest测试框架_第15张图片

十四、其它零碎(随时补充)

1.用--html生成的测试报告添加截图

pytest测试框架_第16张图片

2.--html只生成html文件

生成待时间戳的html文件

import time
import pytest

if __name__ == '__main__':
    current_time = str(int(time.time()))
    print(current_time)
    pytest.main(["--html=./report/report{}.html".format(current_time),"--self-contained-html"])

 

你可能感兴趣的:(pytest,单元测试)