当前位置: 首页 > 后端技术 > Python

02-07Python库-pytest

时间:2023-03-26 16:43:29 Python

pytest成熟的全功能Python测试框架,简单灵活,易于使用。支持参数化测试用例的skip、xfail、自动失败重试等处理。可以支持简单的单元测试和复杂的功能测试,也可以用于selenium/appium等自动化测试,接口自动化测试(pytest+requests)有很多第三方插件,可以自定义扩展:pytest-allure、pytest-xdist(多CPU开发)等支持Jenkins集成Pytest用户手册pytest库安装:pipinstallpytesttest用例识别和运行命名文件要求:test_*.py*_test.py要求命名用例:Test类中包含的所有test_方法(测试类不能有_init_方法)alltest_notintheclass*pytest方法可以执行unittest框架的一些用例和方法。pycharm使用pytest框架时需要指定。具体操作如图:命令行操作方式:#直接执行当前路径下标识的测试用例pytest#执行指定文件pytesttest_material_master.py#执行pytest-v时打印日志,恢复运行方式用Python解释器:此时的运行方式是:importpytestif__name__=='__main__':pytest.main(["test_material_master.py"])#运行整个文件的用例pytest.main(["test_material_master.py::TestMaterialMaster::test_mat_search_by_matCode"])#运行文件中指定项的用例参数化使用方法:#作为装饰器@pytest.mark.parametrize(argnames,argvalues)#argnames:要参数化的变量;type:可以是str(逗号分隔)、list、tuple#argvalues:参数化值;type:list,[tuple]实际应用:@pytest.mark。参数化(“a,b,期望”,get_data(yaml_path,"add"),ids=["Integer","Decimal","LargeInteger"])deftest_add(self,a,b,expect,setup_fixture):"""测试正加例"""result=setup_fixture.add_func(a,b)assertabs(result-expect)<0.01注:参数组合(笛卡尔积):适用于预期结果只有一个的情况importpytest@pytest.mark.parametrize("a",[1,2,3])@pytest.mark.parametrize("b",[4,5,6])deftest_add(a,b):print("参数组合a={},b={}".format(a,b))执行结果:PASSED[11%]参数组合a=1,b=4PASSED[22%]参数组合a=2,b=4PASSED[33%]参数组合a=3,b=4PASSED[44%]参数组合a=1,b=5PASSED[55%]参数组合a=2,b=5PASSED[66%]参数组合a=3,b=5PASSED[77%]参数组合a=1,b=6通过[88%]参数组合a=2,b=6PASSED[100%]参数组合a=3,b=6skip使用场景:在编写测试用例时,发现某个用例本身存在bug,且暂时无法修复。先跳过importpytest@pytest.mark.skip("有bug,先跳过")@pytest.mark.parametrize("a",[1,2,3])@pytest.mark.parametrize("b",[4,5,6])deftest_add(a,b):print("参数组合a={},b={}".format(a,b))mark使用场景:分类用例,labelimportpytest@pytest.mark.test1deftest_01():print("Markassmoketestcase")@pytest.mark.test2deftest_02():print("Markasregressiontestcase")#只执行被标记的test1用例,命令行:#pytest-stest.py-mtest1#反向选择pytest-stest.py-m"nottest1"preandpostusecaserunlevelmodulelevel:startandmodulebeginningandend,globallyvalid;setup_module/teardown_module函数级别:仅对函数用例有效(类中未使用);setup_function/teardown_function类级别:在类前后只运行一次(在类中使用);setup_class/teardown_classmethodlevel:方法的开始和开始和结束(在setup_method/teardown_method类中使用的类中,在调用方法之前和之后运行;setup/teardown是最常用的**fixture:custompre/post@pytest.fixture()优点:命名灵活,不局限于Setup/teardown可以通过conftest.py配置实现数据共享,无需导入即可自动识别scope="module"可以实现多个.py跨文件共享前端,每个.py文件调用scope="session"可以实现多个.py跨文件使用一个session完成多个用例importpytest@pytest。fixture(scope="function")#Deflogin_fixture()通过配置装饰器deflogin_fixture():"""Pre-login"""print("Advancedlogin")deftest_01(login_fixture):#login_fixture作为参数传递print("Testcase01")deftest_02():print("Testcase02")执行结果:test.py::test_01advanceloginPASSED[50%]testcase01test.py::test_02PASSED[100%]testcase02fixture参数scope:作用范围function:每次测试都运行,默认是作用域classoffunction:每个类的所有测试只运行一次module:每个模块的所有测试只运行一次session:每个session都运行onlyonceautouse:caution默认为False,为True时,每个测试用例都会自动调用fixture,不需要传入fixture函数名。可以使用参数对夹具进行参数化。在这种情况下,它们会被调用多次,每次执行一组相关的测试,即依赖于这个fixture的测试,测试函数通常不需要知道它们的rerunimportpytest@pytest.fixture(params=["parameter1","parameter2"])defmyfixture(request):print("Executethepre-functionintestPytest,%s"%request.param)returnparameterinfixtureimportpytest@pytest.fixture(params=["参数1","参数2"])defmyfixture(request):returnrequest.paramdeftest_print_param(myfixture):print("executetest_two")print(myfixture)assert1==1#输出PASSED[50%]executetest_twoparameter1PASSED[100%]executetest_twoparameter2conftest.py应用场景:各接口需要共享的token各接口需要共享的测试用例数据各接口需要共享的配置信息文件名conftest.py文件和运行的用例要在同一个pakage下,还有一个__init__.py文件不需要通过import导入。pytest用例会自动识别同目录下的所有测试文件在运行前都会执行conftest.py文件#conftest.pyfileimportpytest@pytest.fixture()deflogin():print("pre-login")post-operation-yield@pytest.fixture(scope="function")defdemo_fix():print("用例测试前准备操作")yieldprint("测试用例后操作")deftest_1(demo_fix):print("开始执行测试用例1")deftest_2():print("开始执行测试用例2")deftest_3(demo_fix):print("开始执行测试用例3")如果代码中测试用例异常或断言失败,不会影响固件中yield后代码的执行;但是如果fixture中的yield是before代码就相当于setup部分的代码。如果发生错误或断言失败,则不会执行yield之后的代码。当然,测试用例中的代码是不会执行final函数的——addfinalizer相当于try...except在finally中即使设置有问题,addfinalizer仍将执行拆解操作@pytest.fixture(scope="session")deflogin_xadmin_fix(request):s=requests.session()login_xadmin(s)defclose_s():s.close()#closesusecasecomplete最后清理后request.addfinalizer(close_s)returns公共参数说明-v:可以输出用例执行的详细信息;比如用例所在的文件和用例的名称-s:输入用例的调试信息;如print-x的打印信息:遇到失败的用例立即停止-maxfail:当用例失败的次数达到一定数量时停止运行;pytest-maxfail=num-m:运行包含@pytest.mark.markname的测试用例-k:执行匹配的测试用例测试;如pytest-k"raisesandnotdelete"运行所有包含raises但不delete的测试pytest实用插件介绍pytest-rerunfailures:测试用例失败后自动重新运行安装方法:pipinstallpytest-rerunfailures使用方法:pytesttest_x.py--reruns=n#失败后重新运行的次数也可以在脚本中指定,定义重新运行的次数。这时候运行的时候就不需要加上--reruns参数@pytest.mark.flaky(reruns=6,reruns_delay=2)deftest_example(self):print(3)assertrandom.choice([True,false])pytest-assume:多检查pytest中的python断言,也可以写多个Assertion,但是一个失败,后面的断言将不再执行和pytest-assume,即使前面的断言失败,后面的断言也会继续执行安装方式:pipinstallpytest-assume使用方式:deftest_simple_assume(x,y):pytest.assume(x==y)pytest.assume(True)pytest.assume(False)pytest-xdist:分布式并发执行pytest-xdist允许自动化测试用例以分布式方式执行,从而节省自动化测试时间。分布式执行用例设计原则:用例是独立的,用例之间没有依赖关系,用例可以完全独立运行【独立运行】用例的执行没有顺序,随机顺序可以正常执行【随机执行】每个用例可以重复运行,运行结果不会影响其他用例【不影响其他用例】安装方式:pipinstallpytest-xdist使用方式:多CPU并行执行用例,添加即可直接-n参数,后面的num参数为并行数,例如num设置为3pytest-n3pytest-ordering:控制用例的执行顺序安装方式:pipinstallpytest-ordering使用方式:importpytest@pytest.mark.run(order=2)deftest_foo():assertTrue@pytest.mark.run(order=1)deftest_bar():assertTruePS:尽量不要让测试用例有顺序,试试不要让测试用例有依赖性!钩子(hook)功能定制和扩展插件Pytest在收集完所有测试用例后调用钩子方法。我们可以自定义函数实现:自定义测试用例的执行顺序,解决编码问题(中文测试用例名称)自动添加标签建议将hook函数的代码写在conftest.py文件中#conftest.pyfromtypingimportListdefpytest_collection_modifyitems(session:"Session",config:"Config",items:List["Item"])->None:foriteminitems:item.name=item.name.encode("utf-8")项目。decode("unicode-escape")item._nodeid=item.nodeid.encode("utf-8").decode("unicode-esc猿”)