跳到主要内容
知仓学习社ZHICANG

nw-test-organization-conventions

Test directory structure patterns by architecture style, language conventions, naming rules, and fixture placement. Decision tree for selecting test…

不碰外部(只输出文字)无严重或高危命中nWave-ai/nWave

它会碰到什么

扫了多少1 个文本文件,7 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Test Organization Conventions

Core Principle

Test directory structure encodes architectural boundaries. If a developer cannot infer the architecture from the test tree alone, the organization is wrong.

Architecture-to-Organization Decision Tree

What is the project's architectural style?
|
+-- Hexagonal / Clean Architecture
|   --> Test-type-first: tests/{unit,integration,acceptance,e2e}/
|   --> Domain concepts nested within each type
|   --> Port contract tests in tests/integration/
|
+-- Vertical Slice
|   --> Co-located: features/{slice}/tests/
|   --> Cross-slice tests in top-level tests/cross_feature/
|
+-- Modular Monolith
|   --> Module-first: tests/modules/{module}/{unit,integration}/
|   --> Architecture tests per module (dependency rule enforcement)
|   --> Inter-module tests in tests/inter_module/
|
+-- Microservices
|   --> Per-service test tree: {service}/tests/{unit,integration,component,contract}/
|   --> Contract tests: consumer writes in own repo, provider verifies in own repo
|   --> Cross-service E2E in separate project: e2e-tests/
|
+-- Event-Driven
|   --> Test-type-first with event-specific categories
|   --> Unique: schema contract tests, idempotency tests, saga compensation tests
|
+-- CQRS
|   --> Command/Query split within each test type
|   --> Unique: projection tests (rebuild + idempotency)
|
+-- Layered (N-Tier)
|   --> Mirror source: tests mirror src layer hierarchy
|   --> Integration tests verify layer boundary contracts
|
+-- DDD (Tactical)
|   --> Bounded-context-first: tests/{context}/domain/aggregates/
|   --> Cross-context contract tests in tests/bounded_context_integration/

Comparative Summary

| Architecture | Primary Axis | Secondary Axis | Unique Test Types | Co-located? |

|-------------|-------------|----------------|-------------------|-------------|

| Hexagonal | Test type | Domain concept | Port contract | No |

| Clean | Test type | Architecture ring | Gateway | No |

| Layered | Mirror source | Test type | Layer boundary | No (Java: yes) |

| Vertical Slice | Feature | Test type | Cross-slice | Yes |

| Modular Monolith | Module | Test type | Architecture, inter-module | No |

| Microservices | Per-service | Test type | Contract (Pact) | No |

| Event-Driven | Test type | Event flow role | Schema, idempotency, saga | No |

| CQRS | Command/Query | Test type | Projection | No |

| DDD | Bounded context | Building block | Aggregate, cross-context | No |

Mirror vs. Feature vs. Hybrid

| Strategy | Best For | Strengths | Weaknesses |

|----------|----------|-----------|------------|

| Mirror source | Layered, Clean, Hexagonal | Predictable paths, IDE navigation, package-private access (Java) | Feature changes touch multiple dirs |

| Feature co-located | Vertical Slice, React | All feature code in one place, team ownership | Cross-feature tests homeless, hard to run by tier |

| Hybrid (recommended) | Most projects | Type-first for CI stages, feature-nested within | Slightly deeper nesting |

Hybrid pattern (type-first, then feature within):

tests/
  unit/
    features/
      order/test_create_order.py
      payment/test_process_payment.py
  integration/
    features/
      order/test_order_repository.py
  e2e/
    test_checkout_flow.py

Language-Specific Conventions

| Language | File Convention | Discovery Rule | Co-located? |

|----------|---------------|----------------|-------------|

| Python (pytest) | test_.py or _test.py | Prefix/suffix match | Separate tests/ (recommended) or inlined |

| TypeScript/JS (Jest) | .test.ts, .spec.ts, __tests__/*.ts | testMatch pattern | Either |

| Java (JUnit/Maven) | *Test.java in mirrored package | src/test/java mirrors src/main/java | Mirrored packages |

| Go | *_test.go in same directory | Language-enforced co-location | Always co-located |

| C# (xUnit/NUnit) | *Tests.cs in parallel project | Separate test project | Separate project |

| Rust | #[cfg(test)] mod tests inline + tests/ | Inline for unit, tests/ for integration | Unit: inline, Integration: separate |

Python conftest.py Placement

Place conftest.py at the lowest directory where fixtures apply. Pytest discovers from outermost to innermost, enabling hierarchical fixture scoping:

tests/
  conftest.py              # Session fixtures: DB engine, app instance
  unit/
    conftest.py            # Unit-specific: auto-mock markers
  integration/
    conftest.py            # Integration: real DB fixtures
  acceptance/
    conftest.py            # Acceptance: feature file paths

BDD Feature Files

tests/
  features/                # Gherkin .feature files by domain
    order/
      place_order.feature
    payment/
      process_payment.feature
  step_defs/               # Step implementations by domain concept
    conftest.py
    order_steps.py
    payment_steps.py

Organize step definitions by domain concept, not by feature file. Shared steps across features prevent duplication.

Hexagonal Architecture Test Tiers

| Tier | Location | Tests | Adapters |

|------|----------|-------|----------|

| Unit | tests/unit/ | Domain model, value objects, service layer | None (pure) or mock driven ports |

| Integration | tests/integration/ | Individual adapters against real infra | Real infrastructure |

| Acceptance | tests/acceptance/ | Use cases through driving ports | In-memory adapters |

| E2E | tests/e2e/ | Full stack through HTTP/CLI | Real adapters |

Port contract tests: when multiple adapters implement one driven port, create shared contract test suite and run against each adapter.

tests/integration/
  test_repository_contract.py     # Abstract tests for RepositoryPort
  test_postgres_repository.py     # Runs contract against Postgres
  test_inmemory_repository.py     # Runs contract against in-memory

Fixture Organization

| Scope | What | Placement |

|-------|------|-----------|

| Session | Expensive setup (DB engine, app) | Root conftest.py |

| Module | Schema creation, service containers | Directory conftest.py |

| Function | Data cleanup, test isolation | autouse=True in conftest.py |

| Shared across types | Factories, builders | tests/conftest.py or tests/fixtures/ |

Anti-Patterns

| Anti-Pattern | Why It Fails | Fix |

|---|---|---|

| Flat tests/ with no structure | Cannot run by tier, no boundary visibility | Organize by primary axis of architecture |

| Mirroring hex layers in test tree | Couples tests to implementation structure | Organize by test type, not source structure |

| Acceptance tests alongside E2E | Acceptance should use in-memory adapters and run fast | Separate: acceptance/ (fast) vs e2e/ (slow) |

| Feature-coupled step definitions | Steps for login.feature only usable there | Organize steps by domain concept |

| Mixing test tiers in one directory | Cannot run unit-only in pre-commit | Separate directories per tier |

| Cross-module imports in tests | Violates module boundaries | Use inter-module tests with event bus |

| E2E inside single microservice | They span services by definition | Move to separate e2e-tests/ project |

| No contract tests between services | Mocks drift from reality | Consumer-driven contract tests (Pact) |

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

同名技能的其他版本

有 2 个不同仓库或目录里都有叫 nw-test-organization-conventions 的技能。它们内容并不相同,别混用:

  • nWave-ai/nWave — Test directory structure patterns by architecture style, language conventions, naming rule