前言
1、首先要理解unittest中setup、teardown的作用,可以实现在执行用例前或结束后加入一些操作,但这种都是针对整个测试类全局生效的
2、如果有以下场景:用例 1 需要先登录,用例 2 不需要登录,当每个测试用例的执行环境和条件都不一样时,显然无法用 setup 和 teardown 来实现
3、fixture可以使环境管理更灵活,每个测试用例可以有自己的fixture
fixture的优势
1、命名方式灵活,不局限于 setup 和teardown 这几个命名
2、需要和conftest.py同时使用,可以实现数据共享,不需要 import 就能自动找到fixture
3、scope="module" 可以实现多个.py 跨文件共享前置
4、scope="session" 以实现多个.py 跨文件使用一个 session 来完成多个用例
fixture参数列表
- scope:可以理解成fixture的作用域,默认:function,还有class、module、package、session四个【常用】
- autouse:默认False,需要用例手动调用该fixture;如果是True,所有作用域内的测试用例都会自动调用该fixture
- name:默认装饰器的名称,同一模块的fixture相互调用建议写不同的name
测试用例如何调用fixture
- 将fixture名称作为测试用例函数的输入参数
- 测试用例加上装饰器:@pytest.mark.usefixtures(fixture_name)
注意:
添加了 @pytest.fixture ,如果fixture还想依赖其他fixture,需要用函数传参的方式,不能用 @pytest.mark.usefixtures() 的方式,否则不会生效
@pytest.fixture(scope="session")
def open():
print("===打开浏览器===")
@pytest.fixture #
@pytest.mark.usefixtures("open") #不生效
def login(open): # 方法级别前置操作setup
print(f"输入账号,密码先登录{open}")
前面都是setup的操作,那么现在就来讲下teardown怎么实现
fixture之yield实现teardown
用fixture实现teardown并不是一个独立的函数,而是用 yield 关键字来开启teardown操作
@pytest.fixture
def init_driver():
print('begin driver')
driver = webdriver.Chrome()
login_page = LoginPage(driver)
driver.get('http://120.78.128.25:8765/Index/login.html')
yield (driver,login_page)#相当于setup
#生成器,迭代器
driver.quit()
print('quit driver')
注意:
1、如果yield前面的代码,即setup部分已经抛出异常了,则不会执行yield后面的内容
2、如果测试用例抛出异常,yield后面的内容还是会正常执行
3、带有 yield 的函数在 Python 中被称之为 generator(生成器),生成器就是一边循环一边计算的机制,yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力
4、与return的区别:return后面的代码不会执行,yield后面的代码继续执行