πŸ§ͺ Black Trigram (ν‘κ΄˜)

May 5, 2026 Β· View on GitHub

πŸ” ISMS Alignment: This unit test plan implements Secure Development Policy Section 4.3.1 - Unit Testing Requirements.

1. Overview

This document outlines the comprehensive unit testing strategy for the Black Trigram (ν‘κ΄˜) project - a realistic 3D precision combat game inspired by Korean martial arts philosophy and the I Ching. The application is built using React 19 with TypeScript and Three.js (@react-three/fiber), with unit tests implemented using Vitest 4.

ISMS Compliance Requirements

Per Hack23 AB's Secure Development Policy, this project maintains:

🎯 RequirementπŸ“Š Targetβœ… CurrentπŸ“‹ ISMS Reference
Line Coverageβ‰₯80%69.72% ⚠️Section 4.3.1.1
Branch Coverageβ‰₯70%60.87% ⚠️Section 4.3.1.2
Test ExecutionEvery commitβœ… AutomatedSection 4.3.1.3
Public ReportingRequiredβœ… PublishedSection 4.3.1.4

Evidence Links:

See Also:


2. Testing Framework

2.1 Core Testing Stack

ComponentTechnologyVersionPurpose
Unit TestingVitest4.0.6Modern, fast unit test runner
E2E TestingCypress15.6.0End-to-end browser testing
Component Testing@testing-library/react16.3.0React component testing utilities
Coverage Tool@vitest/coverage-v84.0.8V8-based code coverage reporting
Test Environmentjsdom27.2.0DOM simulation for Node.js
UI Testing@vitest/ui4.0.6Visual test interface
Coverage Reportstext, html, lcov, json-Multiple formats with full filenames (120 cols)

2.2 Three.js Testing Configuration

Black Trigram uses Three.js with @react-three/fiber for game rendering, requiring special test configuration:

// vitest.config.ts
test: {
  environment: 'jsdom',
  setupFiles: ['./src/test/test-setup.ts'],
  server: {
    deps: {
      inline: [], // Three.js works well with Vitest by default
    },
  },
}

2.3 Korean Martial Arts Testing Requirements

Tests must validate:

  • βœ… All 8 trigram stances (건/νƒœ/리/μ§„/손/감/κ°„/κ³€)
  • βœ… All 5 player archetypes (무사/μ•”μ‚΄μž/해컀/μ •λ³΄μš”μ›/쑰직폭λ ₯λ°°)
  • βœ… Korean-English bilingual text rendering
  • βœ… Vital point system accuracy (70 anatomical targets)
  • βœ… Combat effectiveness calculations
  • βœ… Cultural authenticity of Korean martial arts representation

3. Test Organization

3.1 File Structure

Unit tests are placed alongside their implementation files with the .test.ts or .test.tsx extension:

src/
β”œβ”€β”€ systems/
β”‚   β”œβ”€β”€ CombatSystem.ts
β”‚   β”œβ”€β”€ CombatSystem.test.ts          # Core combat mechanics tests
β”‚   β”œβ”€β”€ TrigramSystem.ts
β”‚   β”œβ”€β”€ TrigramSystem.test.ts         # Eight trigram stance tests
β”‚   β”œβ”€β”€ VitalPointSystem.ts
β”‚   β”œβ”€β”€ VitalPointSystem.test.ts      # Vital point targeting tests
β”‚   β”œβ”€β”€ GameIntegration.test.ts       # Integration tests
β”‚   β”œβ”€β”€ trigram/
β”‚   β”‚   β”œβ”€β”€ StanceManager.ts
β”‚   β”‚   β”œβ”€β”€ StanceManager.test.ts     # Stance transition logic
β”‚   β”‚   β”œβ”€β”€ KoreanCulture.ts
β”‚   β”‚   β”œβ”€β”€ KoreanCulture.test.ts     # Korean culture validation
β”‚   β”‚   β”œβ”€β”€ KoreanTechniques.ts
β”‚   β”‚   β”œβ”€β”€ KoreanTechniques.test.ts  # Korean technique authenticity
β”‚   β”‚   β”œβ”€β”€ TransitionCalculator.ts
β”‚   β”‚   └── TransitionCalculator.test.ts
β”‚   └── vitalpoint/
β”‚       β”œβ”€β”€ KoreanAnatomy.ts
β”‚       β”œβ”€β”€ DamageCalculator.ts
β”‚       β”œβ”€β”€ HitDetection.ts
β”‚       └── (tests to be added)
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ ui/
β”‚   β”‚   β”œβ”€β”€ KoreanHeader.test.tsx     # Korean text rendering
β”‚   β”‚   └── base/
β”‚   β”‚       └── (Three.js 3D components)
β”‚   β”œβ”€β”€ game/
β”‚   β”‚   β”œβ”€β”€ DojangBackground.test.tsx # Korean dojo aesthetics
β”‚   β”‚   └── GameAudio.test.tsx
β”‚   └── combat/
β”‚       └── components/
β”‚           β”œβ”€β”€ CombatHUD.test.tsx
β”‚           β”œβ”€β”€ CombatControls.test.tsx
β”‚           └── CombatStatsPanel.test.tsx
β”œβ”€β”€ audio/
β”‚   β”œβ”€β”€ AudioManager.test.ts
β”‚   └── AudioUtils.test.ts
└── utils/
    └── playerUtils.test.ts           # Player archetype creation

3.2 Test Categories

CategoryPurposeExamplesCoverage Target
System TestsCore game mechanicsCombat, Trigram, VitalPoint systems90%+
Component TestsReact/Three.js componentsUI elements, game graphics70%+
Integration TestsMulti-system workflowsComplete combat sequences80%+
Utility TestsHelper functionsPlayer creation, calculations90%+
Cultural TestsKorean authenticityNames, techniques, stances100%

3.3 Current Test Statistics

As of Latest Coverage Run (December 2025):

  • Total Tests: 1,192 tests (passed) + 2 skipped = 1,194 total
  • Test Files: 63 test suites
  • Test Duration: ~40 seconds
  • Pass Rate: 100% (1,192/1,192 passing)
  • Flaky Tests: 0 βœ…

4. Testing Standards

4.1 Test Structure - AAA Pattern

All tests follow the Arrange-Act-Assert pattern:

import { describe, it, expect, beforeEach } from "vitest";

describe("VitalPointSystem", () => {
  it("should calculate damage based on vital point criticality", () => {
    // Arrange
    const system = new VitalPointSystem();
    const criticalPoint = system.getVitalPoint("νƒœμ–‘ν˜ˆ"); // Solar plexus
    const normalPoint = system.getVitalPoint("볡뢀"); // Abdomen

    // Act
    const criticalDamage = system.calculateDamage(criticalPoint, 50);
    const normalDamage = system.calculateDamage(normalPoint, 50);

    // Assert
    expect(criticalDamage).toBeGreaterThan(normalDamage);
    expect(criticalPoint.korean).toBe("νƒœμ–‘ν˜ˆ");
  });
});

4.2 Component Testing Standards

React/Three.js components must test:

describe("KoreanHeader", () => {
  it("renders Korean and English text", () => {
    const { container } = render(
      <KoreanHeader korean="ν‘κ΄˜" english="Black Trigram" />
    );

    expect(container).toHaveTextContent("ν‘κ΄˜");
    expect(container).toHaveTextContent("Black Trigram");
  });

  it("uses Korean font family", () => {
    render(<KoreanHeader korean="무사" english="Warrior" />);

    const text = screen.getByText(/무사/);
    expect(text).toHaveStyle({ fontFamily: FONT_FAMILY.KOREAN });
  });
});

4.3 Mock Strategy

Three.js Mocking

// src/test/test-setup.ts
// Three.js mocking if needed (usually not required for basic tests)
vi.mock("three", () => ({
  WebGLRenderer: vi.fn(() => ({
    render: vi.fn(),
    setSize: vi.fn(),
    dispose: vi.fn(),
  })),
  Scene: vi.fn(),
  PerspectiveCamera: vi.fn(),
  Mesh: vi.fn(),
  BoxGeometry: vi.fn(),
  MeshStandardMaterial: vi.fn(),
  Texture: {
    from: vi.fn(() => ({})),
    WHITE: {},
  },
}));

Audio Mocking

vi.mock("../audio/AudioProvider", () => ({
  useAudio: vi.fn(() => ({
    playSFX: vi.fn(),
    playMusic: vi.fn(),
    setVolume: vi.fn(),
  })),
}));

4.4 Edge Case Testing

Every function must test:

  • βœ… Happy path (expected input)
  • βœ… Boundary conditions (min/max values)
  • βœ… Invalid input (null, undefined, negative)
  • βœ… Error handling and recovery
describe("applyDamage", () => {
  it("should handle negative damage", () => {
    const player = createPlayer();
    const result = applyDamage(player, -10);
    expect(result.health).toBe(player.health); // No change
  });

  it("should clamp health to zero", () => {
    const player = createPlayer({ health: 50 });
    const result = applyDamage(player, 100);
    expect(result.health).toBe(0);
    expect(result.health).toBeGreaterThanOrEqual(0);
  });
});

5. Code Coverage Requirements

5.1 Overall Coverage Targets

Per ISMS Secure Development Policy:

MetricPolicy MinimumCurrentStatusTarget Date
Line Coverage80%69.72%⚠️ Gap: 10.28%Q1 2026
Branch Coverage70%60.87%⚠️ Gap: 9.13%Q1 2026
Function Coverage75%68.00%⚠️ Gap: 7.0%Q1 2026
Statement Coverage80%69.06%⚠️ Gap: 10.94%Q1 2026

5.2 Component-Level Coverage

ComponentCurrentTargetPriorityStatus
Systems (Core)95.88%90%Highβœ… Excellent
- TrigramSystem95.34%90%Highβœ… Excellent
- VitalPointSystem95.34%90%Highβœ… Excellent
- CombatSystem94.31%90%Criticalβœ… Excellent
Audio84.51%70%Mediumβœ… Excellent
- AudioManager24.62%70%Medium❌ Major Gap
- AudioUtils34.66%70%Medium❌ Major Gap
Combat Hooks84.44%70%Highβœ… Excellent
- useCombatLayout100.00%90%Highβœ… Excellent
UI Components32.69%70%Medium❌ Major Gap
- HealthBar25.28%70%Medium❌ Major Gap
- RoundTimer40.00%70%Medium❌ Major Gap
- StanceIndicator29.16%70%Medium❌ Major Gap
Combat Components63.18%70%High⚠️ Close
- CombatControls24.44%70%High❌ Critical Gap
- CombatHUD16.66%70%High❌ Critical Gap
- CombatStatsPanel34.69%70%High❌ Major Gap
Vital Point System93.33%90%Criticalβœ… Excellent
- DamageCalculator0.00%90%Critical❌ Not Tested
- HitDetection0.00%90%Critical❌ Not Tested
- KoreanAnatomy19.76%90%Critical❌ Critical Gap
Utilities62.82%80%High⚠️ Gap: 17.18%
- playerUtils94.11%90%Highβœ… Excellent
- threeHelpers18.36%70%Medium❌ Major Gap

5.3 Coverage Enforcement

Coverage thresholds are enforced in vitest.config.ts:

coverage: {
  provider: 'v8',
  reporter: [
    ['text', { maxCols: 120 }],        // Wide columns for full filenames
    ['html', { subdir: 'html' }],       // HTML report in subdirectory
    ['lcov', { file: 'lcov.info' }],    // LCOV format for CI integration
    ['json', { file: 'coverage.json' }], // JSON format for tooling
    ['json-summary', { file: 'coverage-summary.json' }], // Summary JSON
  ],
  reportsDirectory: './build/coverage',
  skipFull: false, // Show files with 100% coverage
  // Note: Global thresholds commented out to avoid breaking existing code
  // These should be enforced via CI checks for new/changed files only
  // thresholds: {
  //   lines: 80,
  //   branches: 70,
  //   functions: 75,
  //   statements: 80,
  // },
}

Regression Prevention: Coverage reports are generated on every commit via CI/CD pipeline to prevent regressions.


6. Test Execution Procedures

6.1 Development Commands

CommandPurposeUse Case
npm testRun all tests onceQuick validation
npm run test:systemsRun system tests onlyCore mechanics validation
npm run test:systems:watchWatch mode for systemsActive development
npm run test:systems:uiVisual test UIInteractive debugging
npm run coverageGenerate coverage reportCoverage analysis
npm run test:ciCI test executionAutomated pipeline

6.2 Coverage Report Generation

# Generate full coverage report with enhanced formatting
npm run coverage

# View HTML coverage report (detailed, interactive)
open build/coverage/html/index.html

# Check specific system coverage
npm run test:systems:coverage

Coverage Report Features:

  • Text Report: 120-column width for full filenames (no truncation)
  • HTML Report: Interactive web interface with drill-down capabilities
  • LCOV Report: Standard format for CI/CD integration (e.g., Codecov, Coveralls)
  • JSON Reports: Machine-readable formats for custom tooling and analysis
  • Summary JSON: Quick overview of overall coverage metrics

Coverage Report Locations:

  • HTML Report: build/coverage/html/index.html
  • LCOV Report: build/coverage/lcov.info
  • JSON Report: build/coverage/coverage.json
  • JSON Summary: build/coverage/coverage-summary.json
  • Note: Coverage reports are in build/ directory (excluded from git)

6.3 Test Debugging

# Run tests with UI for debugging
npm run test:systems:ui

# Run specific test file
npx vitest src/systems/CombatSystem.test.ts

# Run tests matching pattern
npx vitest --grep "Korean"

# Debug in Node inspector
node --inspect-brk ./node_modules/.bin/vitest

7. CI/CD Integration

7.1 GitHub Actions Workflow

Tests are automatically executed via .github/workflows/test-and-report.yml:

name: Test and Report

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  unit-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v6
        with:
          node-version-file: '.nvmrc'

      - name: Install dependencies
        run: npm ci

      - name: Run unit tests with coverage
        run: npm run coverage
        env:
          JEST_JUNIT_OUTPUT_DIR: "docs/coverage"
          JEST_JUNIT_OUTPUT_NAME: "junit.xml"