Skip to content

Improve test organization while keeping unit tests co-located #283

@MrCoder

Description

@MrCoder

Problem Description

The current test organization in mmd-zenuml-core has several issues that make it confusing and hard to maintain, while also not fully leveraging the benefits of co-located unit tests.

Current Issues

1. Confusing Dual Test Directories

  • /test/ - Contains some unit tests
  • /tests/ - Contains E2E Playwright tests
  • The similar names (test vs tests) are confusing and error-prone

2. Split Unit Test Locations

Currently, unit tests are split between:

  • /test/unit/ - Some unit tests (parser, positioning, specs)
  • /src/**/*.spec.ts - Other unit tests co-located with source

This split defeats the purpose of co-location. Some unit tests benefit from being next to their source code, while others are separated.

3. Inconsistent Naming Conventions

  • Most files use .spec.ts or .spec.js
  • One file uses .test.ts (src/utils/urlParams.test.ts)
  • Mix of TypeScript (.spec.ts) and JavaScript (.spec.js) test files

4. Poor E2E Test Organization

  • E2E tests are at the root of /tests/
  • Empty directories /tests/config/ and /tests/e2e/
  • Snapshots mixed with test files creating clutter

5. Mixed Test File Types

  • /test/unit/parser/ contains both .js and .ts files
  • No clear pattern for when to use which

Proposed Solution

1. Keep Unit Tests Co-located (Best Practice)

  • All unit tests should stay with their source files
  • Follow pattern: ComponentName.spec.ts next to ComponentName.ts
  • Move tests from /test/unit/ to their corresponding source locations

2. Rename E2E Test Directory

  • Rename /tests/ to /e2e/ for clarity
  • Remove the confusing /test/ directory after migrating its tests

3. Organize E2E Tests Better

e2e/
├── smoke/
│   └── basic-rendering.spec.ts
├── regression/
│   └── ... (visual regression tests)
├── features/
│   ├── auth.spec.ts
│   ├── fragments.spec.ts
│   └── ...
├── fixtures/
│   └── ... (test data)
└── snapshots/
    ├── darwin/
    └── linux/

4. Standardize Naming Convention

  • Use .spec.ts for all TypeScript tests
  • Use .spec.tsx for React component tests
  • Rename urlParams.test.ts to urlParams.spec.ts
  • Convert remaining .js test files to TypeScript

5. Example Migration

Before:

/test/unit/parser/Participants.spec.js
/test/unit/positioning/ElementDistanceCalculator.spec.ts
/src/components/DiagramFrame/DiagramFrame.tsx

After:

/src/parser/Participants.spec.ts (moved and converted to TS)
/src/positioning/ElementDistanceCalculator.spec.ts (moved)
/src/components/DiagramFrame/DiagramFrame.tsx
/src/components/DiagramFrame/DiagramFrame.spec.tsx (if test exists)

Benefits

  1. Follows Best Practices: Co-located tests are industry standard
  2. Less Confusion: Clear distinction between unit tests (co-located) and E2E tests (/e2e/)
  3. Better Developer Experience: Easy to find tests, encourage test writing
  4. Consistent Standards: Single naming convention and file type
  5. Maintainable: Tests move with their source code

Migration Tasks

  1. Move all tests from /test/unit/ to their corresponding source locations
  2. Convert .js test files to TypeScript
  3. Rename /tests/ to /e2e/
  4. Reorganize E2E tests into subdirectories
  5. Update all import paths
  6. Update test configurations
  7. Remove the old /test/ directory
  8. Update CI/CD workflows
  9. Update documentation

Files to Update

  • vite.config.ts - Remove test-specific configuration, update paths
  • playwright.config.ts - Update test directory to /e2e/
  • .github/workflows/*.yml - Update test paths
  • package.json - Update test scripts
  • CLAUDE.md - Update testing documentation

Note on Co-location Best Practice

Keeping unit tests next to their source code is widely accepted as a best practice because:

  • It makes tests more discoverable
  • It encourages developers to write tests
  • It simplifies refactoring (tests move with code)
  • It makes the codebase more intuitive

This approach is recommended by Jest, used by Create React App, Vue CLI, Angular CLI, and many other modern JavaScript tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions