软件测试Pytest的必会技巧(一)
pytestsetup和teardown
我们在使用selenium执行web自动化测试的时候,当我们需要执行多条测试用例时,执行一条用例就启动一次浏览器显然效率就太低了,我们需要一次启动浏览器,执行多条用例。pytest可以满足我们的需求吗?答案是pytest的setup和teardown完美匹配我们的需求,unittest有的它有,unittest没有的它也有!作用范围模块级(setupmoduleteardownmodule)开始于模块始末,全局的函数级(setupfunctionteardownfunction)只对函数用例生效(不在类中)类级(setupclassteardownclass)只在类中前后运行一次(在类中)方法级(setupmethodteardownmethod)开始于方法始末(在类中类里面的(setupteardown)运行在调用方法的前后函数级
setupfunctionteardownfunction
每个用例开始和结束调用一次testdemo。pycoding:utf8importpytest函数式defsetupfunction():print(setupfunction:每个用例开始前都会执行)defteardownfunction():print(teardownfunction:每个用例结束后都会执行)deftestone():print(正在执行testone)xthisasserthinxdeftesttwo():print(正在执行testtwo)xhelloasserthasattr(x,check)deftestthree():print(正在执行testthree)ahellobhelloworldassertainbifnamemain:pytest。main(〔s,testfixt。py〕)
运行结果:testsessionstartscollecting。。。collected3itemstestdemo。py::testonesetupfunction:每个用例开始前都会执行PASSED〔33〕正在执行testoneteardownfunction:每个用例结束后都会执行testdemo。py::testtwosetupfunction:每个用例开始前都会执行FAILED〔66〕正在执行testtwotestdemo。py:19(testtwo)deftesttwo():print(正在执行testtwo)xhelloasserthasattr(x,check)EAssertionError:assertFalseEwhereFalsehasattr(hello,check)testdemo。py:23:AssertionErrorteardownfunction:每个用例结束后都会执行testdemo。py::testthreesetupfunction:每个用例开始前都会执行PASSED〔100〕正在执行testthreeteardownfunction:每个用例结束后都会执行1failed,2passedin0。04s
从结果可以看出用例执行顺序:setupfunction》用例1》teardownfunction,setupfunction》用例2》teardownfunction,setupfunction》用例3》teardownfunction
注:加上s参数是为了显示用例的打印信息,便于查看。setupmoduleteardownmodule
setupmodule是所有用例开始前只执行一次,teardownmodule是所有用例结束后只执行一次importpytest函数式defsetupmodule():print(setupmodule:整个。py模块只执行一次)print(比如:所有用例开始前只打开一次浏览器)defteardownmodule():print(teardownmodule:整个。py模块只执行一次)print(比如:所有用例结束只最后关闭浏览器)defsetupfunction():print(setupfunction:每个用例开始前都会执行)defteardownfunction():print(teardownfunction:每个用例结束前都会执行)deftestone():print(正在执行testone)xthisasserthinxdeftesttwo():print(正在执行testtwo)xhelloasserthasattr(x,check)deftestthree():print(正在执行testthree)ahellobhelloworldassertainbifnamemain:pytest。main(〔s,testdemo。py〕)
从运行结果可以看到setupmodule和teardownmodule只执行了一次testsessionstartscollecting。。。collected3itemstestdemo。py::testonesetupmodule:整个。py模块只执行一次比如:所有用例开始前只打开一次浏览器setupfunction:每个用例开始前都会执行PASSED〔33〕正在执行testoneteardownfunction:每个用例结束前都会执行testdemo。py::testtwosetupfunction:每个用例开始前都会执行FAILED〔66〕正在执行testtwotestdemo。py:27(testtwo)deftesttwo():print(正在执行testtwo)xhelloasserthasattr(x,check)EAssertionError:assertFalseEwhereFalsehasattr(hello,check)testdemo。py:31:AssertionErrorteardownfunction:每个用例结束前都会执行testdemo。py::testthreesetupfunction:每个用例开始前都会执行PASSED〔100〕正在执行testthreeteardownfunction:每个用例结束前都会执行teardownmodule:整个。py模块只执行一次1failed,2passedin0。04s
注:setupfunctionteardownfunction和setupmoduleteardownmodule这四种方法是可以任意组合的,用一个和多个都可以类和方法
setupteardown和unittest里面的setupteardown是一样的功能,setupclass和teardownclass等价于unittest里面的setupClass和teardownClasscoding:utf8testfixtclass。pycoding:utf8importpytest类和方法classTestCase():defsetup(self):print(setup:每个用例开始前执行)defteardown(self):print(teardown:每个用例结束后执行)defsetupclass(self):print(setupclass:所有用例执行之前)defteardownclass(self):print(teardownclass:所有用例执行之前)defsetupmethod(self):print(setupmethod:每个用例开始前执行)defteardownmethod(self):print(teardownmethod:每个用例结束后执行)deftestone(self):print(正在执行testone)xthisasserthinxdeftesttwo(self):print(正在执行testtwo)xhelloasserthasattr(x,check)deftestthree(self):print(正在执行testthree)ahellobhelloworldassertainbifnamemain:pytest。main(〔s,testdemo。py〕)
运行结果testfixtclass。pysetupclass:所有用例执行之前setupmethod:每个用例开始前执行setup:每个用例开始前执行正在执行testone。teardown:每个用例结束后执行teardownmethod:每个用例结束后执行setupmethod:每个用例开始前执行setup:每个用例开始前执行正在执行testtwoFteardown:每个用例结束后执行teardownmethod:每个用例结束后执行setupmethod:每个用例开始前执行setup:每个用例开始前执行正在执行testthree。teardown:每个用例结束后执行teardownmethod:每个用例结束后执行teardownclass:所有用例执行之前
从结果看出,运行的优先级:setupclass》setupmethod》setup》用例》teardown》teardownmethod》teardownclass
备注:这里setupmethod和teardownmethod的功能和setupteardown功能是一样的,一般二者用其中一个即可。函数和类混合
如果一个。py的文件里面既有函数用例又有类和方法用例,运行顺序又是怎样的呢?coding:utf8importpytest类和方法defsetupmodule():print(setupmodule:整个。py模块只执行一次)print(比如:所有用例开始前只打开一次浏览器)defteardownmodule():print(teardownmodule:整个。py模块只执行一次)print(比如:所有用例结束只最后关闭浏览器)defsetupfunction():print(setupfunction:每个用例开始前都会执行)defteardownfunction():print(teardownfunction:每个用例结束前都会执行)deftestone():print(正在执行testone)xthisasserthinxdeftesttwo():print(正在执行testtwo)xhelloasserthasattr(x,check)classTestCase():defsetupclass(self):print(setupclass:所有用例执行之前)defteardownclass(self):print(teardownclass:所有用例执行之前)deftestthree(self):print(正在执行testthree)xthisasserthinxdeftestfour(self):print(正在执行testfour)xhelloasserthasattr(x,check)ifnamemain:pytest。main(〔s,testfixtclass。py〕)
运行结果:testfixtclass。pysetupmodule:整个。py模块只执行一次比如:所有用例开始前只打开一次浏览器setupfunction:每个用例开始前都会执行正在执行testone。teardownfunction:每个用例结束前都会执行setupfunction:每个用例开始前都会执行正在执行testtwoFteardownfunction:每个用例结束前都会执行setupclass:所有用例执行之前正在执行testthree。正在执行testfourFteardownclass:所有用例执行之前teardownmodule:整个。py模块只执行一次
从运行结果看出,setupmoduleteardownmodule的优先级是最大的,然后函数里面用到的setupfunctionteardownfunction与类里面的setupclassteardownclass互不干涉。