Repository navigation
[Doc] Raise the bar for agent-written tests - #62601
Conversation
Add tests/AGENTS.md with concrete rules for tests: fail-before/pass-after evidence for reproducible bug fixes, at least one real-entry-point test for user-visible fixes, determinism and batch invariance, isolation, specific assertions, no weakening of existing tests, and CI step wiring. Point the root AGENTS.md and the pr-checklist skill at it instead of repeating rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: aoshen02 <281812371+aoshen02@users.noreply.github.com>
Keep only the rules that differed in agent dry runs: real-path regression tests for user-visible fixes, before/after evidence, no reruns or loosened assertions, determinism without batch invariance, and CI step selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: aoshen02 <281812371+aoshen02@users.noreply.github.com>
fxmarty-amd
left a comment
There was a problem hiding this comment.
very nice - some personal opinions
| - **User-visible fixes need a real-path test.** Use the cheapest level that | ||
| reproduces the problem, but a fix to user-visible behavior needs at least one | ||
| regression test through `LLM` (`vllm_runner`) or the OpenAI server | ||
| (`RemoteOpenAIServer`), not only a unit test on hand-built inputs. Mock only | ||
| external dependencies; a test that only asserts `assert_called*` or "no | ||
| exception" guards nothing. |
There was a problem hiding this comment.
I have mixed opinion on this. vllm_runner can be quite slow in the CI (#53291) and is not always necessary.
Something like:
vllm/tests/quantization/test_online.py
Lines 1002 to 1008 in a6c898e
vllm/tests/quantization/test_online.py
Line 1804 in a6c898e
& generally (not on vllm-project/vllm) yet:
@pytest.fixture
def single_rank_parallel_state(monkeypatch: pytest.MonkeyPatch):
"""Single rank parallel groups without initializing a process group.
This is faster than the `dist_init` fixture.
"""
for name in ("_WORLD", "_TP", "_ETP", "_DCP", "_PP", "_DP", "_EP", "_PCP"):
monkeypatch.setattr(
f"vllm.distributed.parallel_state.{name}", _SingleRankGroup()
)
monkeypatch.setattr(
"vllm.model_executor.parameter.get_tensor_model_parallel_rank", lambda: 0
)
monkeypatch.setattr(
"vllm.model_executor.parameter.get_tensor_model_parallel_world_size", lambda: 1
)that is faster than dist_init fixture.
Instead of vllm_runner in cases tests do not read parallelism to be meaningful.
However, there are tests that need real weight loading and not only DummyModelLoader.
| - **Never buy a green CI.** Do not add `@pytest.mark.flaky(reruns=...)`, retry | ||
| loops, wider tolerances, lowered thresholds, `skip`, or deletions to make a | ||
| test pass. Find out whether the failure is caused by your change or also | ||
| happens on main (`.buildkite/scripts/rerun-test.sh`, |
| - **Deterministic by construction.** Use greedy or seeded sampling. vLLM is not | ||
| batch invariant by default: batch size, chunked prefill, prefix caching, | ||
| backend, and TP size can flip greedy tokens, so compare against a reference | ||
| with tolerances (`check_logprobs_close`, `check_embeddings_close`) or require | ||
| `VLLM_BATCH_INVARIANT=1` for exact equality. Never synchronize with a fixed | ||
| `sleep`; poll an explicit condition with a timeout, and force race orderings | ||
| with events. |
There was a problem hiding this comment.
I would also personally prompt not to arbitrarily increase atol/rtol to make tests pass, when they are expected to have strict equality or small atol/rtol. (https://github.com/vllm-project/vllm/pull/59766)
Address review: no SimpleNamespace/MagicMock stand-ins for vLLM objects, use the lightest real path instead of always vllm_runner, forbid xfail and wider atol/rtol to pass, and compare output-preserving changes against the code they replace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: aoshen02 <281812371+aoshen02@users.noreply.github.com>
|
/ci run |
|
✅ Triggered Buildkite CI #96391 for commit |
tomasruizt
left a comment
There was a problem hiding this comment.
Nudging agents to make better tests is great!
There was a problem hiding this comment.
These should be general rules to follow and preferences, but not strict enforcements. Otherwise, agents will get stuck trying to fulfill requirements. I'm thinking concretely of:
- Objects that are really hard to instantiate atm, so
MagicMockmight be needed in special cases. - Statistical tests that check a p-value, confidence intervals, code paths that check temp != 0. These seem to clash with the requirement to always run greedy/deterministic tests.
| state is enough when parallelism is irrelevant. A fix to user-visible behavior | ||
| needs at least one regression test through `LLM` (`vllm_runner`) or | ||
| `RemoteOpenAIServer`, with real weights when loading is involved. A test that |
There was a problem hiding this comment.
-
I like high-level tests like these, but they also have trade-offs. We could add a bullet point:
"These higher-level tests are less likely to be coupled to the concrete implementation and more likely to be robust to false failure when the implementation is refactored. However, they can take many seconds or minutes to run, slowing down iteration speed. Please consider this trade-off and decide what the best level of abstraction is to introduce tests." -
And in favor of low-level unit tests:
"Low-level unit tests make it much easier to quickly iterate on an implementation. You can factor out complicated logic into pure functions that are easier to unit-test. Keep in mind, that this only exercises a part of the entire system." -
Favoring test reuse over new tests:
"Often the new feature can be tested by adding a new entry to a parametrized test that already exists. If the test code needs to be extended or refactored to cover the feature, that is preferable over introducing a completely new test".
Signed-off-by: aoshen02 <281812371+aoshen02@users.noreply.github.com> Co-authored-by: aoshen02 <281812371+aoshen02@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Overview
Raise the bar for tests written by coding agents. Adds a 31-line
tests/AGENTS.mdwith five rules that change what agents actually do, links it fromAGENTS.mdandpr-checklist§2.1, and rewrites the "unit over integration over e2e" line inAGENTS.md:LLM/vllm_runnerorRemoteOpenAIServer, not only a unit test on hand-built inputs.xfailwith an issue link for known bugs.check_logprobs_close/check_embeddings_closeor requireVLLM_BATCH_INVARIANT=1; no fixedsleepas synchronization..buildkite/test_areas/*.yamlstep selects never runs and looks like a pass.Validation
Fresh agents with no context got a repo path and one task, on
main(old instructions) and on this branch.mainLLMregression test with an exact assertionecho=True, max_tokens=0reportscompletion_tokens=1)RequestOutputto the serving layer; e2e as a manual curlxfail+ issue only if main also failsThe main difference is the first rule: on
main, agents fix user-visible bugs with unit tests on synthetic inputs and leave the real path untested.check_agent_files.pyreports no new problems (6 existing errors inmodel-recipes/transformers-upgrade).Details
The current rules come from #47784 and #57084; this replaces the "unit over integration over e2e" ordering instead of adding a conflicting rule, and keeps details in one place (
tests/AGENTS.md). Prior art: sglang.claude/rules/unit-test-admission.md(regression tests fail before the fix, mock only boundaries), PyTorch review checklist (bug fixes need a reproducing test,xfailnotskip), TensorRT-LLMtests/AGENTS.md(unregistered tests silently never run). Does not overlap the docs-requirement PR #62599.cc @simon-mo @benchislett
AI assistance (Claude Code) was used; the submitter reviewed every line.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.
🤖 Generated with Claude Code