Python是非常方便的脚本语言,特别是用于测试非常方便。
Python3升级
linux下的Python默认一般比较老旧,使用时需要先升级
- 下载Python3.8安装包
wget https://www.python.org/ftp/python/3.8.9/Python-3.8.9.tgz - 解压缩
tar -xzvf Python-3.8.9.tgz - 配置
./configure --prefix=/usr/local/python38 --enable-shared - 编译安装
make && sudo make install - 配置python3.8的lib到ldconfig
vi /etc/ld.so.conf.d/python3.conf,添加如下内容 /usr/local/python38/lib 然后执行:ldconfig - 创建Python软链接
ln -s /usr/local/python38/bin/pip3 /usr/local/bin/pip3 ln -s /usr/local/python38/bin/python3 /usr/local/bin/python3 - 设置PATH
vi /etc/profile,添加以下内容 PATH=$PATH:/usr/local/bin/ - 重新加载环境变量
source /etc/profile
完成后,可通过:python3 --version 验证是否成功。
pytest
pytest是一个非常成熟的全功能的Python测试框架
- 入门简单,文档丰富
- 支持单元测试,功能测试
- 支持参数化,重复执行,部分执行,测试跳过
- 兼容其他测试框架(nose,unittest 等)
- 支持生成html报告
- 可集成CI环境(Jenkins 等)
- 第三方插件丰富,良好的自定义扩展性
安装
安装:pip3 install -U pytest
检查是否安装成功:pytest –version
有时安装后pytest无法直接使用,则:python3 -m pytest
一般还需要依赖一些其他包:
pip3 install pyyaml
pip3 install requests
pip3 install pytest-ordering
运行
pytest 不带任何参数,将查看当前目录(或其他一些预配置的目录)以及子目录下所有测试文件,并运行找到的测试代码。
- 测试文件名必须以
test_ 开头 - 测试类以
Test 开头,并且不能带有 init 方法 - 测试方法必须以
test_ 开头
运行:
# -s:打印print输出内容
# -r[s/E/f/x/a]: 打印对应项的额外信息 (f)ailed, (E)rror, (s)kipped, (x)failed,
# (X)passed, (p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll
# --tb=short: 遇到错误时,只打印错误行
# -v: 显示测试的详细参数信息
pytest -rs -s --tb=short
# pytest --collect-only # 只显示要测试的示例信息,不真正测试
参数方式运行(所有的参数放在列表中,每个参数就是列表中的一个元素):
if __name__ == "__main__":
pytest.main(['-v','-s'])
跳过
在测试中会经常需要跳过一些用例:
# 跳过测试函数(放在函数上)
@pytest.mark.skip(reason="test only")
@pytest.mark.skipif(reason="test only")
# 跳过整个模块(整个模块,包括不同目录下的所有文件)
pytest.skip("skipping session tests", allow_module_level=True)
# 跳过指定文件:添加conftest.py文件,把要忽略的文件放在collect_ignore列表中
collect_ignore = ["session/session_test.py"]
通过标识来方便跳过测试文件(conftest.py):
import glob
import os
SKIP_Session = False
collect_ignore = []
if SKIP_Session:
for file in glob.glob("./session/*_test.py"):
collect_ignore.append(file)
参数化调用
很多测试用例,需要使用不同的参数来调用(如不同的边界条),这时就需要使用parametrize :
# @pytest.mark.parametrize 参数调用
参数调用时,若使用全局变量,其值必须是预设定好的(通过setup_module修改无效,parametrize获取的值应在setup_module调取之前)
@pytest.mark.parametrize("fIndex, expectCode", [
(0, base.CodeSuccess),
(1, base.CodeFileInvalid),
])
def test_createSession(fIndex, expectCode):
pass
调用顺序
pytest-ordering可设定测试用例的执行顺序;
pip install pytest-ordering
# 设定执行顺序(@pytest.mark.run(order=1),修饰属性执行顺序 0、1、2......-2、-1,
# 多个文件顺序交叉时,会分段执行(分割为多个子测试去执行,setup也会多次调用))
# @pytest.mark.run(after = 'test_second')
# @pytest.mark.run(before = 'test_second')
setup 与 teardown
装载运行级别:
- 模块级(setup_module/teardown_module)开始于模块(文件)始末
- 函数级(setup_function/teardown_function)只对函数用例生效(不在类中)
- 类级(setup_class/teardown_class)只在类中前后运行一次(在类中)
- 方法级(setup_method/teardown_method)开始于方法始末(在类中)
- 类里面的(setup/teardown)运行在调用方法的前后
import pytest
def setup_module():
print("setup_module:整个.py模块只执行一次(进入py文件时,执行一次)")
def teardown_module():
print("teardown_module:整个.py模块只执行一次(退出py文件时,执行一次)")
def setup_function():
print("setup_function:每个函数测试用例开始前都会执行(本例中test_one、test_two执行前)")
def teardown_function():
print("teardown_function:每个函数测试用例结束后都会执行(本例中test_one、test_two执行后)")
def test_one():
print("正在执行测试模块----test_one")
def test_two():
print("正在执行测试模块----test_two")
class TestCase():
def setup_class(self):
print("setup_class:所有类中测试用例执行之前(进入类时,执行一次)")
def teardown_class(self):
print("teardown_class:所有类中测试用例执行之后(退出类时,执行一次)")
def setup(self):
print("setup:每个用例开始前都会执行(本例中test_three、test_four执行前)")
def teardown(self):
print("teardown:每个用例结束后都会执行(本例中test_three、test_four执行后)")
def test_three(self):
print("正在执行测试类----test_three")
def test_four(self):
print("正在执行测试类----test_four")
if __name__ == "__main__":
pytest.main(["-s", "test_module.py"])
|