标记机制
我们可以利用标记,对测试用例进行分级,例如某些主流程的用例可以标记为L1,次要流程的用例标记为L2等。这样有一个好处,我们可以在不同的情况执行不同的测试用例,例如,在做冒烟测试的时候,只需要执行L1级别的用例就行了。
●一个测试函数(类、方法)可以有多个标记。
●一个标记也可以应用于多个函数(类、方法)。
●执行参数使用:pytest -m mark名。
●执行多个标记:pytest -m “L1 or L2”。
import pytest
class TestDemo:
@pytest.mark.L1
@pytest.mark.L2
def test_01(self):
assert 1==1 # 断言成功
@pytest.mark.L2
def test_02(self):
assert 1==2 # 断言失败
if __name__ == '__main__':
pytest.main(['-m L2','test.py'])
如上,给测试用例添加标记,并在main中以-m参数指定选择的标记,也可以使用or和and。
pytest.main(['-m L2 or L1','test.py']) # 执行标记为L1或者L2的
pytest.main(['-m L2 and L1','test.py']) #执行标记同时为L1和L2的
测试固件
在进行UI测试时,可能每个用例的操作前提都是需要登录系统,那么我们也不能在每次写用例的时候,都把登录写一遍,或者调用一遍,这样会造成代码冗余。有没有可能,在整个测试类或者所有测试用例执行之前,调用一次登录呢?
这样的工具,就是测试固件,测试固件有不同级别。
函数中的测试固件
●setup_module、teardown_module,在整个文件的开始和最后执行一次。
●setup_function和teardown_function,在每个函数开始前后执行。
import pytest
'''
在函数中使用
1.setup_module、teardown_module,在整个文件的开始和最后执行一次
2.setup_function和teardown_function,在每个函数开始前后执行
'''
def setup_module():
print('setup_module')
def teardown_module():
print('teardown_module')
def setup_function():
print('setup_function')
def teardown_function():
print('teardown_function')
def test_a():
print('aaaa')
assert 1 == 1
def test_b():
print('bbbb')
assert 1 == 2
if __name__ == '__main__':
pytest.main(["-s", "test.py"])
class中的测试固件
●setup_class、teardown_class,在整个class的开始和最后执行一次。
●setup_method和teardown_method,在每个方法开始前后执行。
class TestDemo():
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 test_a(self):
print('aaaa')
assert 1 == 1
def test_b(self):
print('bbbb')
assert 1 == 2
if __name__ == '__main__':
pytest.main(["-s", "test.py"])
setup和teardown
setup和teardown既可以应用在函数中,也可以应用在class中,作用对象是函数或方法,在每个测试用例执行前后执行一次。
我们通常使用setup来进行一些数据准备工作,使用teardown来进行数据清理工作。
import pytest
class TestDemo:
def setup(self):
print('setup')
def teardown(self):
print('teardown')
@pytest.mark.L1
@pytest.mark.L2
def test_01(self):
assert 1==1 # 断言成功
@pytest.mark.L2
def test_02(self):
assert 1==2 # 断言失败
if __name__ == '__main__':
pytest.main(['-s','test.py'])
断言
我们在进行手工测试时,测试用例有预期结果,那么在进行UI测试时,我们也需要来判定结果是否符合我们的预期。
在python中用断言来实现。断言assert用于检查指定的表达式的结果是否为True。
一个测试用例可以写多个断言,当有一个断言失败时,pytest就认为测试的结果为失败,该测试用例的执行会被终止。
如果一条测试用例不写断言,那么它的结果为通过。所以一定要写断言,否则测试执行就没有了意义。
import pytest
class TestDemo:
@pytest.mark.L1
@pytest.mark.L2
def test_01(self):
assert 1==1 # 断言成功
assert 1==3
@pytest.mark.L2
def test_02(self):
assert 1==2 # 断言失败
if __name__ == '__main__':
pytest.main(['-s','test.py'])
参数化
在进行UI测试时,我们需要给测试用例传测试数据,那么如何做呢?
pytest使用@pytest.mark.parametrize装饰器来实现数据驱动测试,也就是常说的参数化。
单个参数
import pytest
class TestDemo:
data = ["小红", "小明"]
@pytest.mark.parametrize("username",data)
def test_01(self,username):
print("我是{}".format(username))
if __name__ == '__main__':
pytest.main(['-s','test.py'])
运行结果如下,这里给一条测试用例传入两条数据,显示收集到了两条用例。
多个参数
列表嵌套字典
import pytest
class TestDemo:
data_1 = [
{"username": "admin1", "password": "123456"},
{"username": "admin2", "password": "12345678"},
]
@pytest.mark.parametrize("data", data_1)
def test_login(self,data):
print("账号:{},密码:{}".format(data["username"], data["password"]))
if __name__ == '__main__':
pytest.main(['-s','test.py'])
可以看到这里传入两条数据,显示收集了两条用例。
列表嵌套列表
import pytest
class TestDemo:
data_1 = [
["admin1", "123456"],
["admin2", "12345678"],
]
@pytest.mark.parametrize("username,password", data_1)
def test_login(self,username, password):
print("账号:{},密码:{}".format(username, password))
if __name__ == '__main__':
pytest.main(['-s','test.py'])
列表嵌套元组
import pytest
class TestDemo:
data_1 = [
("admin1", "123456"),
("admin2", "12345678"),
]
@pytest.mark.parametrize("username,password", data_1)
def test_login(self,username, password):
print("账号:{},密码:{}".format(username, password))
if __name__ == '__main__':
pytest.main(['-s','test.py'])
本文介绍了pytest测试框架的安装、运行、用例收集、标记、测试固件、断言、参数化等内容,实际这些内容只是pytest的冰山一角,还有
失败重跑,测试报告,全局设置等内容没有进行介绍,但学习了本文的内容,相信你已经可以上手进行自动化测试用例的编写了。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理