# ERROR: tearDown (tests.test_foo.TestFoo) ...
Traceback (最近一次调用最后):
  File "...", 第 N 行, 在 tearDown 中
    self.conn.close()
AttributeError: 'NoneType' 对象没有属性 'close'

- **ID:** `python/unittest-teardown-exception-masks-test`
- **领域:** python
- **类别:** runtime_error
- **验证级别:** ai_generated
- **修复率:** 80%

## 根因

tearDown 引用了 setUp 未能赋值的属性（例如 setUp 抛出异常或被跳过），导致清理逻辑作用于未初始化的值。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| 3.11 | active | — | — |
| 3.12 | active | — | — |

## 解决方案

1. **** (94% 成功率)
   ```
   def tearDown(self):
    conn = getattr(self, 'conn', None)
    if conn is not None:
        conn.close()
    super().tearDown()
   ```
2. **** (96% 成功率)
   ```
   def setUp(self):
    self.conn = connect()
    self.addCleanup(self.conn.close)

# addCleanup runs only if the resource was created
   ```

## 无效尝试

- **** — Silences the error but leaks resources (open sockets, temp files) and hides genuine teardown bugs, causing cascading failures in later tests. (70% 失败率)
- **** — addCleanup still calls the same code path; if the attribute is None the same AttributeError is raised, now reported as a cleanup error. (80% 失败率)
