-
Pytest
1)结合 Requests 实现接口测试
2)结合 Selenium / Appium 实现Web / APP自动化功能测试
3)结合Allure集成到Jenkins中实现持续集成
选择pytest的原因:
①报告(Allure);②多线程(distributed testing plugin);③控制顺序(pytest-ordering插件);④兼容unittest;⑤定制化插件开发。 -
Pytest 环境安装
方式一:命令 pip install -U pytest
方式二:在Pycharm的 Settings-Project Interpreter 中直接安装 -
Pytest 格式要求
1)文件:test_开头 或者 _test 结尾
2)类:Test 开头
3)方法/函数:test_开头
4)注意:测试类中不可以添加__init__构造函数- 函数(function):在类外部 / 方法(method):在类内部。
-
Pytest 测试框架结构
setup_module/teardown_module
全局模块级
setup_class/teardown_class
类级,只在类中前后运行一次(常用)
setup_function/teardown_function
函数级,在类外
setup_method/teardown_methond
方法级,类中的每个方法执行前后(用法同下)
setup/teardown
在类中,运行在调用方法的前后(重点) -
运行结果分析
常见结果:fail / error / pass
特殊结果:warning / deselected -
运行测试用例
方式一:使用pytest解释器,打开terminal 或 cmd,cd到项目路径
1)执行包下所有用例:pytest
2)执行单独一个pytest模块:pytest 文件名.py
3)执行某个模块中某个类:pytest 文件名.py::类名
4)执行某个模块中某个类里面的方法:pytest 文件名.py::类名::方法名
方式二:使用python解释器,执行pytest.main函数
①
#入口
if __name__ == '__main__':
#1、运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py)
pytest.main()
#2、运行某个模块中的某一条用例
pytest.main(['test_mark.py::test_case2', '-vs'])
#3、运行某个标签
pytest.main(['test_search.py', '-vs', '-m', 'str'])
运行方式
python test_*.py
#入口函数所在的文件
②
使用 python -m pytest test_*.py
调用pytest(jenkins持续集成用到)
-
常用命令行参数
–help
-v 打印详细日志
-s 打印输出日志(一般-vs)
-x 用例一旦失败(fail/error),立刻停止执行
--maxfail=num
用例失败数达到,则不再继续执行
-k “xx” 执行包含某个关键字的测试用例
--collect-only
(测试平台,pytest 自动导入功能 )
--lf(--last-failed)
只重新运行故障
--ff(--failed-first)
先运行故障然后再运行其余的用例 -
使用Mark标记测试用例
场景:可以把一个web项目划分成多个部分,根据标签名指定用例去执行。
语法:在测试用例方法上加 @pytest.mark.标签名(英文)
举例:加 -m 参数执行
pytest -s test_mark_zi_09.py -m=webtest
pytest -s test_mark_zi_09.py -m apptest
pytest -s test_mark_zi_09.py -m "not ios"
- 不提示warning:创建pytest.ini文件,将所有标签名列举出来
[pytest]
markers = str
min
ios
- Mark:跳过(skip) 预期失败(xFail)
skip用法1:添加装饰器 @pytest.mark.skip
* @pytest.mark.skipif
skip用法2:在代码中跳过 pytest.skip(reason)
@pytest.mark.skip(reason="跳过本条")
def test_mark_func():
print("test mark function")
print(sys.platform)
@pytest.mark.skipif(sys.platform == "darwin", reason="does not run on mac")
def test_case1():
assert True
@pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
def test_case2():
assert True
@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
def test_case3():
assert True
def login():
return False
def test_func():
print("111")
if not login():
pytest.skip("unsupported function")#条件符合,执行跳过,后面的代码不再执行
print("end")
xfaile用法1:@pytest.mark.xfail
#提示用例失败的作用,用法类似于skip
xfaile用法2:在代码中跳过 pytest.xfail(reason)
- Mark参数化–将模型中的定量信息变量化
1、单参数
search_list = ['appium', 'selenium', 'pytest']
@pytest.mark.parametrize('name', search_list)
def test_search(name):
assert name in search_list
2、多参数
3、用例重命名(ids)
#1、参数化的名字,要与方法中传入的参数名,一一对应
#2、如果传递多个参数,要放在列表中,列表中嵌套列表/元组
#3、ids 的个数 == 传递的数据组数
@pytest.mark.parametrize("test_input, expected",[
("3+5", 8), ("2+5", 7), ("7+5", 12)
], ids=['add_3+5=8', 'add_2+5=7', 'add_3+5=12'])
def test_mark_more(test_input, expected):
assert eval(test_input) == expected
4、笛卡尔积(全量:全组合)
- 常用的异常处理方法
1、try…except
try:
a = int(input("输入被除数:"))
b = int(input("输入除数:"))
c = a / b
print("您输入的两数相除的结果是:", c)
except (ValueError, ArithmeticError):
print("程序发生了 数字格式异常、算数异常 之一")
except :
print("未知异常")
print("程序继续运行")
2、pytest.raises()
def test_raise():
with pytest.raises(ValueError, ZeroDivisionError):#异常为当中的一个,则抛出
raise ZeroDivisionError("除数为0")
def test_raise1():
with pytest.raises(ValueError) as exc_info:
raise ValueError("value must be 42")
assert exc_info.type is ValueError
assert exc_info.value.args[0] == "value must be 42"