1 pytest
# 如何使用python进行测试?
进行请求场景的封装之后,我们还需要进行针对测试参加的改造。
主要的诉求有以下几点:
1.需要校验响应结构的功能(检查点),并且要能进行数据/报告转化
2.需要进行有效的组织,测试py文件、测试case、测试点等等
3.需要结合jenkins进行自动执行(命令行工具)
4.需要实现测试常用的需求,例如给case打标签、一个case对应多个断言、正交生成case。。。。
# 什么是pytest?
pytest是一个强大的Python测试工具,它可以用于所有类型和级别的软件测试。 Pytest可以被开发团队,QA团队,独立测试小组,实践TDD的个人和开放源代码项目。
实际上,整个互联网上的项目都是从unittest或者nose转向pytest,包括Mozilla和Dropbox。为什么?因为pytest提供 强大的功能,如'断言'重写,第三方插件模型,强大但简单的fixture模型。
pytest是软件测试框架,这意味着pytest是命令行工具。它会自动找到你写的测试,运行测试并报告结果。可编写插件或安装第三方来扩展插件。它可以用来测试Python发行版。它很容易与其他工具对接,如持续集成和网页自动化。
Pytest脱颖而出的原因:
- 简单
- 易读
- 用assert来测试失败,而不是self.assertEqual() 或者self.assertLessThan()
- 可运行unittest或nose测试。
事实上很多自动化测试平台,底层就是用驱动的。它们用flask或django等提供友好的页面展示,但是核心层还是在pytest和一些测试库的开发。
# pytest入门
1.安装
pip install pytest
需要注意的是,pytest生态之中有众多的插件。插件有往往依赖pytest主体版本,所以大多数时候我们需要指定pytest版本
pytest 5.4.2
allure-pytest 2.8.16
2.测试用例有什么规则
# 1.测试case所属的py文件,需要以test开头
# 2.用作case的类需要以Test开头
# 3.case方法需要以test_开头
class TestCase():
def setup_class(self):
print("setup_class:所有用例执行之前")
def teardown_class(self):
print("teardown_class:所有用例执行之前")
def test_case1(self):
print("正在执行----test_three")
x = "this"
assert 'h' in x
def test_case2(self):
print("正在执行----test_four")
x = "hello"
assert hasattr(x, 'check')
if __name__ == "__main__":
pytest.main(["-s", "关于初始化方法.py"])
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
3.检查点怎么写
# 安装多断言插件
# pip install pytest-assume
# 原始单断言:
# assert 1==2
# 插件的多断言:
# pytest.assume(1==2)
class TestClass:
def test_one(self):
x = "this"
pytest.assume('h' in x)
pytest.assume('pp' in x)
pytest.assume('spo' in x)
# def test_two(self):
# x = "hello"
# assert hasattr(x, 'check')
#
# def test_three(self):
# a = "hello"
# b = "hello world"
# assert a in b
if __name__ == "__main__":
pytest.main('-q test_class.py')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
3.参数化case如何实现
import pytest
#单个参数:@pytest.mark.parametrize("参数bai名",["01_值1","02_值2"])
@pytest.mark.parametrize('passwd',
['123456',
'abcdefdfs',
'as52345fasdf4'])
@pytest.mark.skip
def test_passwd_length(passwd):
assert len(passwd) >= 8
# 一组参数(列表)
# ①指定变量进行接收
data = [[1, 2, 3],[4, 5, 9]]
# @pytest.mark.parametrize('a, b, res', data)
# def test_parametrize_1(a, b, res): # 一个参数接收一个数据
# print(f'当前测试内容是:{a}+{b}={res}?')
# actual = a + b
# assert actual == res
# ②整体接收列表
@pytest.mark.parametrize('value', data)
def test_parametrize_2(value): # 一个参数接收一组数据
print(f'当前取到的数据是{value}')
res = value[0] + value[1]
assert res == value[2]
if __name__ == "__main__":
pytest.main('-q 参数化设计.py')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
*4.pytest如何与第三方库结合
安装一个用于生成多因子case的库:pip install allpairspy
进行以下测试
# 导入库
from allpairspy import AllPairs
# 列出所有参数
parameters = [
["Ie", "Firefox", "Chrome", "UC", "QQ"],
["Ios10", "Ios11", "Ios12", "Ios13"],
["用例1", "用例2", "用例3", "用例4", "用例5"]
]
# 输出 pairwise 参数组合
if __name__ == '__main__':
print("PAIRWISE:")
for i, pairs in enumerate(AllPairs(parameters)):
# print("{:2d}: {}".format(i, pairs))
print(f"{i}:{pairs}")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
结合pytest的参数化功能
import pytest
from allpairspy import AllPairs
def function_to_be_tested(brand, operating_system, minute):
# do something
return True
class TestParameterized(object):
@pytest.mark.parametrize(["brand", "operating_system", "minute"], [
value_list for value_list in AllPairs([ #此处使用了语法:列表生成式
["Brand X", "Brand Y"],
["98", "NT", "2000", "XP"],
[10, 15, 30, 60]
])
])
def test(self, brand, operating_system, minute):
assert function_to_be_tested(brand, operating_system, minute)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
5.关于运行case
import pytest
@pytest.mark.start#标签可以打多个
@pytest.mark.set_up
def test_func1():
assert 1 == 1
@pytest.mark.finish
def test_func2():
assert 1 != 1
if __name__ == "__main__":
# pytest.main('-q run_some_case.py::test_func1')
pytest.main('关于运行部分case.py')
#使用terminal来执行case(命令行)
# 模糊匹配,可以返回多个结果
# pytest - k func run_some_case.py
# 指定方法运行,只能单个
# pytest run_some_case.py::test_func1
# 使用“标签”
# pytest -m start run_some_case.py
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23