add-test
Skill240 starsChanged 11 days agoApache-2.0View on GitHub
Use when assessing the need for, adding, or extending tests for EmbodiChain modules
18 other projects use a version of this.
Adopted by
Most recently taken up by
- microsoft/veronatheir own version, first seen Nov 8, 2026
- TidalPaladin/skillstheir own version, first seen Nov 8, 2026
- flavien-ia/hypervibe-crafttheir own version, first seen Oct 25, 2026
- flavien-ia/hypervibe-harnesstheir own version, first seen Oct 23, 2026
- WhatIfWeDigDeeper/claude-code-courseratheir own version, first seen Oct 20, 2026
- nativewind/react-native-csstheir own version, first seen Oct 9, 2026
Used with
Projects with it also use triage and review.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.Other versions18 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 18
- gitkraken/vscode-gitlens★ 10ksame name
- nativewind/nativewind★ 8.1ksame name
- microsoft/verona★ 3.7ksame name
- The-OpenROAD-Project/OpenROAD★ 3.3ksame name
- OpenAEV-Platform/openaev★ 1.8ksame name
- fpindej/netrock★ 234same name
- nativewind/react-native-css★ 167same name
- osmandapp/web★ 63same name
- flavien-ia/hypervibe-craft★ 50same name
- flavien-ia/hypervibe-harness★ 50same name
8 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository35 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-atomic-actionSkill
- add-embodiment-componentSkill
- add-functorSkill
- add-robotSkill
- add-semantic-callSkill
- add-solverSkill
- add-task-envSkill
- add-task-programSkill
- benchmarkSkill
- implement-performanceSkill
- pre-commit-checkSkill
- project-dev-contextSkill
- prSkill
- releaseSkill
- review-prSkill
- update-api-docsSkill
- add-atomic-actionSkill
- add-embodiment-componentSkill
- add-functorSkill
- add-robotSkill
- add-semantic-callSkill
- add-solverSkill
- add-task-envSkill
- add-task-programSkill
- add-testSkill
- benchmarkSkill
- implement-performanceSkill
- pre-commit-checkSkill
- project-dev-contextSkill
- prSkill
- releaseSkill
- review-prSkill
- update-api-docsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. 0 are common, 10 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 17 edited versions we read keep these.
10
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 19
Before adding or extending tests, inspect the production contract, supported callers and inputs, and the closest existing coverage.
- Distinctive: line 26
Use an independent expected result derived from the contract, a known example, or a trusted reference.
- Distinctive: line 28
Avoid reproducing the implementation to calculate its own expected result or asserting only that a result exists when correctness matters.
- Distinctive: line 30
Prefer extending a relevant case or adding a meaningful parameter to creating parallel coverage.
- Distinctive: line 34
Keep negative and boundary cases for explicit validation contracts, safety constraints, and reachable failures.
- Very specific: line 59
Create __init__.py files in new tests/ subdirectories if needed
- Very specific: line 65
Use when: testing functors, utility functions, pure math, config validation — anything that doesn't need a SimulationManager.
- Very specific: line 90
Use when: tests need SimulationManager, GPU setup, or must run in a specific order.
- Distinctive: line 129
Use the narrowest test type that proves the behavior:
- Distinctive: line 131
Prefer mocks or CPU-only inputs for pure logic and shape validation.
- Distinctive: line 183
When changed validation behavior lacks coverage, add a focused negative case at its earliest owning boundary.
- Very specific: line 229
Use MagicMock(uid="...") for SceneEntityCfg parameters
- Distinctive: line 249
Prefer extending a relevant existing case or test module when it closes the identified gap.
- Distinctive: line 266
Use the appropriate template (pytest or class style above).
“Common” is measured: kept by at least 6 in 10 of the 17 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add Test
Reuse sufficient existing coverage; add or extend focused tests following EmbodiChain's conventions when a meaningful coverage gap remains.
When to Use
- User asks to "add a test", "write tests for X", "test this module"
- A production change may leave a behavior or regression unverified
- Assessing test coverage during PR preparation or review
Test necessity review
Before adding or extending tests, inspect the production contract, supported callers and inputs, and the closest existing coverage. Reapply these criteria after writing the cases:
- Identify the observable behavior, real regression, or explicit boundary the case protects and the gap in existing coverage. Reuse adequate existing tests; a new public function or PR checklist does not require a new test file.
- Use an independent expected result derived from the contract, a known example, or a trusted reference. A regression case should detect the original error. Avoid reproducing the implementation to calculate its own expected result or asserting only that a result exists when correctness matters.
- Prefer extending a relevant case or adding a meaningful parameter to creating parallel coverage. Remove or merge additions that repeat the same behavior without detecting a distinct failure. Do not lock private layout, call order, or source wording without a contract requirement.
- Keep negative and boundary cases for explicit validation contracts, safety constraints, and reachable failures. Do not enumerate hypothetical unsupported states, chase coverage percentages, or add cases just to check a PR box.
- Weigh distinct verification value against fixture complexity, brittleness, maintenance, and runtime/resource cost. Preserve explicitly requested scenarios while simplifying their implementation.
Briefly report the coverage relied upon, including why no new cases were needed when existing tests or appropriate static checks suffice. No per-test justification ledger is required.
Test File Location
Tests mirror the source tree under tests/:
embodichain/lab/sim/motion/solvers/pytorch_solver.py → tests/sim/motion/solvers/test_pytorch_solver.py
embodichain/lab/gym/envs/managers/rewards.py → tests/gym/envs/managers/test_reward_functors.py
embodichain/toolkits/graspkit/pg_grasp/foo.py → tests/toolkits/test_pg_grasp.py
extensions/embodichain_tasks/embodichain_tasks/manipulation/push_cube.py → tests/gym/envs/tasks/test_push_cube.pyRules:
- File name:
test_<module>.py - Directory path mirrors
embodichain/structure undertests/ - Create
__init__.pyfiles in newtests/subdirectories if needed
Two Test Styles
pytest Style — For Pure-Python Logic (No Sim)
Use when: testing functors, utility functions, pure math, config validation — anything that doesn't need a SimulationManager.
# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# ...
# ----------------------------------------------------------------------------
from __future__ import annotations
import pytest
import torch
from embodichain.my_module import my_function
def test_expected_output():
result = my_function(input_value)
assert result == expected_valueClass Style — For Sim-Dependent or Ordered Tests
Use when: tests need SimulationManager, GPU setup, or must run in a specific order. Share state via setup_method/teardown_method.
# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# ...
# ----------------------------------------------------------------------------
from __future__ import annotations
import pytest
import torch
from embodichain.lab.sim import SimulationManager, SimulationManagerCfg
class TestMySimComponent:
def setup_method(self):
config = SimulationManagerCfg(headless=True, device="cpu")
self.sim = SimulationManager(config)
# ... setup ...
def teardown_method(self):
self.sim.destroy()
SimulationManager.flush_cleanup_queue()
def test_basic_behavior(self):
result = self.sim.do_something()
assert result == expected_result
def test_raises_on_bad_input(self):
with pytest.raises(ValueError):
self.sim.do_something(bad_input)Resource-Aware Test Classification
Use the narrowest test type that proves the behavior:
- Prefer mocks or CPU-only inputs for pure logic and shape validation.
tests/conftest.pyautomatically classifies conventional CUDA, renderer, and real-simulation tests. Add@pytest.mark.gpu,@pytest.mark.slow, or@pytest.mark.requires_simexplicitly only when the test's node id/source cannot reveal that requirement (for example, a hidden CUDA helper or an end-to-end toolkit test).
Slow CPU cases that do not launch simulation can run on separate workers. Keep
them independent of test order and shared mutable module state, or declare an
explicit xdist_group when cases must stay together. Ordinary CPU modules and
native resource groups retain their existing grouping.
The CI runner discovers serial GPU/simulation selections in a separate collection-only process, then executes their exact ordered node IDs. Execution checks that node order and markers match discovery before setup. Keep imports and parametrization independent of unrelated test modules; discovery and execution startup both count toward lane time. Retain native destruction, cleanup-queue flushes and garbage collection in every test lifecycle.
GPU tests are skipped by default to keep normal test runs within the shared VRAM budget. Run them explicitly and serially:
# Default suite: GPU-marked tests are skipped.
pytest tests/
# Dedicated GPU suite. Do not add -n unless pytest-xdist is installed.
pytest tests/ --run-gpu -m gpuFor backend/device matrices, run the complete contract on one representative
configuration and use small (one environment, low-resolution) smoke tests for
the remaining configurations. Always destroy a real SimulationManager and
flush its cleanup queue in teardown.
Task Program and task-configuration tests
Choose the test surface by ownership layer:
| Changed boundary | Primary test location |
| Language schema, strict decoder, AST/compiler | tests/lab/task_program/ |
| Semantic scene/profile/call/effect contracts | tests/lab/task_program/semantics/ |
| Configured integration, catalog, simulation assembly | tests/gym/envs/task_program/ |
| Gym bridge and episode completion | tests/gym/envs/task_program/, tests/gym/envs/test_embodied_env_task_program.py |
| Packaged task components/deployments | tests/test_task_program_package_data.py, task-layout/config tests |
| Lightweight RL environment/trainer routing | tests/learning/ |
For JSON/YAML configuration, test through the same strict loader and component
composition used by production. A yaml.safe_load() assertion alone does not
prove closed fields, relative component paths, physical scene targets,
contracts, catalog coverage, or program preflight.
When changed validation behavior lacks coverage, add a focused negative case at
its earliest owning boundary. Candidate cases include unknown fields, missing
component files, duplicate inline/component ownership, absent simulation_uid,
contract mismatch, unknown Semantic Calls, or missing registered lowerers; they
are not a required matrix for every change. Keep live-simulation qualification
separate from provider-free decode/compiler tests.
For a complete configured Task Program deployment, use
$add-task-program's read-only inspector as a focused smoke check before
adding a heavier environment test.
Mocking Patterns for Functor Tests
Most functor tests don't need a live simulation. Use mock objects following the pattern in tests/gym/envs/managers/test_reward_functors.py:
from unittest.mock import MagicMock, Mock
class MockSim:
"""Mock simulation for functor tests."""
def __init__(self, num_envs: int = 4):
self.num_envs = num_envs
self.device = torch.device("cpu")
self._rigid_objects: dict = {}
def get_rigid_object(self, uid: str):
return self._rigid_objects.get(uid)
def add_rigid_object(self, obj):
self._rigid_objects[obj.uid] = obj
class MockEnv:
"""Mock environment for functor tests."""
def __init__(self, num_envs: int = 4):
self.num_envs = num_envs
self.device = torch.device("cpu")
self.sim = MockSim(num_envs)Key points for mock objects:
- Set
num_envsanddeviceattributes (functors use these) - Mock only the sim methods the functor actually calls
- Use
MagicMock(uid="...")forSceneEntityCfgparameters
Steps
1. Identify the Behavior and Coverage Gap
Inspect the changed code, its callers, and existing tests to determine the behavior to verify and whether it needs live simulation. Apply the test necessity review; reuse sufficient existing coverage instead of adding a case. Ask the user only when unresolved intent materially affects the required coverage.
2. Determine Test File Path
Map the source path to test path:
embodichain/<subpath>/<module>.py → tests/<subpath>/test_<module>.pyPrefer extending a relevant existing case or test module when it closes the identified gap. Create a new test file only when no suitable module exists.
3. Choose Test Style
digraph test_style {
rankdir=LR;
"Needs SimulationManager?" -> "Class style" [label="yes"];
"Needs SimulationManager?" -> "pytest style" [label="no"];
"Tests share state/order?" -> "Class style" [label="yes"];
"Tests share state/order?" -> "pytest style" [label="no"];
}4. Write the Test
Use the appropriate template (pytest or class style above).
Rules:
- Apache 2.0 header — required on every test file
from __future__ import annotations— after header, before imports- No magic numbers — define expected values as named constants or comment their origin
- Test function names —
test_<scenario>(descriptive, not justtest_foo) - One assertion concept per test — don't bundle unrelated checks
Reapply the test necessity review to the completed cases and remove or consolidate redundant additions before validation.
5. Add if __name__ == "__main__" Block
Include this for tests that support optional visual/interactive debugging:
if __name__ == "__main__":
# For visual debugging: set is_visual=True when calling env methods
test_obj = TestMyComponent()
test_obj.setup_method()
# ... manually run test logic ...6. Run the Test
# Single file
pytest tests/<subpath>/test_<module>.py -v
# Single test function
pytest tests/<subpath>/test_<module>.py::test_expected_output -v
# GPU-specific test
pytest tests/<subpath>/test_<module>.py --run-gpu -m gpu -v
# Single test class method
pytest tests/<subpath>/test_<module>.py::TestMyClass::test_basic_behavior -v7. Run black
black tests/<subpath>/test_<module>.pyConventions Summary
| Convention | Rule |
| File header | Apache 2.0 copyright block (same 15 lines as source) |
| File naming | test_<module>.py |
| Function naming | test_<scenario> |
from __future__ | Required after header |
| Magic numbers | Define as named constants with explanatory comments |
| Simulation tests | Initialize/teardown in setup_method/teardown_method |
| CUDA coverage | Use @pytest.mark.gpu; run with --run-gpu -m gpu |
| Long integration | Use @pytest.mark.slow; keep it out of normal PR runs |
| Pure-logic tests | Use mock objects, no real sim |
SceneEntityCfg | Use MagicMock(uid="...") in tests |
| Assertions | assert, pytest.approx, torch.allclose, pytest.raises |
| Entry block | if __name__ == "__main__" for visual debugging support |
Common Mistakes
| Mistake | Fix |
| Missing Apache header on test file | Copy the 15-line copyright block |
Using real SimulationManager for functor tests | Use MockEnv/MockSim — much faster, no GPU needed |
| Hardcoded numbers without explanation | Define as EXPECTED_DISTANCE = 0.5 # cube at origin, target at (0.5, 0, 0) |
| Testing multiple concepts in one function | Split into separate test_<scenario> functions |
| Forgetting cleanup | Call self.sim.destroy() and SimulationManager.flush_cleanup_queue() in teardown |
| Using full matrices | Use one full representative case and low-resource smoke coverage elsewhere |
Not running black on test file | CI checks all files including tests |
Quick Reference
| Action | Command |
| Run default tests | pytest tests/ |
| Run GPU tests | pytest tests/ --run-gpu -m gpu |
| Run single file | pytest tests/<path>/test_<name>.py -v |
| Run single test | pytest tests/<path>::test_<name> -v |
| Run with print output | pytest -s tests/<path>/test_<name>.py |
| Format | black tests/<path>/test_<name>.py |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

