为什么要写pytest?

之前分享了java自动(详见:),

部分测友建议分享一个python版本自动化,

而pytest这个热门单元测试框架作为python自动化中的必备技术栈,必须单独拎出来详解。

后续分享基于pytest最新版,和老版本有微小差异。

 

pytest简易教程(01):pytest介绍及基本使用_用例

 

pytest介绍

官网:https://www.osgeo.cn/pytest/contents.html

pytest是python语言下的一种单元测试框架,与python自带的unittest单元测试框架类似,相比于unittest框架使用起来更简洁,效率更高。

(补充:java语言下的单元测试框架是junit和testng)

pytest可以结合requests实现接口测试,结合selenium/playwright、appium实现自动化功能测试。

 

pytest特点:

1.具有unittest绝大部分功能,非常容易上手,入门简单,功能灵活,文档丰富,文档中有很多实例可以参考

2.具有强大灵活的fixture固件,支持简单的单元测试和复杂的功能测试;

3.支持参数化(parametrize)、数据驱动

4.执行测试过程中可以将某些测试跳过(skip),或者对某些预期失败的case标记成失败(xfail)

5.支持重复执行(rerun)失败的case

6.支持运行由nose ,unittest编写的测试case

7.支持执行部分用例(比如:根据标记,或者features、stories,后者一来allure-pytest插件)

8.具有很多第三方插件(顺序控制pytest-ordering、allure报告allure-pytest、多线程pytest-xdist、......),并且可以自定义开发插件

9.可生成html报告,也可以结合allure生成精美的测试报告

10.方便的和持续集成工具jenkins集成

 

和unittest区别:

不同点

unittest

pytest

命名

测试方法以test开头

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

类以Test开头

方法/函数以test开头

 框架结构

写case必须定义类,测试类要继承unitttest.TestCase

不需要继承,可以是函数也可以是类中方法

 测试报告

使用HTMLTestRunner

使用allure-pytest

 数据驱动

参数化使用第三方ddt

参数化使用自带的parametrize

 断言

断言库丰富

采用python断言:使用assert关键字

 失败重试

不支持 

支持

 固件

 -

灵活的fixture固件

 扩展性

 -

快速自定义插件开发

  

pytest测试用例编写规则

类型

规则

模块

模块名必须以test_开头,也就是:test_*.py

或者_test结尾,也就是:*_test.py

建议:test_+业务名称


测试类类名以Test开头

说明:测试类中不能包含__init__构造方法,添加构造方法后就不是测试类了,里面的测试方法都识别不到

方法/函数

以test开头


包名无特殊要求

包必项要有__init__.py文件

 

安装pytest

前提:已经安装、配置python环境

参考:

通过命令安装

安装命令:pip install pytest

如果安装不了,请更换pip源,参考:

pytest简易教程(01):pytest介绍及基本使用_python_02

 

如果已经安装,升级到最新版本:pip install -U pytest

pytest简易教程(01):pytest介绍及基本使用_python_03

 

通过pycharm安装

pycharm中安装需要的包,在settings中,选择Python Interpreter,然后点击“+”

pytest简易教程(01):pytest介绍及基本使用_用例_04

 

搜索要安装的包,右下角可以选择需要的版本,最后左下角安装即可

pytest简易教程(01):pytest介绍及基本使用_测试方法_05

 

验证是否安装成功

pytest --version

pytest简易教程(01):pytest介绍及基本使用_用例_06

 

pycharm默认测试执行器

settings中,进入Tools -> Python Intergrated Tools,Default test runner默认是自动发现的,可以直接选择pytest

pytest简易教程(01):pytest介绍及基本使用_测试方法_07

 

也可以settings中搜索pytest快速进入Python Intergrated Tools

pytest简易教程(01):pytest介绍及基本使用_python_08

 

第一个示例

pytest简易教程(01):pytest介绍及基本使用_python_09

 

test_qzcsbj.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : 韧


def inc(x):
    return x + 1

def test_a():
    print("---test_a")
    assert inc(0) == 1

class TestCase:
    def test_b(self):
        print("---test_b")
        assert "cs" in "qzcsbj"

 

pycharm中运行

左侧有绿色执行按钮

pytest简易教程(01):pytest介绍及基本使用_用例_10

 

点击绿色按钮,用的pytest解释器执行的,而不是python解释器

pytest简易教程(01):pytest介绍及基本使用_测试方法_11

 

结果(pycharm中执行,选中“√”才展示所有测试方法)

pytest简易教程(01):pytest介绍及基本使用_用例_12

 

一次执行模块中所有方法

  1、可以非测试方法处点右键执行

  2、也可以用main方法运行:调用pytest的main函数执行测试,需要import pytest

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : 韧


import pytest

def inc(x):
    return x + 1

def test_a():
    print("---test_a")
    assert inc(0) == 1

class TestCase:
    def test_b(self):
        print("---test_b")
        assert "cs" in "qzcsbj"

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

  

pytest.main()等价于pytest.main(["./"]),运行当前目录下的所有用例

点击main左侧绿色按钮

pytest简易教程(01):pytest介绍及基本使用_测试方法_13

 

结果

pytest简易教程(01):pytest介绍及基本使用_python_14

 

补充:

  如果放到vscode中,会执行工程下所有用例,只运行当前模块的用例,需要加参数__file__,表示当前文件

if __name__ == '__main__':
    pytest.main([__file__])

 

命令运行

注:此时用例文件中有main方法,把main方法注释掉

pytest简易教程(01):pytest介绍及基本使用_用例_15

 

进入项目目录,执行pytest

test_a改为失败,一个成功一个失败,成功是.,失败是F

pytest简易教程(01):pytest介绍及基本使用_用例_16

 

pytest等价于python -m pytest

pytest简易教程(01):pytest介绍及基本使用_测试方法_17

 

但是,

如果没有main方法,执行python case\test_qzcsbj.py,下面没有结果

pytest简易教程(01):pytest介绍及基本使用_用例_18

 

如果有main方法

pytest简易教程(01):pytest介绍及基本使用_python_19

执行python case\test_qzcsbj.py,就有结果

pytest简易教程(01):pytest介绍及基本使用_python_20

 

总结

用pytest的解释器执行用例:1、命令行中直接执行pytest;2、pycharm中方法和类,直接点绿色执行按钮运行;模块和包,选中模块或者包,然后右键运行;或者非测试方法处点右键执行(因为pycharm默认测试执行器是pytest)

用python的解释器执行用例:1、命令中执行python -m pytest调用pytest(jenkins持续集成可用到,可指定不同版本的python);2、有main函数,命令中执行python xxx.py,调用py文件中main函数中的pytest.main();说明:直接执行这个模块,被执行的模块是main(可print(__name__)查看结果),如果此模块被其它模块导入,这个模块就不是main了。

 

主要命令参数

参数

说明

--help

查看帮助,等同-h

-q

简化控制台的输出,只输出执行结果,几条用例通过或不通过

-v

详细输出,打印详细日志,可以看到用例执行的先后顺序、结果;如果不加-v,成功看到的是绿色.,失败看到的是红色F 

-s

调试输出,就是输出print的内容,等价于pytest --capture=no,可以捕获print函数的输出

一般和-v一起用,-vs

-k

测试方法名中包含指定关键字的测试用例,支持and、or、not

比如:

  pytest -k test_2,或者pytest -k "test_2"

  pytest -k "test_2 or test_1",这里要用双引号

  pytest -k "not test_1"

-m

通过标志表达式运行

比如:pytest -m user,pytest -m "user",将运行 @pytest.mark.user装饰器修饰的所有用例

  等价main中,pytest.main(["-m","user"]),一般加上-vs,pytest.main(["-vs","-m","user"]) 

-n=2

多线程运行(依赖于插件)

-x

用例一旦失败(fail/error)就立即停止测试(相当于冒烟测试,失败就停止,哪怕没执行完,也不用关心后面的执行结果),等价于pytest --exitfirst

--maxfail=n

在第n次失败后停止测试,也就是失败数达到num就停止

 --lf

重跑上次失败用例,等价于--last-failed;命令行参数使用缓存状态


如果这些失败的都成功了,再次运行,会把所有成功的都运行,而不是没有失败的了就不运行了

--collect-only

收集测试用例(不执行)

 

-h参数

pytest -h的结果分类:

1. 命令行参数
用于pytest运行时的参数,比如-k、-m等,有通用类、报告类、收集类、调试类、日志类等

通用类

pytest简易教程(01):pytest介绍及基本使用_测试方法_21

 

报告类

pytest简易教程(01):pytest介绍及基本使用_用例_22

 

告警

pytest简易教程(01):pytest介绍及基本使用_测试方法_23

 

收集

pytest简易教程(01):pytest介绍及基本使用_测试方法_24

 

调试

pytest简易教程(01):pytest介绍及基本使用_测试方法_25

 

日志

pytest简易教程(01):pytest介绍及基本使用_用例_26

 

2. 元数据

pytest简易教程(01):pytest介绍及基本使用_用例_27

3.配置参数:pytest.ini中配置的参数

pytest简易教程(01):pytest介绍及基本使用_python_28

 

4.环境变量

pytest简易教程(01):pytest介绍及基本使用_测试方法_29

 

5.重跑失败

pytest简易教程(01):pytest介绍及基本使用_测试方法_30

 

-s参数

示例:上面示例发现,如果用例执行成功,print内容没显示,可以加-s参数捕获print函数的输出

pytest简易教程(01):pytest介绍及基本使用_用例_31

 

 

其它参数用法,后续篇幅通过示例演示。

 

【bak】

 

 

__EOF__


本文作者:持之以恒(韧)
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevTestOps)、测开等