pytest使用总结笔记
简介
pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。并且pytest兼容unittest的用例,支持的插件也更多
安装
pip install pytest
简单上手,创建个test_sample.py文件
def func(x):
return x + 1 def test_answer():
assert func(3) == 5
运行测试,直接在当前文件夹运行pytest
collected 1 item test_sample.py F [100%] ================================= FAILURES =================================
_______________________________ test_answer ________________________________ def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3) test_sample.py:6: AssertionError
============================ 1 failed in 0.12s =============================
pytest运行规则:查找当前目录及其子目录下以test_*.py或*_test.py文件,找到文件后,在文件中找到以test开头函数并执行。
以类来封装用例
# content of test_class.py
class TestClass:
def test_one(self):
x = "this"
assert "h" in x def test_two(self):
x = "hello"
assert hasattr(x, "check")
运行可以使用pytest [file_path]指定文件,-q是静默模式,不会打印用例输出
$ pytest -q test_class.py
.F [100%]
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________ self = <test_class.TestClass object at 0xdeadbeef> def test_two(self):
x = "hello"
> assert hasattr(x, "check")
E AssertionError: assert False
E + where False = hasattr('hello', 'check') test_class.py:8: AssertionError
1 failed, 1 passed in 0.12s
用例设计原则
- 文件名以test_*.py文件和*_test.py
- 以test_开头的函数
- 以Test开头的类
- 以test_开头的方法
- 所有的包pakege必须要有__init__.py文件
执行用例
1.执行某个目录下所有的用例
pytest 文件名/
2.执行某一个py文件下用例
pytest 脚本名称.py
3.-k 按关键字匹配
pytest -k "MyClass and not method"
这将运行包含与给定字符串表达式匹配的名称的测试,其中包括Python使用文件名,类名和函数名作为变量的运算符。 上面的例子将运行TestMyClass.test_something但不运行TestMyClass.test_method_simple
4.按节点运行
每个收集的测试都分配了一个唯一的nodeid,它由模块文件名和后跟说明符组成来自参数化的类名,函数名和参数,由:: characters分隔。
运行.py模块里面的某个函数
pytest test_mod.py::test_func
运行.py模块里面,测试类里面的某个方法
pytest test_mod.py::TestClass::test_method
5.标记表达式
pytest -m slow
将运行用@ pytest.mark.slow装饰器修饰的所有测试,slow是自己命名的标记,可以自定义
import pytest @pytest.mark.finished
def test_send_http():
pass def test_something_quick():
pass
运行测试时使用-m选项可以加上逻辑
>pytest -m "finished and commit" //匹配finished和commit运行 >pytest -m "finished and not merged" //finished运行,merged不运行
6.从包里面运行
pytest --pyargs pkg.testing
这将导入pkg.testing并使用其文件系统位置来查找和运行测试。
7.在第一个(或N个)失败后停止
pytest -x # stop after first failure
pytest --maxfail=2 # stop after two failures
8.跳过测试
使用pytest.mark.skip标记需要跳过的用例
@pytest.mark.skip(reason="not finished")
def test_send_http():
pass
也支持使用 pytest.mark.skipif 为测试函数指定被忽略的条件
@pytest.mark.skipif(finishflag==Fasle,reason="not finished")
def test_send_http():
pass
9.脚本调用执行
直接使用 pytest.main() 像命令行一样传递参数 pytest.main(["-x", "mytestdir"])
用例编写
断言
pytest直接使用python assert语法来写
def f():
return 3 def test_function():
assert f() == 4
断言中添加消息
assert a % 2 == 0, "value was odd, should be even"
预设与清理
与unittest中的setup和teardown类似,pytest也有这样的环境清理方法,主要有
模块级(setup_module/teardown_module)开始于模块始末,全局的
函数级(setup_function/teardown_function)只对函数用例生效(不在类中)
类级(setup_class/teardown_class)只在类中前后运行一次(在类中)
方法级(setup_method/teardown_method)开始于方法始末(在类中)
类里面的(setup/teardown)运行在调用方法的前后
import pytest class TestClass: def setup_class(self):
print("setup_class:类中所有用例执行之前") def teardown_class(self):
print("teardown_class:类中所有用例执行之前") def setup_method(self):
print("setup_method: 每个用例开始前执行") def teardown_method(self):
print("teardown_method: 每个用例结束后执行") def setup(self):
print("setup: 每个用例开始前执行") def teardown(self):
print("teardown: 每个用例结束后执行") def test_one(self):
print("执行第一个用例") def test_two(self):
print("执行第二个用例") def setup_module():
print("setup_module:整个.py模块只执行一次") def teardown_module():
print("teardown_module:整个.py模块只执行一次") def setup_function():
print("setup_function:每个方法用例开始前都会执行") def teardown_function():
print("teardown_function:每个方法用例结束前都会执行") def test_three():
print("执行第三个用例")
使用pytest -s test_sample.py运行,-s参数是为了显示用例的打印信息,下面是输出,可以看出几个方法之间的优先级
test_sample.py setup_module:整个.py模块只执行一次
setup_class:类中所有用例执行之前
setup_method: 每个用例开始前执行
setup: 每个用例开始前执行
执行第一个用例
.teardown: 每个用例结束后执行
teardown_method: 每个用例结束后执行
setup_method: 每个用例开始前执行
setup: 每个用例开始前执行
执行第二个用例
.teardown: 每个用例结束后执行
teardown_method: 每个用例结束后执行
teardown_class:类中所有用例执行之前
setup_function:每个方法用例开始前都会执行
执行第三个用例
.teardown_function:每个方法用例结束前都会执行
teardown_module:整个.py模块只执行一次
注意:setup_method和teardown_method的功能和setup/teardown功能是一样的,一般二者用其中一个即可;函数里面用到的setup_function/teardown_function与类里面的setup_class/teardown_class互不干涉
参数化
使用pytest.mark.parametrize(argnames, argvalues)可以实现函数的参数化
@pytest.mark.parametrize('text',['test1','test2','test3'])
def test_one(text):
print(text)
argnames就是形参名称,argvalues就是待测的一组数据
固件fixture
基本使用
固件Fixture是一些函数,pytest 会在执行测试函数之前(或之后)加载运行它们。主要是为一些单独测试用例需要预先设置与清理的情况下使用的。
不同于上面的setup和teardown的就是,可以自定义函数,可以指定用例运行,使用方法如下
@pytest.fixture()
def text():
print("开始执行") #使用pytest.fixture()装饰一个函数成为fixture def test_one():
print("执行第一个用例") def test_two(text): #用例传入fixture函数名,以此来确认执行
print("执行第二个用例")
使用yield可以实现固件的拆分运行,yield前在用例前执行,yield后再用例后执行
@pytest.fixture()
def text():
print("开始执行")
yield #yield 关键词将固件分为两部分,yield 之前的代码属于预处理,会在测试前执行;yield 之后的代码属于后处理,将在测试完成后执行
print("执行完毕") def test_one():
print("执行第一个用例") def test_two(text):
print("执行第二个用例")
统一管理
固件可以直接定义在各测试脚本中,就像上面的例子。更多时候,我们希望一个固件可以在更大程度上复用,这就需要对固件进行集中管理。Pytest 使用文件 conftest.py 集中管理固件。
不用显式调用 conftest.py,pytest 会自动调用,可以把 conftest 当做插件来理解
./conftest.py @pytest.fixture()
def text():
print("开始执行")
yield
print("执行完毕") ./test_sample.py def test_one():
print("执行第一个用例") def test_two(text):
print("执行第二个用例")
作用域
fixture可以通过 scope 参数声明作用域,比如
- function: 函数级,每个测试函数都会执行一次固件;
- class: 类级别,每个测试类执行一次,所有方法都可以使用;
- module: 模块级,每个模块执行一次,模块内函数和方法都可使用;
- session: 会话级,一次测试只执行一次,所有被找到的函数和方法都可用。
./conftest.py @pytest.fixture(scope="module")
def text():
print("开始执行")
yield
print("执行完毕") ./test_sample.py def test_one(text):
print("执行第一个用例") def test_two(text):
print("执行第二个用例")
执行情况
test_sample.py 开始执行
执行第一个用例
.执行第二个用例
.执行完毕
如果对于类使用作用域,需要使用 pytest.mark.usefixtures(对函数和方法也适用)
./conftest.py @pytest.fixture(scope="class")
def text():
print("开始执行")
yield
print("执行完毕") ./test_sample.py @pytest.mark.usefixtures('text')
class TestClass: def test_one(self):
print("执行第一个用例") def test_two(self):
print("执行第二个用例")
自动运行
将fixture的autouse参数设置为True时,可以不用传入函数,自动运行
./conftest.py @pytest.fixture(scope="module",autouse=True)
def text():
print("开始执行")
yield
print("执行完毕") ./test_sample.py def test_one():
print("执行第一个用例") def test_two():
print("执行第二个用例")
参数化
使用fixture的params参数可以实现参数化
./conftest.py @pytest.fixture(scope="module",params=['test1','test2'])
def text(request):
print("开始执行")
yield request.param
print("执行完毕") ./test_sample.py def test_one(text):
print("执行第一个用例")
print(text) def test_two(text):
print("执行第二个用例")
固件参数化需要使用 pytest 内置的固件 request,并通过 request.param 获取参数。
结果如下
test_sample.py 开始执行
执行第一个用例
test1
.执行第二个用例
.执行完毕
开始执行
执行第一个用例
test2
.执行第二个用例
.执行完毕
生成报告
HTML报告
安装pytest-html
pip install pytest-html
使用方法是,直接在命令行pytest命令后面加--html=<文件名字或者路径>.html参数就可以了
pytest --html=report.html
结果如下
上面生成的报告包括html和一个assets文件(里面是报告CSS样式),如果要合成一个文件可以添加下面的参数
pytest --html=report.html --self-contained-html
XML报告
使用命令可以生成XML格式报告
pytest --junitxml=report.xml
allure报告
1.首先安装java环境
下载JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html
安装对应系统的包,如windowsx64是xxx-windows-x64.exe
一路下一步安装就可以了
然后在环境变量中添加下面变量
变量名:JAVA_HOME
变量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根据自己的实际路径配置 变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"." 变量名:Path
变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
然后再cmd中运行 java -version、java、javac 几个命令没有报错即可
2.安装allure
下载allure 会跳转到github,找到link下载
解压包后进入bin文件,复制路径并添加到环境变量Path中
cmd运行allure命令,没有报错即正确
3.pytest使用
安装插件
pip install allure-pytest 如果timeout就加 --index-url https://pypi.douban.com/simple 用豆瓣源
进入测试py文件目录,运行
pytest --alluredir ./report
运行完成后生成report文件,-alluredir后面跟的是文件路径,可以自定义
使用allure查看报告,直接启动allure server后面加报告路径就行
allure serve report(报告文件夹名)
等一会就生成报告
参考:
https://learning-pytest.readthedocs.io/zh/latest/index.html
https://docs.pytest.org/en/latest/contents.html
pytest使用总结笔记的更多相关文章
- pytest参数化代码笔记
#!/usr/local/bin/python3 # -*- coding: utf-8 -*- import pytest __author__ = "Carp-Li" __da ...
- pytest使用笔记(三)——pytest+allure+jenkins配置使用
按照pytest使用笔记(二)把pytest+allure配置好后,现在在jenkins配置好,先实现手动构建(立个小目标) 一,安装jenkins插件 首页->系统管理->插件管理,从“ ...
- [转载]pytest学习笔记
pytest学习笔记(三) 接着上一篇的内容,这里主要讲下参数化,pytest很好的支持了测试函数中变量的参数化 一.pytest的参数化 1.通过命令行来实现参数化 文档中给了一个简单的例子, ...
- Pytest学习笔记5-conftest.py的用法
前言 在之前介绍fixture的文章中,我们使用到了conftest.py文件,那么conftest.py文件到底该如何使用呢,下面我们就来详细了解一下conftest.py文件的特点和使用方法吧 什 ...
- Pytest学习笔记6-自定义标记mark
前言 在pytest中,我们可以使用mark进行用例的自定义标记,通过不同的标记实现不同的运行策略 比如我们可以标记哪些用例是生产环境执行的,哪些用例是测试环境执行的,在运行代码的时候指定对应的mar ...
- Pytest学习笔记7-skip和skipif的使用
前言 在实际的测试中,我们经常会遇到需要跳过某些测试用例的情况,pytest提供了skip和ifskip来跳过测试 下面我们就来通过一些例子看看skip和ifskip具体如何使用吧 skip的用法 使 ...
- Pytest学习笔记11-重复执行用例插件pytest-repeat
前言 我们在平时做测试的时候,经常会遇到一些偶现的bug,通常我们会多次执行来复现此类bug,那么在自动化测试的时候,如何多次运行某个或某些用例呢,我们可以使用pytest-repeat这个插件来帮助 ...
- Pytest学习笔记12-配置文件pytest.ini
前言 pytest配置文件可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行. 常用的配置项 marks 作用:测试用例中添加了自定义标记( ...
- pytest学习笔记(三)
接着上一篇的内容,这里主要讲下参数化,pytest很好的支持了测试函数中变量的参数化 一.pytest的参数化 1.通过命令行来实现参数化 文档中给了一个简单的例子, test_compute.py ...
随机推荐
- 四十五.加密与解密 AIDE入侵检测系统 扫描与抓包
一.加密与解密 1.1 常见的加密算法 对称加密:怎么加密,就怎么解密 DES Date Encryption Standard AES Advance Encryption Standard 非对称 ...
- 使用 ServerSocket 建立聊天服务器-2
1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...
- 西门子二次开发--HMI failed to start
一.Sinumerik二次开发错误:HMI failed to start. HMI--SL Framework reported error: GUI Component could not be ...
- Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...
- AtCoder Grand Contest 002题解
传送门 \(A\) 咕咕 int main(){ cin>>a>>b; if(b<0)puts(((b-a+1)&1)?"Negative": ...
- Windows10下安装Ubuntu18.04LTS详细教程
这篇文章分享自己在Windows10系统下安装VMware虚拟机,然后在VMware中安装Ubuntu 18.04 LTS的详细过程.之所以选择在虚拟机中安装Ubuntu,主要是可以不影响自己电脑的正 ...
- 使用scala通过JNI技术调用c++代码
scala代码编写 Sample1.scala class Sample1 { // --- Native methods @native def intMethod(n: Int): Int def ...
- 新的log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- OFF < FATAL < ERROR & ...
- mysql5.7 源码安装步骤
操作系统:centos 7 mysql版本:5.7 下载地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-gli ...
- spring boot 之 如何创建spring boot项目
创建spring boot的方式有非常多,今天我们使用maven来进行创建spring boot项目,因为maven使用的非常广泛,也很好用,很多IDE也都支持maven. 1 创建maven项目 1 ...