1.pytest基本使用方法
1.1 断言
import pytest
# 功能1:计算a+b
def add(a, b):
return a + b
# 功能2:判断素数
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
# 测试功能1
def test_add_1():
assert add(3, 4) == 7
def test_add_2():
assert add(3, 4) != 8
def test_add_3():
assert add(3, 4) <= 9
def test_add_4():
assert add(3, 4) >= 5
# 测试包含
def test_in():
a = "hello"
b = "he"
assert b in a
def test_not_in():
a = "hello"
b = "hi"
assert b in a
# 测试功能2
def test_is_prime_1():
assert is_prime(13)
def test_is_prime_2():
assert is_prime(13) is True
def test_is_prime_3():
assert not is_prime(9)
def test_is_prime_4():
assert is_prime(9) is not True
def test_is_prime_5():
assert is_prime(9) is False
if __name__ == "__main__":
pytest.main()
1.2 Fixture
import pytest
# 功能
def multiply(a, b):
return a * b
# Fixture
# 在当前文件夹中,在所有的测试用例之前与之后执行
def setup_module(module):
print("setup module...")
def teardown_module(module):
print("teardown module...")
# 在每个测试函数之前与之后执行
def setup_function(function):
print("setup function...")
def teardown_function(function):
print("teardown function...")
# 在每个测试函数之前与之后执行,也可以作用与类方法
def setup():
print("setup...")
def teardown():
print("teardown...")
# 测试用例
def test_module_1():
print("test module 1")
assert multiply(3, 4) == 12
def test_module_2():
print("test module 2")
assert multiply(3, 'a') == 'aaa'
if __name__ == "__main__":
pytest.main(['-s', 'test_fixture_1.py'])
import pytest
# 功能
def multiply(a, b):
return a * b
class TestMultiply:
# Fixture
# 在当前类的开始与结束执行
@classmethod
def setup_class(cls):
print("setup module...")
@classmethod
def teardown_class(cls):
print("teardown module...")
# 在每个测试方法的开始与结束时执行
def setup_method(self, method):
print("setup method...")
def teardown_method(self, method):
print("teardown method...")
# 在每个测试方法的开始与结束时执行,也可以作用与测试函数
def setup(self):
print("setup...")
def teardown(self):
print("teardown...")
# 测试用例
def test_module_1(self):
print("test module 1")
assert multiply(3, 4) == 12
def test_module_2(self):
print("test module 2")
assert multiply(3, 'a') == 'aaa'
if __name__ == "__main__":
pytest.main(['-s', 'test_fixture_2.py'])
?1.3 参数化
import math
import pytest
# 参数化
@pytest.mark.parametrize(
"base, exponent, expected",
[(2, 2, 4),
(2, 3, 8),
(1, 9, 1),
(0, 9, 0)],
ids=["case1", "case2", "case3", "case4"]
)
def test_pow(base, exponent, expected):
assert math.pow(base, exponent) == expected
if __name__ == "__main__":
# -v增加测试用例冗长
pytest.main(['-v', 'test_parameterize.py'])
?1.4 运行测试
if __name__ == "__main__":
# -s用于关闭捕捉,从而输出打印信息
pytest.main(['-s', 'test_assert.py'])
if __name__ == "__main__":
# -v用于增加测试用例冗长
pytest.main(['-v', 'test_assert.py'])
if __name__ == "__main__":
# -k指定运行名称中包含某字符串的测试用例
pytest.main(['-k add', 'test_assert.py'])
if __name__ == "__main__":
# -q用于减少测试运行冗长,等价于--quiet
pytest.main(['-q', 'test_assert.py'])
if __name__ == "__main__":
# -x如果出现一条测试用例失败,则退出测试
pytest.main(['-x', 'test_assert.py'])
?运行测试目录:
?指定特定类或方法执行:
1.5 生成测试报告
生成JUnit XML文件:
(venv) D:\PythonProject>pytest ./pytest_demo ?--junit-xml=./report/log.xml
?生成在线测试报告:
# 要加这段
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
(venv) D:\PythonProject>pytest ./pytest_demo ?--pastebin=all
1.6 conftest.py
是pytest特有的本地测试配置文件,既可以用来设置项目级别的Fixture,也可以用来导入外部插件,还可以用来指定钩子函数。只作用于所在目录及其子目录。
test_project/conftest.py
import pytest
# 设置测试钩子
@pytest.fixture()
def test_url():
return "http://www.baidu.com"
?test_project/test_sub.py
def test_baidu(test_url):
print(test_url)
2.pytest扩展
2.1 pytest-html可以生成HTML格式的测试报告
(venv) D:\PythonProject>pip install pytest-html
(venv) D:\PythonProject>pytest ./pytest_demo --html=./report/result.html
?2.2 pytest-rerunfailures可以在测试用例失败时进行重试
(venv) D:\PythonProject>pip install pytest-rerunfailures (venv) D:\PythonProject>pytest -v test_baidu.py --reruns 3
2.3 pytest-parallel扩展,可以实现测试用例的并行运行(运行失败)
(venv) D:\PythonProject>pip install pytest-parallel (venv) D:\PythonProject>pytest -q test_parallel.py --tests-per-worker auto
3.构建web自动化测试项目
pytest对比unittest:
- pytest可以通过conftest.py文件配置全局浏览器的启动或关闭,整个项目的运行只需要启动或关闭一次浏览器即可;
- 测试用例运行失败截图;
- 测试用例运行失败重跑。
|