写点什么

软件测试|Pytest 的必会技巧(一)

  • 2023-05-14
    北京
  • 本文字数:4149 字

    阅读完需:约 14 分钟

pytest setup 和 teardown

我们在使用 selenium 执行 web 自动化测试的时候,当我们需要执行多条测试用例时,执行一条用例就启动一次浏览器显然效率就太低了,我们需要一次启动浏览器,执行多条用例。pytest 可以满足我们的需求吗?答案是 pytest 的 setup 和 teardown 完美匹配我们的需求,unittest 有的它有,unittest 没有的它也有!

作用范围

  • 模块级(setup_module/teardown_module)开始于模块始末,全局的

  • 函数级(setup_function/teardown_function)只对函数用例生效(不在类中)

  • 类级(setup_class/teardown_class)只在类中前后运行一次(在类中)

  • 方法级(setup_method/teardown_method)开始于方法始末(在类中

  • 类里面的(setup/teardown)运行在调用方法的前后

函数级

setup_function/teardown_function


每个用例开始和结束调用一次


# test_demo.py
# coding:utf-8import pytest# 函数式
def setup_function(): print("setup_function:每个用例开始前都会执行")
def teardown_function(): print("teardown_function:每个用例结束后都会执行")
def test_one(): print("正在执行----test_one") x = "this" assert 'h' in x
def test_two(): print("正在执行----test_two") x = "hello" assert hasattr(x, 'check')
def test_three(): print("正在执行----test_three") a = "hello" b = "hello world" assert a in b
if __name__ == "__main__": pytest.main(["-s", "test_fixt.py"])
复制代码


运行结果:


============================= test session starts =============================collecting ... collected 3 items
test_demo.py::test_one setup_function:每个用例开始前都会执行PASSED [ 33%]正在执行----test_oneteardown_function:每个用例结束后都会执行
test_demo.py::test_two setup_function:每个用例开始前都会执行FAILED [ 66%]正在执行----test_two
test_demo.py:19 (test_two)def test_two(): print("正在执行----test_two") x = "hello"> assert hasattr(x, 'check')E AssertionError: assert FalseE + where False = hasattr('hello', 'check')
test_demo.py:23: AssertionError
teardown_function:每个用例结束后都会执行
test_demo.py::test_three setup_function:每个用例开始前都会执行PASSED [100%]正在执行----test_threeteardown_function:每个用例结束后都会执行

========================= 1 failed, 2 passed in 0.04s =========================
复制代码


从结果可以看出用例执行顺序:setup_function》用例 1》teardown_function, setup_function》用例 2》teardown_function, setup_function》用例 3》teardown_function


注:加上-s 参数是为了显示用例的打印信息,便于查看。

setup_module/teardown_module

setup_module 是所有用例开始前只执行一次,teardown_module 是所有用例结束后只执行一次


import pytest# 函数式def setup_module():    print("setup_module:整个.py模块只执行一次")    print("比如:所有用例开始前只打开一次浏览器")
def teardown_module(): print("teardown_module:整个.py模块只执行一次") print("比如:所有用例结束只最后关闭浏览器")
def setup_function(): print("setup_function:每个用例开始前都会执行")
def teardown_function(): print("teardown_function:每个用例结束前都会执行")
def test_one(): print("正在执行----test_one") x = "this" assert 'h' in x
def test_two(): print("正在执行----test_two") x = "hello" assert hasattr(x, 'check')
def test_three(): print("正在执行----test_three") a = "hello" b = "hello world" assert a in b
if __name__ == "__main__": pytest.main(["-s", "test_demo.py"])
复制代码


从运行结果可以看到 setup_module 和 teardown_module 只执行了一次


============================= test session starts =============================collecting ... collected 3 items
test_demo.py::test_one setup_module:整个.py模块只执行一次比如:所有用例开始前只打开一次浏览器setup_function:每个用例开始前都会执行PASSED [ 33%]正在执行----test_oneteardown_function:每个用例结束前都会执行
test_demo.py::test_two setup_function:每个用例开始前都会执行FAILED [ 66%]正在执行----test_two
test_demo.py:27 (test_two)def test_two(): print("正在执行----test_two") x = "hello"> assert hasattr(x, 'check')E AssertionError: assert FalseE + where False = hasattr('hello', 'check')
test_demo.py:31: AssertionError
teardown_function:每个用例结束前都会执行
test_demo.py::test_three setup_function:每个用例开始前都会执行PASSED [100%]正在执行----test_threeteardown_function:每个用例结束前都会执行teardown_module:整个.py模块只执行一次


========================= 1 failed, 2 passed in 0.04s =========================
复制代码


注:setup_function/teardown_function 和 setup_module/teardown_module 这四种方法是可以任意组合的,用一个和多个都可以

类和方法

setup/teardown 和 unittest 里面的 setup/teardown 是一样的功能,setup_class 和 teardown_class 等价于 unittest 里面的 setupClass 和 teardownClass



# coding:utf-8#test_fixtclass.py
# coding:utf-8import pytest# 类和方法class TestCase():
def setup(self): print("setup: 每个用例开始前执行")
def teardown(self): print("teardown: 每个用例结束后执行")
def setup_class(self): print("setup_class:所有用例执行之前")
def teardown_class(self): print("teardown_class:所有用例执行之前")
def setup_method(self): print("setup_method: 每个用例开始前执行")
def teardown_method(self): print("teardown_method: 每个用例结束后执行")
def test_one(self): print("正在执行----test_one") x = "this" assert 'h' in x
def test_two(self): print("正在执行----test_two") x = "hello" assert hasattr(x, 'check')
def test_three(self): print("正在执行----test_three") a = "hello" b = "hello world" assert a in b
if __name__ == "__main__": pytest.main(["-s", "test_demo.py"])
复制代码


运行结果


test_fixtclass.py setup_class:所有用例执行之前setup_method:  每个用例开始前执行setup: 每个用例开始前执行正在执行----test_one.teardown: 每个用例结束后执行teardown_method:  每个用例结束后执行setup_method:  每个用例开始前执行setup: 每个用例开始前执行正在执行----test_twoFteardown: 每个用例结束后执行teardown_method:  每个用例结束后执行setup_method:  每个用例开始前执行setup: 每个用例开始前执行正在执行----test_three.teardown: 每个用例结束后执行teardown_method:  每个用例结束后执行teardown_class:所有用例执行之前
复制代码


从结果看出,运行的优先级:setup_class》setup_method》setup 》用例》teardown》teardown_method》teardown_class 备注:这里 setup_method 和 teardown_method 的功能和 setup/teardown 功能是一样的,一般二者用其中一个即可。

函数和类混合

如果一个.py 的文件里面既有函数用例又有类和方法用例,运行顺序又是怎样的呢?


# coding:utf-8import pytest# 类和方法
def setup_module(): print("setup_module:整个.py模块只执行一次") print("比如:所有用例开始前只打开一次浏览器")
def teardown_module(): print("teardown_module:整个.py模块只执行一次") print("比如:所有用例结束只最后关闭浏览器")
def setup_function(): print("setup_function:每个用例开始前都会执行")
def teardown_function(): print("teardown_function:每个用例结束前都会执行")
def test_one(): print("正在执行----test_one") x = "this" assert 'h' in x
def test_two(): print("正在执行----test_two") x = "hello" assert hasattr(x, 'check')
class TestCase():
def setup_class(self): print("setup_class:所有用例执行之前")
def teardown_class(self): print("teardown_class:所有用例执行之前")
def test_three(self): print("正在执行----test_three") x = "this" assert 'h' in x
def test_four(self): print("正在执行----test_four") x = "hello" assert hasattr(x, 'check')
if __name__ == "__main__": pytest.main(["-s", "test_fixtclass.py"])
复制代码


运行结果:


test_fixtclass.py setup_module:整个.py模块只执行一次比如:所有用例开始前只打开一次浏览器setup_function:每个用例开始前都会执行正在执行----test_one.teardown_function:每个用例结束前都会执行setup_function:每个用例开始前都会执行正在执行----test_twoFteardown_function:每个用例结束前都会执行setup_class:所有用例执行之前正在执行----test_three.正在执行----test_fourFteardown_class:所有用例执行之前teardown_module:整个.py模块只执行一次
复制代码


从运行结果看出,setup_module/teardown_module 的优先级是最大的,然后函数里面用到的 setup_function/teardown_function 与类里面的 setup_class/teardown_class 互不干涉。


用户头像

社区:ceshiren.com 微信:ceshiren2021 2019-10-23 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料,实时更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬。

评论

发布
暂无评论
软件测试|Pytest的必会技巧(一)_霍格沃兹测试开发学社_InfoQ写作社区