一、安装
pytest不是python默认的package,需要手动安装。
pytest支持python 2.6--3.5之间的版本,同时可以在windows、unix系统上安装
安装方式:
pip install pytest
安装完成后,可以查看版本:
pytest --version
二、pytest 用例规则
pytest可以在不同的函数、包中发现用例,发现的规则如下
- 文件名以test_开头的py文件
- 以test_开头的函数
- 以Test开头的类
- 以test_开头的方法(与2类似)
- 要注意的是所有的包必须要有init.py文件(在使用各种编辑器时会自动生成)
三、第一个测试例子
1.创建test_stsrt.py文件,创建一个方法、一个用例
import pytest
def func(x):
return x + 1
def test_answer():
assert func(3) == 5
# 执行 case,我们可以直接使用 main 方法去运行代码
# 也可以在 Terminal 中,进入当前目录下使用 pytest test_start.py 执行 case
if __name__ == '__main__':
pytest.main(["-s", __file__])
2.执行结果
(venv) zhulixiangdeMacBook-Pro:Day10 zhulixiang$ pytest test_start.py
================================================================== test session starts ==================================================================
platform darwin -- Python 3.7.5, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/zhulixiang/Downloads/pythonProject/thz/Day10
plugins: PyTestReport-0.2.1, metadata-1.11.0, json-report-1.4.1, ordering-0.6, Faker-9.5.1
collected 1 item
test_start.py F [100%]
======================================================================= FAILURES ========================================================================
______________________________________________________________________ test_answer ______________________________________________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_start.py:9: AssertionError
================================================================ short test summary info ================================================================
FAILED test_start.py::test_answer - assert 4 == 5
=================================================================== 1 failed in 0.12s ===================================================================
此测试返回失败报告,因为func(3)
不返回5。
四、pytest参数
import pytest
from pytest_jsonreport.plugin import JSONReport
def calc(a, b):
return a + b
# case 标签,一个 case 可以有多个标签
# 格式为 @pytest.mark.标签名,标签名命令随意
@pytest.mark.smoke
# case 的优先级,数值越小优先级越大
# 格式为 @pytest.mark.run(order=(0-10))
@pytest.mark.run(order=10)
def test_calc():
print("test_calc")
ret = calc(1, 2)
assert ret == 2
@pytest.mark.pre
@pytest.mark.smoke
@pytest.mark.run(order=1)
def test_calc2():
print("test_calc2")
ret = calc(1.0, 2)
assert ret == 3.0
# case 参数化
# 格式为 @pytest.mark.parametrize(参数名,参数的二维数组)
@pytest.mark.parametrize("a,b,c", [
[1, 2, 3],
[1, 3, 4],
[1, 5, 6],
[1, 6, 8],
])
def test_calc_p(a, b, c):
ret = calc(a, b)
assert ret == c
# case 参数化,如果写了多个 parametrize,那么 pytest 会自动组合所有的测试 case
# 所以 test_login 一共需要执行 2 条用例,分别为 username:"11123",password:"123456" 和 username:"sdgsdg@qq.com",password:"123456"
@pytest.mark.parametrize('username', ["11123", "sdgsdg@qq.com"])
@pytest.mark.parametrize('password', ["123456"])
def test_login(username, password):
print("=" * 30)
print(username, password)
class TestCalc:
@pytest.mark.prod
@pytest.mark.run(order=2)
def test_calc3(self):
print("test_calc3")
ret = calc(3, 3)
assert ret == 6
if __name__ == '__main__':
pytest.main() # 如果什么也不指定,从当前目录下所有文件夹里面搜索case
pytest.main(["-q", __file__]) # 安静模式,不会显示pytest版本信息等等,__file__ 表示当前路径的绝对路径
pytest.main(["-v", __file__]) # 详细模式,会打印每条case执行结果,指定python文件
pytest.main(["-s", __file__]) # 展示模式,函数里面有print或者日志输出,会展示,指定python文件
pytest.main(["-vs", "./cases", ]) # 展示模式+详细模式,指定目录
pytest.main(["-vs", "a.py", "b.py"]) # 展示模式+详细模式,指定目录
pytest.main(["./cases", "-k", "login"]) # 指定运行包含login关键字的,包括 py文件、类、函数
pytest.main(["./cases", "-k", "login or register"]) # 指定运行包含login或者register关键字的,包括 py文件、类、函数
pytest.main(["./cases", "-k", "login and online"]) # 指定运行包含login并且包含online关键字的,包括 py文件、类、函数
pytest.main(["./cases", "-m", "smoke"]) # 指定运行smoke标签的case
pytest.main(["./cases", "-m", "smoke or online"]) # 指定运行smoke或者online标签的case
pytest.main(["./cases", "-m", "smoke and online"]) # 指定运行smoke是并且是online标签的case
pytest.main(["./cases", "-sk", "user", "-m", "smoke"]) # 指定运行名称中包含user的,标签是smoke的case
pytest.main(["./cases", "-sk", "user", "-m", "smoke", "--last-failed"]) # 指定运行名称中包含user的,上次失败的标签是smoke的case
pytest.main(["./cases", "-sk", "user", "-m", "smoke", "--failed-first"]) # 指定运行名称中包含user的,优先运行上次失败的标签是smoke的case
五、生成测试报告
需要先 import JSONReport 模块
from pytest_jsonreport.plugin import JSONReport
执行代码:
if __name__ == '__main__':
# 实例化对象
plugin = JSONReport()
pytest.main(["-vs", '--json-report-file=none', __file__, "-m", "smoke",
"--pytest_report", "py_test_report.html", "--pytest_title", "这是测试报告的标题", "--pytest_desc", "测试报告描述"],
plugins=[plugin]
) # 展示模式+详细模式,指定python文件
summary = plugin.report.get("summary")
print(summary) # case 执行结果
print(summary.get("passed")) # 通过的 case
print(summary.get("failed")) # 失败的 case
print(summary.get("skipped")) # 跳过的 case
print(summary.get("total")) # 一共有多少 case
报告截图:(点击浏览器图标就可以在浏览器中打开,查看测试报告)
浏览器打开测试报告:
六、 pytest 运行方式
1.单独执行某一个py文件里所有的用例
pytest test_start.py
2.执行目录下所有用例
pytest case/
3.单独执行某个用例
# 以函数形式的用例
pytest pytest-1.py::test_calc
# 以类形式的用例
pytest pytest使用.py::TestCalc::test_calc3