如何在pytest BDD特定场景测试结束时通过fixture执行指定函数
问题描述
背景
需要为某个特定测试场景,在场景运行结束后执行特定方法。
我的尝试
场景代码
Scenario: Test Fixture Given I am a mechanic When I start a car Then I should get to know the primitive issues
步骤定义代码
@pytest.mark.usefixtures("stop_car") @scenario('../FeatureFiles/Test.feature', 'Test Fixture') def test_mechanic(): logging.info('Test Mechanic') @given("I am a mechanic") def given_mechanic(): print('given_mechanic') @when("I start a car") def when_mechanic(): print('when_mechanic') @then("I should get to know the primitive issues") def then_mechanic(): print('then_mechanic') assert 1 < 0, 'Failed validation' @pytest.fixture def stop_car(): print('stop car')
遇到的问题
当前stop_car()函数在场景执行前就被触发,需要让它在场景结束后执行,且无论Given、When或Then步骤中出现断言失败,该方法都必须执行。
解决方案
要实现测试结束后执行指定方法(无论成功失败),利用pytest fixture的销毁机制即可,有两种常用实现方式:
方式1:使用yield分割前后置逻辑
修改stop_car fixture,将后置执行代码放在yield之后。yield前的代码会在测试前运行(无需前置操作可留空),yield后的代码会在测试结束后自动执行,不受测试结果影响:
@pytest.fixture def stop_car(): # 可选:测试前执行的操作 yield # 标记前置操作结束,后置操作开始 # 测试结束后必须执行的代码 print('stop car')
方式2:通过request.addfinalizer添加终结器
如果需要更灵活的后置逻辑管理,可以借助fixture的request对象添加终结器,确保代码在测试结束后执行:
@pytest.fixture def stop_car(request): def teardown(): print('stop car') # 注册终结器,测试完成后自动调用 request.addfinalizer(teardown)
执行效果验证
修改后测试的执行顺序为:
- 执行
given_mechanic→ 打印given_mechanic - 执行
when_mechanic→ 打印when_mechanic - 执行
then_mechanic→ 打印then_mechanic,触发断言失败 - 执行
stop_car的后置逻辑 → 打印stop car
无论步骤中是否出现断言失败,stop_car的指定方法都会被执行。
内容的提问来源于stack exchange,提问作者KBNanda
相关产品推荐
相关产品推荐

