test(harness): 黄金测试加非空护栏、补类型注解、端到端对照旧逻辑

回应 Codex 审查三项测试质量问题:
- C1: 每个 byte-identical 断言前加非空护栏(sum(len)>0 / len==samples>0),
  防空==空误通过。
- I1: TestBatchingByteIdentical._assert 补齐完整类型注解。
- I2: 端到端 checkpoint 用例增加 _reference_build_batches 对照,断言真实池划分
  →batching 与旧逐题逻辑逐字节一致(不只是 rebuilt==batches 自往返)。
This commit is contained in:
2026-07-15 08:28:12 -04:00
parent 6c6fb576ee
commit 19911e18e0
+21 -1
View File
@@ -168,9 +168,19 @@ class TestPureSingleAreSizeOneUnits:
class TestBatchingByteIdentical: class TestBatchingByteIdentical:
"""纯 single build_batches 与旧逐题算法逐字节一致。""" """纯 single build_batches 与旧逐题算法逐字节一致。"""
def _assert(self, items, correctness, batch_size, min_cls, seed, ratio) -> None: def _assert(
self,
items: list[GeneratedQuestion],
correctness: dict[str, bool],
batch_size: int,
min_cls: int,
seed: int,
ratio: float,
) -> None:
got, _ = build_batches(items, correctness, batch_size, min_cls, seed, ratio) got, _ = build_batches(items, correctness, batch_size, min_cls, seed, ratio)
ref = _reference_build_batches(items, correctness, batch_size, min_cls, seed, ratio) ref = _reference_build_batches(items, correctness, batch_size, min_cls, seed, ratio)
# 非空护栏:确保对照是实质性非空比较(防空==空误通过)
assert sum(len(b) for b in ref) > 0
assert _ids(got) == _ids(ref) assert _ids(got) == _ids(ref)
def test_pure_errors(self) -> None: def test_pure_errors(self) -> None:
@@ -249,6 +259,14 @@ class TestEndToEndByteIdentical:
) )
batches, _ = build_batches(p.diagnosis, p.correctness, 6, 2, seed=3, correct_ratio=0.5) batches, _ = build_batches(p.diagnosis, p.correctness, 6, 2, seed=3, correct_ratio=0.5)
# 端到端对照旧逻辑:真实池划分 → batching 与引入 QuestionUnit 前逐字节一致
reference = _reference_build_batches(
p.diagnosis, p.correctness, 6, 2, seed=3, correct_ratio=0.5
)
# 非空护栏:确保对照是实质性非空比较(防空==空误通过)
assert sum(len(b) for b in reference) > 0
assert _ids(batches) == _ids(reference)
# checkpoint 折叠为 unit_id(纯 single 即 question_id)后恢复 # checkpoint 折叠为 unit_id(纯 single 即 question_id)后恢复
epoch_batches = [_batch_unit_ids(b) for b in batches] epoch_batches = [_batch_unit_ids(b) for b in batches]
assert epoch_batches == _ids(batches) # 纯非 ARunit_id 序列 == question_id 序列 assert epoch_batches == _ids(batches) # 纯非 ARunit_id 序列 == question_id 序列
@@ -274,6 +292,7 @@ class TestMomentumPureNonARByteIdentical:
candidates = [q for q in pool if q.task_type in allowed] candidates = [q for q in pool if q.task_type in allowed]
ref = random.Random(epoch).sample(candidates, samples) ref = random.Random(epoch).sample(candidates, samples)
assert len(ref) == samples > 0 # 非空护栏:实质性抽样
assert [q.question_id for q in got] == [q.question_id for q in ref] assert [q.question_id for q in got] == [q.question_id for q in ref]
def test_ar_pairs_of_other_type_do_not_shift(self) -> None: def test_ar_pairs_of_other_type_do_not_shift(self) -> None:
@@ -289,6 +308,7 @@ class TestMomentumPureNonARByteIdentical:
po, pm = _pair(f"p{k}", task_type="AR") po, pm = _pair(f"p{k}", task_type="AR")
mixed.extend([po, pm]) mixed.extend([po, pm])
after = _sample_momentum_candidates(mixed, allowed, samples, epoch) after = _sample_momentum_candidates(mixed, allowed, samples, epoch)
assert len(base) == samples > 0 # 非空护栏:实质性抽样
assert [q.question_id for q in base] == [q.question_id for q in after] assert [q.question_id for q in base] == [q.question_id for q in after]
def test_fewer_candidates_than_samples_returns_all(self) -> None: def test_fewer_candidates_than_samples_returns_all(self) -> None: