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:
@@ -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) # 纯非 AR:unit_id 序列 == question_id 序列
|
assert epoch_batches == _ids(batches) # 纯非 AR:unit_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:
|
||||||
|
|||||||
Reference in New Issue
Block a user