1、用例设计规则
(1)unittest测试类必须继承unittest.TestCase;
(2)unittest测试函数必须以“test_”开头,测试类也可以由‘Test’开头;
(3)unittest测试类必须有unittest.main()方法
(4)pytest测试函数必须以“test”开头,测试类命名必须以”Test”开头,测试文件的文件名必须以”test_”开头,或者以”_test”结尾
(5)pytest测试类里面不能使用”init”方法
2、参数化
(1)pytest常用参数方式
parametrize数据驱动
用到装饰器@pytest.mark.parametrize(args_name,args_value),args_name代表变量名,args_value代表需要测试的数据。
import pytest
class Test05:
@pytest.mark.parametrize("args_name", ['百里','婉儿','露露'])
def test_get_token(self,args_name):
print('测试参数'+args_name)
yaml驱动
1)创建yaml文件如下:
-
name: 获取token接口1
request:
method: get
data:
name: 百里
age: 18
url: https://www.baidu.com
validate: None
-
name: 获取token接口2
request:
method: get
data:
name: 婉儿
age: 17
url: https://www.baidu.com
validate: None
2)添加读取yaml的工具类yaml_util.py
import yaml
def read_yaml(yaml_path):
with open(yaml_path,encoding='utf‐8') as f:
value = yaml.load(f,Loader=yaml.FullLoader)
return value
3)用例读取数据
import pytest
from commons.yaml_util import read_yaml
class Test05:
@pytest.mark.parametrize("args", read_yaml("./testcase/test_05.yaml"))
def test_get_token(self,args):
print(args)
print(args['request']['date']['name'])
注:其它文档类型读取方法见python基础_python 字符串命令-CSDN博客 9.0
(2)unittest数据驱动
1)创建yaml文件如上文件
2)用例读取数据
import unittest
import ddt
@ddt.ddt
class TestLogout(unittest.TestCase):
@ddt.file_data(./testcase/test_05.yaml)
def test_logout(self,**case):
print(args)
print(args['request']['date']['name'])
3、自动生产测试报告
(1)pytest报告
1)通过pytest-html生成html格式报告
2)通过allure生成方案
if _name=='_main_':
pytest.main()
os.systew('allure generate ./temp -o ./report --clear')
./temp:临时的json报告路径
-o:输出output
./report:生成allure报告路径
--clear:清空原来的报告
在用例中使用下列装饰器,返回的报告可以更加简洁易懂,还可以仅执行特定装饰器用例
epic是feature父级,feature是story父级,是包含关系,效果跟书籍的目录或者项目结构相似
@allure.feature(‘’):敏捷里面的概念,定义史诗,相当于module级的标签
@allure.feature(‘功能名称’):功能点的描述,可以理解成模块,相当于class级的标签
@allure.story(’子功能名称‘):故事,可以理解为场景,相当于method级的标签
例如:
import allure
def test_without_any_annotations_that_wont_be_executed():
pass
@allure.story('epic_1')
def test_with_epic_1():
pass
@allure.story('story_1')
def test_with_story_1():
pass
@allure.story('story_2')
def test_with_story_2():
pass
@allure.feature('feature_2')
@allure.story('story_2')
def test_with_story_2_and_feature_2():
pass
@allure.epic('epic_2')
@allure.feature('feature_2')
@allure.story('story_2')
def test_with_epic_2_story_2_and_feature_2():
pass
没有使用标记的效果
使用epic、feature、story装饰器的效果
@allure.step()可以让allure报告中测试用例更加详细
@allure.step(‘步骤’):测试过程中的每个步骤,放在具体逻辑方法中
@allure.step(‘步骤’) 只能以装饰器的形式放在类或者方法上面
with allure.step(‘步骤’):可以放在测试用例方法里面
import pytest
import allure
@allure.step("步骤1:用户登陆")
def test_login():
pass
@allure.step("步骤2:用户数据检查")
def test_check():
test_login()
if __name__ == '__main__':
pytest.main(["-s", "test_allure_step.py"])
(2)unittest报告
通过HTMLTestRunner生成
from HTMLTestRunner import HTMLTestRunner #引入HTMLTestRunner
test_dir="./test/test_case" #定义测试用例目录
discover=unittest.defaultTestLoader.discover(test_dir,pattern="test*.py") #执行对应的文件
f=open("./result.html","wb") #新建报告文件,用wb二进制方式打开
runner=HTMLTestRunner(stream=f,title="自动化测试",description="测试用例执行情况") #实例化类
runner.run(discover)
f.close #关闭文件
4、跳过用例
(1)unittest跳过
强制跳过@unittest.skip(string)
(2)pytest跳过
A.强制跳过@pytest.mark.skip(string)
B.条件跳过@pytest.mark.skipif(条件,reason=string)满足条件就跳过
5、前后置
(1)unittest前置和后置
通过setUp、tearDown每个用例执行其前后执行;通过setUpClass、tearDownClass类里面所有用例执行前后执行
(2)pytest前置和后置
1)模块级别:setup_module/teardown_module,整个.py全部用例开始前执行/全部用例执行完后执行
2)函数级别:setup_function/teardown_function,只对函数级别生效
3)类级别:setup_class/teardown_function,只对类级别生效
4)方法级别:setup_method/teardown_method,只是类里面方法级别生效
5)方法级别:setup/teardown,这个与setup_method/teardown_method用法很类似,但是级别比method级别要低,也就是说在同一个方法中会先执行setup_method再执行setup,方法结束后先执行teardown再执行teardown_method
@pytest.fieture()自定义设置前置和后置:
格式@pytest.fixture(scope=”function”, params=None, autouse=False, ids=None, name=Noe)
scope:表示被@pytest.fixture标记的作用域,有四个级别,function(默认),class,module,session
params:参数列表
autouse:False为默认值,意思代表需要根据设置的条件(scope级别)来激活fixture,如果为Ture,则表示所有function级别的都被激活fixture
ids:每个字符串id的列表,感觉没啥实质性作用
name:fixture的名字
6、用例执行顺序
(1)unittest执行顺序
unittest通过ASCLL码的大小来执行的
(2)pytest执行顺序
pytest默认由上到下执行
通过装饰器@pytest.mark.run(order=num),num≥1
7、断言
(1)unittest断言
常用的断言方法
assertEqual(arg1,arg2,msg=None) | 验证arg1=arg2,不等则fail |
assertNotEqual(arg1,arg2,msg=None) | 验证arg1!=arg2,相等则fail |
assertTrue(expr,msg=None) | 验证expr为true,如果为false,则fail |
assertFalse(expr,msg=None) | 验证expr为false,如果为true,则fail |
assertIsNone(expr,msg=None) | 验证expr是None,不是则fail |
assertIsNotNone(expr,msg=None) | 验证expr不是None,是则fail |
assertIn(arg1,arg2,msg=None) | 验证arg1是arg2的子串,不是则fail |
assertNotIn(arg1,arg2,msg=None) | 验证arg1不是arg2的子串,是则fail |
所有的断言方法都有msg参数,如果指定msg参数的值,则将该信息作为失败的错误信息返回。
(2)pytest断言
assert a #判断a为真
assert not a #判断a不为真
assert a > b #判断a大于b
assert a < b #判断a小于b
assert a == b #判断a等于b
assert a != b #判断a不等于b
assert a in b #判断b包含a
assert a not in b #判断b不包含a
8、pytest其它
(1)常见插件
pytest -html #生成html格式报告
pytest -xdist #测试用例分布式执行,多cpu分发
pytest -ordering #改变用例执行顺序
pytest -rerunfailures #用例失败后重跑
allure -pytest #生成美观测试报告
将上述插件写入文件requirements.txt文件,再命令行输入pip install -r requirements.txt,等待安装成功。
(2)pytest.ini配置文件
该文件的作用是改变pytest默认行为,再执行用例前会优先读取该文件,文件一般放在项目的根目录下,且文件必须是ANSI码(通过notpad++修改)
[pytest]
addopts=-vs #其它参数,用空格隔开
testpaths=./testcase #目录
python_files=test*.py #文件
python_classes=
python_functions=
markers=
smoke:冒烟测试
AAA:ui测试
marker:指定需要执行的用例,在用例上添加装饰器@pytest.mark.AAA,需要执行对应用例是需要添加参数-m "smoke or AAA"(仅执行有装饰器smoke或AAA的用例)
(3)其它常见参数
if _name_='_main_':
pytest.main(['-vs',./testcase/test_case.py::Testcase::testcase,'--reruns=2','-x','--maxfail=3','-k=test','--html=./report/report.html'])
-v:显示详细信息
-s:显示print和执行的信息
./testcase/test_case.py::Testcase::testcase:执行目录/文件::类::方法,可以目录、目录/文件、目录/文件::类、目录/文件::类::方法
--reruns=2:执行失败了的用例,再执行2次
-x:只要用例失败就停止执行用例
--maxfail=3:出现3次失败就停止执行
-k=test:仅执行方法中包含test的
--html=./report/report.html:自动生成报告
-n:线程