# test_create_user 的 teardown 出错
  文件 "..."，行 ...，在 db_session 中
    session.close()
RuntimeError: generator didn't stop after throw()

- **ID:** `python/pytest-teardown-error-generator`
- **领域:** python
- **类别:** runtime_error
- **验证级别:** ai_generated
- **修复率:** 80%

## 根因

基于 yield 的 fixture 在测试注入异常后再次 yield 或抛出异常。通常由在 `finally` 内 yield 的 `try/finally`，或捕获异常后再次 yield 的生成器 fixture 引起。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| 3.x | active | — | — |

## 解决方案

1. **** (95% 成功率)
   ```
   import pytest

@pytest.fixture
def db_session():
    session = SessionLocal()
    try:
        yield session
    finally:
        session.close()  # no yield here
   ```
2. **** (90% 成功率)
   ```
   import contextlib

@contextlib.contextmanager
def db_session():
    s = SessionLocal()
    try:
        yield s
    finally:
        s.close()

# then in fixture
@pytest.fixture
def db():
    with db_session() as s:
        yield s
   ```

## 无效尝试

- **** — pytest requires the generator to stop after the exception is thrown; a second yield triggers the same error. (85% 失败率)
- **** — Loses teardown entirely; DB session/resources are never closed, causing connection leaks. (70% 失败率)
