Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/skills-registry --skill fairdm-testing명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | fairdm-testing |
| description | >- Use when this capability is needed. |
Never use unittest, TestCase, or setUp/tearDown.
Tests mirror the fairdm/ source tree with test_ prefixes:
fairdm/core/project/models.py → tests/test_core/test_project/test_models.py
fairdm/contrib/contributors/ → tests/test_contrib/test_contributors/
fairdm/registry/config.py → tests/test_registry/test_config.py
fairdm/plugins.py → tests/test_plugins.py
fairdm/db/fields.py → tests/test_db/test_fields.py
See references/structure-map.md for the complete mapping.
Rules:
test_<dirname>/test_<module>.py__init__.pyunit/, integration/, contract/ subdirectories)poetry run pytest # all tests
poetry run pytest tests/test_core/ # one subtree
poetry run pytest -k "test_project" # by name
poetry run pytest -m slow # only slow-marked tests
poetry run pytest --no-header -q # quiet output
Import from the canonical path:
from fairdm.factories import (
ContributorFactory, DatasetFactory, MeasurementFactory,
OrganizationFactory, PersonFactory, ProjectFactory,
SampleFactory, UserFactory,
)
FairDM factories follow an opt-in pattern for creating related metadata (descriptions, dates):
Key Principle: By default, factories create only required fields. No descriptions or dates are auto-created.
Why Opt-In?
unique_together on (related, type). Auto-creating metadata could conflict with test-specific data.Usage Patterns:
# Minimal (no metadata) - DEFAULT behavior
project = ProjectFactory()
assert project.descriptions.count() == 0
assert project.dates.count() == 0
# With metadata (opt-in via kwargs)
project = ProjectFactory(descriptions=2, dates=1)
assert project.descriptions.count() == 2
assert project.dates.count() == 1
# Custom types (validated against model VOCABULARY)
project = ProjectFactory(
descriptions=3,
descriptions__types=["Abstract", "Introduction", "Objectives"]
)
# All core factories support this pattern
dataset = DatasetFactory(descriptions=2, dates=1)
sample = SampleFactory(descriptions=1, dates=2)
measurement = MeasurementFactory(descriptions=2)
Vocabulary Validation:
All description/date types are validated against the model's VOCABULARY.values:
# ✓ Valid - types exist in ProjectDescription.VOCABULARY
project = ProjectFactory(
descriptions=2,
descriptions__types=["Abstract", "Methods"]
)
# ✗ Raises ValueError - "InvalidType" not in VOCABULARY
project = ProjectFactory(
descriptions=1,
descriptions__types=["InvalidType"]
)
Available VOCABULARY types:
ProjectDescription.VOCABULARY.values: Abstract, Introduction, Background, Objectives, ExpectedOutput, Conclusions, Other (+ sample/measurement-specific types)ProjectDate.VOCABULARY.values: Start, EndDatasetDescription.VOCABULARY.values: Similar to ProjectDatasetDate.VOCABULARY.values: Check model for available typesSampleDescription.VOCABULARY.values: Includes SampleCollection, SamplePreparation, etc.MeasurementDescription.VOCABULARY.values: Includes MeasurementConditions, MeasurementSetup, etc.Batch Creation with Metadata:
# All projects get 2 descriptions and 1 date
projects = ProjectFactory.create_batch(5, descriptions=2, dates=1)
# Custom types for all
datasets = DatasetFactory.create_batch(
3,
descriptions=2,
descriptions__types=["Abstract", "Methods"]
)
SubFactory for FK relations — never manually create parent objects when a factory existsfactory.Sequence(lambda n: f"value{n}") for unique fieldscreate_batch(n) for bulk creationPortal-specific factories (e.g. demo app custom samples) are mapped via FAIRDM_FACTORIES
in test settings.
Use directly — no need to redeclare: db, client, rf, admin_user,
django_user_model, django_assert_num_queries.
def test_something(user): # UserFactory()
def test_something(project): # ProjectFactory(owner=user)
def test_something(project_with_datasets): # (project, [3 datasets])
def test_registration(clean_registry): # empty registry, cleaned after test
def test_dynamic_model(unique_app_label): # "test_app_<hex>" for Meta.app_label
# cleanup_test_app_models runs autouse — removes test_app_* from Django app registry
Prefer a factory call over a fixture when the fixture would just wrap a single factory call.
Group tests into classes by subject. One class per logical unit under test:
@pytest.mark.django_db
class TestProjectModel:
def test_creation_with_required_fields(self): ...
def test_uuid_is_unique(self): ...
def test_status_choices(self): ...
@pytest.mark.django_db
class TestProjectCreateForm:
def test_valid_with_required_fields(self): ...
def test_invalid_without_name(self): ...
Naming: test_<what_is_being_tested> — descriptive, no abbreviations.
@pytest.mark.django_db on every class or function that touches the database@pytest.mark.parametrize for repeated logic with different inputs@pytest.mark.slow for tests that take >1 secondNever use wall-clock timing assertions (assert elapsed < 0.1).
Use query-count guards instead:
def test_list_view_query_count(client, django_assert_num_queries):
ProjectFactory.create_batch(10)
with django_assert_num_queries(3):
client.get("/projects/")
Or algorithmic complexity guards (assert O(n) not O(n²)).
See references/exemplar-patterns.md for complete tested patterns covering:
See references/anti-patterns.md for common mistakes and their corrections.
Key configuration (already set up — do not modify without reason):
DisableMigrations classfairdm.setup(apps=["fairdm_demo"]) loads the demo appFAIRDM_FACTORIES maps demo models to their factories__init__.py in any new directoriesfairdm.factories for model instancesTestXxxModel, TestXxxForm, etc.)@pytest.mark.django_dbpoetry run pytest <test_file> to verifyThis skill file supersedes the original specs/002-testing-strategy spec (created January 2026, removed February 2026). The skill format provides more maintainable, agent-friendly documentation of FairDM's testing conventions.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.