【pytest】(十二)参数化测试用例中的setup和teardown要怎么写?

还是一篇关于pytest的fixture在实际使用场景的分享。

fixture我用来最多的就是写setup跟teardown了,那么现在有一个用例是测试一个列表接口,参数化了不同的状态值传参,来进行测试。

那么对于这个用例的setup跟teardown,我就要在setup里插入不同状态的测试数据,并且在测试完成后,在teardown里清除掉插入的数据。

一、setup

不过在插入数据的时候,我不想要一次性的把所有状态的数据都插入进去。比如1,2,3,4,5 有5个状态的参数,我想执行1的时候,插入状态
1的数据,测试完成后,删除刚才插入的这条数据,后面以此类推。

那么,这里还是要用到参数传递的一个效果了,这个在之前的文章里也讲过,有兴趣可以去看下,这里不再赘述。

@pytest.fixture(params=[1, 2, 3, 4, 5])
def init_allot_task_status(request):
    status = request.param
    db = DB()
    insert_allot_task_sql = """
    INSERT INTO purchase_allot (`id`, `allot_sn`... )
    """.format(10000086, status)
    db.exec_sql(insert_allot_task_sql)
    yield status #这里把参数给出去,供测试用例使用
    delete_sql = "DELETE from sm_purchase_allot WHERE id = {}".format(10000086)
    print("执行delete-sql:", delete_sql)
    db.exec_sql(de
<think> 我们正在讨论pytest框架中setupteardown无法使用的问题。根据引用内容,pytest有自己的一套前后置方法体系,包括不同级别(函数级、类级、模块级等)。用户遇到了无法使用的问题,我们需要分析可能的原因。 可能的原因包括: 1. 命名不符合pytest的约定:pytest要求setupteardown方法必须按照特定的命名规则,如函数级的应该命名为setup_functionteardown_function,类级的为setup_methodteardown_method等。如果命名不正确,pytest将无法识别。 2. 作用域问题:在类中,setupteardown方法需要放在测试类中,并且测试类必须命名以Test开头(如果默认配置如此),否则pytest可能不会收集该类。 3. 没有放置在正确的位置:如,函数级的setup_functionteardown_function应该定义在测试函数所在的模块中,但不在任何类内。 4. 使用了unittest风格的setupteardown:在pytest中,可以直接使用unittest风格的setupteardown,但需要确保测试类继承自unittest.TestCase。如果没有继承,则无法使用。 5. pytest版本问题:极少数情况下可能是pytest版本不兼容,但这种情况较少见。 6. 其他配置问题:如,pytest.ini配置文件可能禁用了某些特性,或者有插件干扰。 根据引用[1][2],pytest框架中前后置方法有多种: - 函数级:setup_function、teardown_function(作用于每个测试函数) - 类级:setup_class、teardown_class(使用@classmethod装饰器,整个类前后执行一次) - 方法级:setup_method、teardown_method(类中每个测试方法前后执行) - 模块级:setup_module、teardown_module(整个模块前后执行) 另外,pytest还提供了更灵活的fixture机制,通常推荐使用fixture来替代传统的setup/teardown。 因此,用户的问题可能是由于命名错误或放置位置不正确导致的。我们需要检查用户代码是否符合这些要求。 由于用户并未提供具体代码,我们只能给出常见原因的排查步骤: 1. 检查命名:确保使用的前置后置函数名称完全正确(如,函数级的必须叫setup_functionteardown_function,并且是模块级的函数;类中的方法级应该叫setup_methodteardown_method,或者使用unittest风格的setupteardown但必须继承unittest.TestCase)。 2. 检查测试类:如果是在类中,类名应该以Test开头(默认情况下,除非修改配置),且测试方法以test_开头。 3. 检查是否使用了fixture:如果用户使用了fixture,那么需要检查fixture的定义使用是否正确。因为fixture可以替代setup/teardown,而且功能更强大。 4. 运行命令:确保运行测试时使用的是pytest命令,而不是python直接运行模块(因为pytest需要收集测试用例)。 如果用户使用的是类,以下是一个正确的示: ```python class TestExample: def setup_method(self, method): # 在每个测试方法之前执行 print("setup method") def teardown_method(self, method): # 在每个测试方法之后执行 print("teardown method") def test_one(self): assert 1 == 1 def test_two(self): assert 2 == 2 ``` 对于函数级的: ```python def setup_function(function): print("setup function") def teardown_function(function): print("teardown function") def test_func(): pass ``` 如果用户按照正确的命名位置编setupteardown,但仍然无法执行,那么可能需要检查pytest的版本配置文件。 另外,引用[3]给出了函数级setupteardown的执行顺序,这也验证了命名的正确性。 因此,建议用户首先检查命名位置,然后确保测试用例文件、类函数都符合pytest的默认命名规则(一般测试文件以test_开头,测试函数以test_开头,测试类以Test开头)。 如果用户使用的是类,并且没有使用unittest.TestCase,那么应该使用setup_methodteardown_method,而不是setupteardown(除非在继承unittest.TestCase的情况下)。 总结:无法使用的最常见原因是命名错误(如,在类中使用setup而不是setup_method)或者测试用例未被pytest发现(如,测试类没有以Test开头或者测试方法没有以test_开头)。 </think> 在 pytest 框架中,`setup` `teardown` 失效通常由以下原因造成: ### ⚠️ 常见失效原因及解决方案 1. **命名不符合 pytest 规范** - ❌ 错误示:`setup()` / `teardown()`(缺少后缀) - ✅ 正确命名(根据作用域选择): ```python # 函数级 def setup_function(): pass # 每个测试函数前执行 def teardown_function(): pass # 每个测试函数后执行 # 类方法级 class TestExample: def setup_method(self): pass # 类中每个测试方法前执行 def teardown_method(self): pass # 类中每个测试方法后执行 # 类级(需搭配装饰器) @classmethod def setup_class(cls): pass # 整个测试类前执行(仅1次) @classmethod def teardown_class(cls): pass # 整个测试类后执行(仅1次) ``` > 📌 命名必须包含作用域后缀(`_function`/`_method`/`_class`),否则 pytest 无法识别[^1][^2][^3] 2. **作用域层级错误** - 函数级固件(`setup_function`)不能在测试类内部 - 类级固件(`setup_class`)必须使用 `@classmethod` 装饰器 3. **测试命名不规范** pytest 默认只收集以下命名的测试: - 测试文件:`test_*.py` 或 `*_test.py` - 测试函数:`test_*()` - 测试类:`Test*` ❌ 若命名不符(如类名 `DemoTest` 缺少大 `T`),固件不会触发 4. **与 fixture 冲突** 若同时存在固件 `@pytest.fixture`,fixture 优先级更高。解决: ```python @pytest.fixture(autouse=True) # 替代 setup/teardown def set_teardown(): print("\nsetup") yield print("\nteardown") ``` 5. **执行顺序错误** 当存在多级固件时,执行顺序为: ```mermaid graph LR A[setup_class] --> B[setup_method] --> C[测试方法] --> D[teardown_method] --> E[teardown_class] ``` ❌ 若 `teardown_method` 包含退出语句(如 `sys.exit()`),将阻断后续执行[^3] ### 🔍 诊断步骤 1. 检查所有固件命名是否包含作用域后缀 2. 确认测试文件/函数/类符合命名规范 3. 使用 `pytest -v` 查看测试收集列表 4. 在固件中添加 `print` 语句验证是否执行 5. 排查是否有同作用域的 fixture 覆盖固件 ### ✅ 推荐实践 ```python # 正确示(类方法级) class TestLogin: def setup_method(self): self.driver = webdriver.Chrome() # 启动浏览器 def test_valid_login(self): self.driver.get("https://example.com/login") # 执行登录测试... def teardown_method(self): self.driver.quit() # 关闭浏览器(每个用后执行) ``` > ⚡ 提示:现代 pytest 更推荐使用 [`fixture`](https://docs.pytest.org/en/stable/fixture.html) 替代传统固件,支持参数化、依赖注入等高级特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值