Pytest测试框架
Pytest测试框架
简介
PyTest
是一个常用的 Python 测试框架,它提供了简单灵活的方式来编写测试代码,并且具有丰富的扩展和插件生态系统。
PyTest
能够支持简单的单元测试和复杂的功能测试;PyTest
可以结合Requests
实现自动化接口测试;- 结合
Selenium
、Appium
实现 Web 自动化测试; - 使用
PyTest
结合Allure
集成到Jenkins
中可以实现持续集成。 PyTest
支持 315 种以上的插件;
环境安装与配置
安装模块
前提:本地已配置完成 Python 环境
pip install pytest
环境配置
PyCharm 默认测试执行器为 Pytest,也可自行设置。
- 进入
Settings
->Tools
->Python Intergrated Tools
-Testing
- 选择
Default test runner
为pytest
命名规则
类型 | 规则 |
---|---|
文件 | test_ 开头 或者 _test 结尾 |
类 | Test 开头 |
方法/函数 | test_ 开头 |
注意:测试类中不可以添加__init__ 构造函数 |
函数级别测试用例示例
- 格式
def test_XXX(): # 测试步骤1 # 测试步骤2 # 断言 实际结果 对比 预期结果 assert ActualResult == ExpectedResult
- 示例
import pytest def add_one(x): return x + 1 def test_answer(): assert add_one(3) == 5 if __name__ == "__main__": # 运行测试用例 pytest.main() # 也可以在终端执行 pytest 测试用例文件 执行测试用例 # #pytest test_case.py
类级别的用例示例
- 格式
# 定义一个测试类,方便管理测试用例 class TestXXX: # 测试类中的测试方法,一个方法对象一个测试用例 def test_XXX(self): # 测试步骤1 # 测试步骤2 # 断言 实际结果 对比 预期结果 assert ActualResult == ExpectedResult
- 示例
# 测试添加功能的模块 import pytest def add_one(x): return x + 1 # 定义一个测试类 class TestCaseManager(object): def test_answer(self): assert add_one(1) == 2
断言
断言 assert
,是一种在程序中为了表示与验证软件开发者预期的结果。
当程序执行到断言的位置时,对应的断言应该为真。若断言不为真时,给出错误信息。
断言语法
# 方式一
assert <bool expression>;
# 方式二
assert <bool expression> , <message>;
第一种:assert <表达式>
示例
def test_a():
assert True
def test_b():
assert 'abc' in "abcd"
第二种:assert <表达式>, <描述>
示例
断言结果为真时,描述信息不展示
def test_c():
a = 1
b = 1
c = 2
assert a + b == c, f"{a}+{b}=={c}, 结果为假"
import sys
def test_platform():
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
常见的断言形式
断言格式 | 说明 |
---|---|
assert xx |
判断 xx 为真 |
assert not xx |
判断 xx 不为真 |
assert a in b |
判断 b 包含 a |
assert a == b |
判断 a 等于 b |
assert a != b |
判断 a 不等于 b |
示例
def test_assert_true():
a = 1
assert a
def test_assert_false():
a = False
assert not a
def test_assert_in():
a = "霍格沃兹测试开发学社"
b = "霍格沃兹"
assert b in a
def test_assert_equal():
a = "霍格沃兹测试开发学社"
b = "霍格沃兹测试开发学社"
assert a == b
def test_assert_unequal():
a = "霍格沃兹测试开发学社"
b = "霍格沃兹"
assert a != b
测试装置
Pytest中装置用来在用例执行之前或之后,完成资源准备或回收的操作。
例如:
- 初始/关闭数据库
- 打开/关闭浏览器
- 读取/清理测试数据
常用测试装置
类型 | 规则 |
---|---|
setup_class / teardown_class |
类级,只在类中前后运行一次 |
setup_method / teardown_method |
在类中,运行在调用方法的前后 |
# 用例类中配置装置
class TestCaseManager(object):
def setup_class(self):
print("setup_class,类级测试装置,只执行一次")
def setup_method(self):
print("setup_method,方法级测试装置,每个测试用例执行时都会执行一次")
def teardown_method(self):
print("teardown_method,方法级测试装置,每个测试用例执行时都会执行一次")
def teardown_class(self):
print("teardown_class,类级测试装置,只执行一次")
def test_case1(self):
assert True
def test_case2(self):
assert True
运行结果
========== test session starts ==========
collecting ... collected 2 items
test_add.py::TestCaseManager::test_add1
setup_class,类级测试装置,只执行一次
setup_method,方法级测试装置,每个测试用例执行时都会执行一次
PASSED [ 50%]
teardown_method,方法级测试装置,每个测试用例执行时都会执行一次
test_add.py::TestCaseManager::test_add2
setup_method,方法级测试装置,每个测试用例执行时都会执行一次
PASSED [100%]
teardown_method,方法级测试装置,每个测试用例执行时都会执行一次
teardown_class,类级测试装置,只执行一次
========== 2 passed, 4 warnings in 0.02s ==========
数据参数化
在执行测试用例时,经常会出现同一个测试场景下,使用不同的数据来验证的情况,此时就可以使用参数形式。
Pytest
使用装饰器 @pytest.mark.parametrize("参数名",[数据列表])
实现参数化
- 参数名要使用字符串表示, 多个参数之间使用逗号分隔, 参数名要和测试函数参数名相同
- 数据列表中是参数化的数据,提供的结构需要和变量定义的结构相同
数据参数化示例
简单的参数化形式
@pytest.mark.parametrize("param",["Tom","Jack", "Rose"])
def test_case01(param):
print("Test Case 01 Run ....")
print(param)
复杂的参数化形式
@pytest.mark.parametrize("name, age, habby",[["Tom",18,["eat","drink","play"]],["Rose",18,["eat","drink","play"]]])
def test_case02(name, age, habby):
print("Test Case 02 Run ....")
print(name)
print(age)
for v in habby:
print(v)
使用 YAML 文件进行数据驱动测试
data.yaml
- - 1
- 2
- 3
- - 4
- 5
- 9
- - 7
- 8
- 9
- - 11
- 22
- 33
test_case.py
import yaml
import pytest
def add(a, b):
return a + b
with open("data.yaml", "r") as file:
data = yaml.safe_load(file)
@pytest.mark.parametrize("a, b, expect", data)
def test_add(a, b, expect):
assert add(a, b) == expect