pytest 第一性原理:fixture 与断言驱动重构
pytest 是谁
pytest 就是 Python 的测试运行框架:用普通的 assert 做断言(不用一堆 self.assertEqual),用 fixture 准备测试数据和环境,运行 pytest tests/ 一键跑全部。
一个最简测试
python
# tests/test_core.py
def test_split_identifier():
from core import process_pdf
text = "Lot No.: 9471A-5"
assert process_pdf.extract_identifier(text) == "9471A-5"
就一个函数、一个 assert。pytest 自动发现 test_ 开头的函数并执行。
为什么用 assert 就够了
pytest 给 assert 搭配了智能失败信息。断言失败时它直接告诉你两边各是什么:
E AssertionError: assert '9471A' == '9471A-5'
一眼看出差在哪(前面就是为了修这个从 9471A 到 9471A-5 的正则)。
fixture:把准备工作抽出来
当多个测试都要"先造一个临时 xlsx"时,fixture 省事且隔离:
python
@pytest.fixture
def temp_xlsx(tmp_path):
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws["A1"] = "母锭号"
path = tmp_path / "demo.xlsx"
wb.save(path)
return path
def test_read(temp_xlsx):
from openpyxl import load_workbook
wb = load_workbook(temp_xlsx)
assert wb.active["A1"].value == "母锭号"
tmp_path 是 pytest 内置 fixture------每个测试一个独立临时目录,测试之间不污染。
断言驱动重构
我们先写断言(期望行为),再让代码满足它。重构时,跑测试就知道有没有改坏:
python
python -m pytest tests/ -q
一把全过,才能自信说"没改坏"。这就是回归屏障。
一句话:pytest = 普通 assert + 可复用的 fixture + 一条命令跑全量,是重构期敢动手的底气。