pytest---测试框架初探
一、命令行终端执行
1、测试用例的识别
1)、测试文件
test_*.py
*_test.py
2)、用例识别
Test*类包含的所有test_*的方法(测试类不能包含构造方法__init__)
不在类中的所有test_*方法
3)、pytest可以执行unittest框架写的用例和方法
2、常用命令
pytest -v(最高级别信息--verbose),打印详细运行日志信息
pytest 文件名.py 执行单独一个pytest模块
pytest 文件名.py::类名 执行某个模块里面的某个类
pytest 文件名.py::类名::方法名 运行某个模块里面的某个类里面的某个方法
pytest -v -k "类名 and not 方法名" 跳过运行某个用例
pytest -m 标记名 @pytest.mark.标记名 运行有这个标记的测试用例
pytest -x 文件名 一旦运行到报错就停止运行
pytest --maxfail=num 当运行错误达到num的时候就停止运行
3、失败用例重复运行
pip install pytest-rerunfailures
pytest -v --rerun 重新运行次数
4、用例中断言失败后继续执行
同一个测试方法中有多个断言的,前面断言失败后,继续执行后面的断言:
pip install pytest-assume
pytest.assume(1==1)
5、类似unittest的setup、teardown
import pytest
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_01():
assert 1==1
print('类外面的方法01')
def test_02():
assert 2==2
print('类外面的方法02')
class TestCase():
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_03(self):
assert 1 == 1
print('类里面的用例03')
def test_04(self):
assert 2 == 2
print('类里面的用例04')
if __name__ == '__main__':
pytest.main('-v')
运行结果
test_pytest1.py::test_01 setup_module方法
setup_function方法
类外面的方法01
PASSEDteardown_function方法
test_pytest1.py::test_02 setup_function方法
类外面的方法02
PASSEDteardown_function方法
test_pytest1.py::TestCase::test_03 setup_class方法
setup_method方法
setup方法
类里面的用例03
PASSEDteardown方法
teardown_method方法
test_pytest1.py::TestCase::test_04 setup_method方法
setup方法
类里面的用例04
PASSEDteardown方法
teardown_method方法
teardown_class方法
teardown_module方法
6、fixture使用
import pytest
@pytest.fixture()
def login():
print('这是登录方法')
def test01(login):
print('测试用例01')
assert 1 == 1
if __name__ == '__main__':
pytest.main()
执行结果如下:
7、conftest.py配置
可以将公共的方法放在这个文件里面,方便用例调用,如:全局配置、前期工作
conftest文件名不能变
与运行的用例要在同一个package下,且要有__init__.py文件
不需要导入conftest.py,pytest用例会首先在当前文件中查找,找不到再导conftest.py中查找
8、yield执行后续清理工作
import pytest @pytest.fixture(scope='module') def open(): print('打开浏览器') yield print('关闭浏览器') def test01(open): print('执行测试用例01') def test02(open): print('执行测试用例02') if __name__ == '__main__': pytest.main()
执行结果:
9、autouse=True自动执行前置条件
import pytest @pytest.fixture(autouse=True) def open(): print('打开浏览器') yield print('关闭浏览器') def test01(): print('执行测试用例01') def test02(): print('执行测试用例02') if __name__ == '__main__': pytest.main('-v')
执行结果
10、pytest参数化
@pytest.mark.parametrize(argnames, argvalues)
argnames: 要参数化的变量,string (逗号分割),list, tuple
argvalues:参数化的值,list, list[tuple]
示例代码:
import pytest #使用string @pytest.mark.parametrize("a,b",[(1,2),(2,3),(1,1)]) def test01(a,b): print(a,b) #使用tuple @pytest.mark.parametrize(("a","b"),[(1,2),(2,3),(1,1)]) def test02(a,b): print(a,b) #使用list @pytest.mark.parametrize(["a","b"],[(1,2),(2,3),(1,1)]) def test03(a,b): print(a,b) if __name__ == '__main__': pytest.main()
当该装饰器修饰测试类的时候,类下面所有的测试方法可以共享该参数化数据
@pytest.mark.parametrize(["name", "pwd"], [("name1", "123"), ("name2", "123")]) class TestClass(): def test_01(self,name,pwd): print("name:",name) print(("pwd:",pwd)) def test_02(self,name,pwd): print("name:",name) print(("pwd:",pwd))