Skip to main content

add-unit-tests

Guide for adding unit tests to AReaL. Use when user wants to add tests for new functionality or increase test coverage.

Quellinformationen

Repository
areal-project/AReaL
Letzte Quellaktivität
28. Februar 2026 um 12:13
Erkannte Sprache von SKILL.md
Englisch
Sterne
5.829
Forks
621

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
add-unit-tests
description
Guide for adding unit tests to AReaL. Use when user wants to add tests for new functionality or increase test coverage.
# Add Unit Tests Add unit tests to AReaL following the project's testing conventions. ## When to Use This skill is triggered when: - User asks "how do I add tests?" - User wants to increase test coverage - User needs to write tests for new functionality - User wants to understand AReaL testing patterns ## Step-by-Step Guide ### Step 1: Understand Test Types AReaL has two main test categories: | Test Type | Purpose | Location Pattern | How It Runs | | --------------------- | ---------------------------------- | ---------------------------------- | ------------------------------------------ | | **Unit Tests** | Test individual functions/modules | `tests/test_<module>_<feature>.py` | Directly via pytest | | **Distributed Tests** | Test distributed/parallel behavior | `tests/torchrun/run_*.py` | Via torchrun (called by pytest subprocess) | **Note**: All tests are invoked via pytest. Distributed tests use `torchrun` but are still called from pytest test files. ### Step 2: Create Test File Structure Create test file with naming convention: `test_<module>_<feature>.py` ```python import pytest import torch # Import the module to test from areal.dataset.gsm8k import get_gsm8k_sft_dataset from tests.utils import get_dataset_path # Optional test utilities # For mocking tokenizer: from unittest.mock import MagicMock ``` ### Step 3: Write Test Functions Follow Arrange-Act-Assert pattern: ```python def test_function_under_condition_returns_expected(): """Test that function returns expected value under condition.""" # Arrange input_data = 5 expected_output = 10 # Act result = function_under_test(input_data) # Assert assert result == expected_output ``` ### Step 4: Add Pytest Markers and CI Strategy Use appropriate pytest markers: | Marker | When to Use | | --------------------------------------- | ------------------------------------------------------------ | | `@pytest.mark.slow` | Test takes > 10 seconds (excluded from CI by default) | | `@pytest.mark.ci` | Slow test that must run in CI (use with `@pytest.mark.slow`) | | `@pytest.mark.asyncio` | Async test functions | | `@pytest.mark.skipif(cond, reason=...)` | Conditional skip | | `@pytest.mark.parametrize(...)` | Parameterized tests | **CI Test Strategy**: - `@pytest.mark.slow`: Excluded from CI by default (CI runs `pytest -m "not slow"`) - `@pytest.mark.slow` + `@pytest.mark.ci`: Slow but must run in CI - No marker: Runs in CI (fast unit tests) ```python @pytest.mark.asyncio async def test_async_function(): result = await async_function() assert result == expected @pytest.mark.skipif(not torch.cuda.is_available(), reason="CUDA not available") def test_gpu_feature(): tensor = torch.tensor([1, 2, 3], device="cuda") # ... assertions @pytest.mark.parametrize("batch_size", [1, 4, 16]) def test_with_parameters(batch_size): # Parameterized test @pytest.mark.slow def test_slow_function(): # Excluded from CI by default @pytest.mark.slow @pytest.mark.ci def test_slow_but_required_in_ci(): # Slow but must run in CI ``` ### Step 5: Mock Distributed Environment For unit tests that need distributed mocks: ```python import torch.distributed as dist def test_distributed_function(monkeypatch): monkeypatch.setattr(dist, "get_rank", lambda: 0) monkeypatch.setattr(dist, "get_world_size", lambda: 2) result = distributed_function() assert result == expected ``` ### Step 6: Handle GPU Dependencies Always skip gracefully when GPU unavailable: ```python CUDA_AVAILABLE = torch.cuda.is_available() @pytest.mark.skipif(not CUDA_AVAILABLE, reason="CUDA not available") def test_gpu_function(): tensor = torch.tensor([1, 2, 3], device="cuda") # ... assertions ``` ## Key Requirements (Based on testing.md) ### Mocking Distributed - Use `torch.distributed.fake_pg` for unit tests - Mock `dist.get_rank()` and `dist.get_world_size()` explicitly - Don't mock internals of FSDP/DTensor ### GPU Test Constraints - **Always skip gracefully** when GPU unavailable - Clean up GPU memory: `torch.cuda.empty_cache()` in fixtures - Use smallest possible model/batch for unit tests ### Assertions - Use `torch.testing.assert_close()` for tensor comparison - Specify `rtol`/`atol` explicitly for numerical tests - Avoid bare `assert tensor.equal()` - no useful error message ## Reference Implementations | Test File | Description | Key Patterns | | -------------------------------- | -------------------------------------- | ------------------------------------------------- | | `tests/test_utils.py` | Utility function tests | Fixtures, parametrized tests | | `tests/test_examples.py` | Integration tests with dataset loading | Dataset path resolution, success pattern matching | | `tests/test_fsdp_engine_nccl.py` | Distributed tests | Torchrun integration | ## Common Mistakes - **Missing test file registration**: Ensure file follows `test_*.py` naming - **GPU dependency without skip**: Always use `@pytest.mark.skipif` for GPU tests - **Incorrect tensor comparisons**: Use `torch.testing.assert_close()` not `assert tensor.equal()` - **Memory leaks in GPU tests**: Clean up with `torch.cuda.empty_cache()` - **Mocking too much**: Don't mock FSDP/DTensor internals - **Unclear test names**: Follow `test_<what>_<condition>_<expected>` pattern - **No docstrings**: Add descriptive docstrings to test functions ## Integration with Other Skills This skill complements other AReaL development skills: - **After `/add-dataset`**: Add tests for new dataset loaders - **After `/add-workflow`**: Add tests for new workflows - **After `/add-reward`**: Add tests for new reward functions - **With expert agents**: Reference this skill when planning test implementation ## Running Tests ```bash # First check GPU availability (many tests require GPU) python -c "import torch; print('GPU available:', torch.cuda.is_available())" # Run specific test file uv run pytest tests/test_<name>.py # Skip slow tests (CI default) uv run pytest -m "not slow" # Run with verbose output uv run pytest -v # Run distributed tests (requires torchrun and multi-GPU) # Note: Usually invoked via pytest test files torchrun --nproc_per_node=2 tests/torchrun/run_<test>.py ``` <!-- ================================================================================ MAINTAINER GUIDE ================================================================================ Location: .opencode/skills/add-unit-tests/SKILL.md Invocation: /add-unit-tests ## Purpose Step-by-step guide for adding unit tests to AReaL. ## How to Update ### When Testing Conventions Change 1. Update "Key Requirements" section based on `testing.md` 2. Update test examples to match new patterns 3. Update reference implementations ### When Test Types Need Update 1. Update "Understand Test Types" table (currently two main types) 2. Add new examples if needed 3. Update common mistakes ### Integration with Other Skills Ensure references to other skills (`/add-dataset`, `/add-workflow`, `/add-reward`) remain accurate. ================================================================================ -->
Auf GitHub ansehen