読み込み中
豆知識
一人社長のフロント/バックエンドで、どの層のテストをいつ走らせるかの案内です。
ユニットから E2E までの層と、よく使うコマンドをまとめています。
┌───────────┐
│ E2E │ ← Slow, expensive, catch integration issues
│ Tests │ (~200 tests, run before releases)
├───────────┤
│Integration│ ← Medium speed, test service interactions
│ Tests │ (API + DB tests)
├───────────┤
│ Unit │ ← Fast, cheap, high coverage
│ Tests │ (Functions, components, hooks)
└───────────┘
Recommended Distribution:
What: Test individual functions, methods, or components in isolation.
When to Use:
Characteristics:
Example:
// src/utils/currency.test.ts
import { formatYen } from "./currency"
describe("formatYen", () => {
it("formats positive amounts with ¥ symbol", () => {
expect(formatYen(1234567)).toBe("¥1,234,567")
})
it("handles zero", () => {
expect(formatYen(0)).toBe("¥0")
})
it("formats negative amounts with minus sign", () => {
expect(formatYen(-5000)).toBe("-¥5,000")
})
})
Tools:
What: Test how multiple units work together, including API calls and database operations.
When to Use:
Characteristics:
Example (Backend API Test):
# tests/integration/test_documents_api.py
def test_create_document_with_linked_transaction():
"""Test creating a document and linking it to a bank transaction."""
# Setup
transaction_id = create_test_transaction(amount=10000)
# Create document via API
response = client.post('/api/documents', json={
'type': 'invoice',
'amount': 10000,
'linked_transaction_id': transaction_id
})
assert response.status_code == 201
# Verify link was created
links = db.query("SELECT * FROM document_transaction_links WHERE document_id = %s",
[response.json()['id']])
assert len(links) == 1
assert links[0]['bank_transaction_id'] == transaction_id
Example (Frontend Hook Test):
// src/hooks/useDocuments.test.ts
import { renderHook, waitFor } from "@testing-library/react"
import { useDocuments } from "./useDocuments"
describe("useDocuments", () => {
it("fetches and returns documents list", async () => {
const { result } = renderHook(() => useDocuments())
await waitFor(() => {
expect(result.current.isLoading).toBe(false)
})
expect(result.current.documents).toHaveLength(10)
expect(result.current.documents[0]).toHaveProperty("id")
})
})
What: Test complete user flows by automating browser interactions.
When to Use:
Characteristics:
Our E2E Test Types:
| Type | Badge | Description |
|---|---|---|
smoke |
Purple | Basic functionality - page loads, no errors |
visibility |
Blue | UI element presence verification |
interaction |
Amber | Click, type, and user action tests |
content |
Cyan | Data display and formatting validation |
flow |
Indigo | Multi-step user journey tests |
Example:
# tests/e2e/tests/test_home_page.py
@test("Page Loads",
description="Verify home page renders without JavaScript errors",
test_type="smoke",
expected="DOM loads completely, no console errors")
def test_page_loads(self) -> bool:
return self.home_page.is_page_loaded()
@test("Tab Sales Click",
description="Click 営業 (Sales) tab and verify it becomes active",
test_type="interaction",
expected="Tab highlights, sales documents panel displays")
def test_tab_sales_click(self) -> bool:
return self.home_page.click_tab_sales()
Tools:
What: Verify the system meets business requirements from user perspective.
When to Use:
Characteristics:
Example (Gherkin format):
Feature: Tax Estimation Calculator
As a business owner
I want to estimate my tax liability
So I can plan my finances
Scenario: Calculate corporate tax
Given I am on the tax estimation page
And my revenue is ¥10,000,000
And my expenses are ¥7,000,000
When I view the tax breakdown
Then I should see corporate tax based on ¥3,000,000 profit
And the tax rate should match current brackets
What: Measure system performance under various conditions.
When to Use:
Metrics to Measure:
Tools:
What: Identify security vulnerabilities.
When to Use:
Areas to Test:
Example (RLS Test):
-- Test that user A cannot see user B's documents
SET LOCAL role = 'authenticated';
SET LOCAL request.jwt.claims = '{"sub": "user-a-id"}';
SELECT * FROM documents WHERE user_id = 'user-b-id';
-- Should return 0 rows
What: Quick sanity checks that critical paths work.
When to Use:
Characteristics:
Our Smoke Test Checklist:
[What]_[Condition]_[Expected Result]
Good:
formatYen_withNegativeAmount_returnsMinusSignDocumentList_whenEmpty_showsEmptyStateLoginForm_withInvalidCredentials_showsErrorBad:
test1testFormattingit_worksit("creates a document with correct amount", () => {
// Arrange - Set up test data
const amount = 50000
// Act - Perform the action
const document = createDocument({ amount })
// Assert - Verify the result
expect(document.amount).toBe(50000)
expect(document.formatted_amount).toBe("¥50,000")
})
Each test should verify one specific behavior. Multiple assertions are OK when testing related properties.
Tests should not depend on each other. Each test should set up its own data and clean up after itself.
// Good
expect(result).toBe(
expected,
`Expected ${expected} but got ${result} for input ${input}`
)
// Better with custom matchers
expect(result).toEqualYen(expected)
# Run all unit tests
npm run test
# Run with watch mode
npm run test:watch
# Run specific file
npm run test -- src/utils/currency.test.ts
# Run with coverage
npm run test:coverage
# 1. Launch Chrome with debug port
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="C:\temp\chrome-debug-profile"
# 2. Log in to
# 3. Run all E2E tests (PARALLEL - recommended, ~3x faster)
python tests/e2e/run_parallel_tests.py
# 4. Run with more workers for even faster execution
python tests/e2e/run_parallel_tests.py --workers 5
# 5. Run in background (returns immediately)
python tests/e2e/run_parallel_tests.py --background
# 6. Run specific suites
python tests/e2e/run_parallel_tests.py --suites home,settings,journal
# 7. Sequential execution (original, slower)
python tests/e2e/run_all_tests.py
# 8. Save results to database
python tests/e2e/run_parallel_tests.py --save-to-db
Parallel Execution Benefits:
/docs/testing-strategy(公開ハブ)。/docs/dev/* は /docs/developer-guide へリダイレクト。npx playwright test --config=playwright.e2e.config.tstests/test-results/e2e-full-report.htmltests/test-results/e2e-full-results.json各レイヤーの目標値です。最新の実測値は CI のカバレッジレポート (npm run test:coverage) を参照してください。
| Area | Target |
|---|---|
| Utility Functions | 90%+ |
| React Hooks | 80%+ |
| UI Components | 70%+ |
| API Endpoints | 80%+ |
| E2E Critical Paths | 100% |
name: Test Suite
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run test:coverage
e2e-tests:
runs-on: ubuntu-latest
needs: unit-tests
steps:
- uses: actions/checkout@v4
- run: python tests/e2e/run_all_tests.py --save-to-db
| Test Type | Speed | Scope | When to Run |
|---|---|---|---|
| Unit | Fast | Single function | Every commit |
| Integration | Medium | Multiple services | PR merge |
| E2E | Slow | Full user flow | Before release |
| Smoke | Fast | Critical paths | After deploy |
| Performance | Medium | System capacity | Before major release |
| Security | Variable | Vulnerabilities | Regular audits |
読み込み中
豆知識