Skip to content

Buổi 9: Test Gate Assembly - 5 Layers đội hình

I. Lý Thuyết (30 phút)

5 Phases of Test Gate Protocol

┌─────────────────────────────────────────────────┐
│  PHASE 1: Stack Detection (Node.js+Express+SQLite) │
│  Check: package.json, src/, test/                │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│  PHASE 2: 4 Core Test Files                      │
│  ✓ Frontend Safety (jest)                        │
│  ✓ API Routes (supertest)                        │
│  ✓ Business Logic (Vitest)                       │
│  ✓ i18n Sync (JSON parity)                       │
│  ✓ Security Scan (secret patterns)               │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│  PHASE 3: Script Wiring                          │
│  npm run test:gate = all 5 test files in order   │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│  PHASE 4: Secret Hygiene                         │
│  - No hardcoded secrets                          │
│  - .env in .gitignore                            │
│  - process.env for sensitive data                │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│  PHASE 5: Verification                           │
│  Gate Decision: PASS → Deploy, FAIL → Stop      │
└─────────────────────────────────────────────────┘

cm-test-gate: 5 Phases Chi Tiết

Phase 1: Stack Detection

  • Xác định công nghệ: Node.js, Express, SQLite, Vitest
  • Check package.json có đủ devDependencies: vitest, supertest, @testing-library/react

Phase 2: 4 Core Test Files

test/
├── frontend-safety.test.ts      (Layer 1: DOM-XSS, input validation)
├── api-routes.test.ts           (Layer 2: endpoints, status codes)
├── business-logic.test.ts        (Layer 3: logic, edge cases)
├── i18n-sync.test.ts            (Layer 4: key parity)
└── security-scan.test.ts        (Layer 5: hardcoded secrets)

Phase 3: Script Wiring

json
{
  "scripts": {
    "test:gate": "vitest run test/frontend-safety.test.ts test/api-routes.test.ts test/business-logic.test.ts test/i18n-sync.test.ts test/security-scan.test.ts"
  }
}

Phase 4: Secret Hygiene

  • Scan src/ cho /API_KEY\s*=\s*['"].*['"]/
  • Verify .gitignore có .env, .dev.vars
  • Verify no process.env.SECRET được print hoặc log

Phase 5: Verification

  • All 5 test files PASS?
  • Zero failures?
  • Evidence log created?

3 Iron Laws of cm-quality-gate

Law 1: NO DEPLOY without test:gate

if (test:gate !== PASS) {
  STOP
  throw new Error("Gate failed - do not deploy")
}

Law 2: NO CLAIMS without evidence

Claim: "This feature is ready"
Evidence: 
  - test:gate PASS ✓
  - All 5 layers verified ✓
  - Timestamp & git commit ✓

Law 3: NO FRAGILE FRONTEND

BAD: Inline style="color: red" + hardcoded user data
GOOD: Sanitized HTML + environment-driven styling

Anti-Patterns vs. Best Practices

❌ DON'T✅ DO
Deploy, then testTest, then deploy
"Tests passed yesterday"Run fresh NOW, every time
Skip tests for "small changes"Every change tested
Run test + deploy in parallelSequential: test → verify → deploy
Check code quality laterScan at commit time (pre-commit hook)
Trust previous env setupVerify env vars before deploy gate

Gate Function: IDENTIFY → RUN → READ → VERIFY → CLAIM

1. IDENTIFY
   ↓ What are we testing?
   ├─ Stack type?
   ├─ Test files present?
   └─ Test scripts wired?

2. RUN
   ↓ Execute all tests
   ├─ npm run test:gate
   └─ Capture exit code + output

3. READ
   ↓ Parse results
   ├─ Count failures
   ├─ Extract error messages
   └─ Check for warnings

4. VERIFY
   ↓ Validate evidence
   ├─ All 5 layers covered?
   ├─ No skipped tests?
   └─ Coverage adequate?

5. CLAIM
   ↓ Make gate decision
   ├─ PASS: "Safe to deploy"
   └─ FAIL: "Stop, fix issues"

II. Thực Hành (55 phút)

CHECKPOINT: Verify 5 Test Files Exist

Bước 1: Liệt kê test files

bash
cd /path/to/taskflow-app
ls -la test/

Expected:

-rw-r--r--  1 user staff   2.1K Apr 24 10:30 frontend-safety.test.ts
-rw-r--r--  1 user staff   1.8K Apr 24 10:31 api-routes.test.ts
-rw-r--r--  1 user staff   2.4K Apr 24 10:32 business-logic.test.ts
-rw-r--r--  1 user staff   1.9K Apr 24 10:33 i18n-sync.test.ts
-rw-r--r--  1 user staff   1.7K Apr 24 10:34 security-scan.test.ts

Bước 2: Kiểm Tra package.json có test:gate script

bash
grep "test:gate" package.json

Expected:

json
"test:gate": "vitest run test/frontend-safety.test.ts test/api-routes.test.ts test/business-logic.test.ts test/i18n-sync.test.ts test/security-scan.test.ts --reporter=verbose"

Bước 3: Chạy test:gate

bash
npm run test:gate 2>&1 | tee test-gate-output.log

Expected Output:

✓ test/frontend-safety.test.ts (234ms)
  ✓ should sanitize user input
  ✓ should prevent XSS attacks
  ✓ should validate form inputs

✓ test/api-routes.test.ts (456ms)
  ✓ GET /api/tasks returns 200
  ✓ POST /api/tasks validates body
  ✓ DELETE /api/tasks/:id returns 204

✓ test/business-logic.test.ts (345ms)
  ✓ Task.isOverdue() returns true for past dates
  ✓ Task.assignee validation works
  ✓ Task.priority enum constraints

✓ test/i18n-sync.test.ts (125ms)
  ✓ should have same keys in en.json and vi.json

✓ test/security-scan.test.ts (98ms)
  ✓ should not have hardcoded API keys in src/
  ✓ should have .env in .gitignore

Test Files  5 passed (5)
     Tests  15 passed (15)

Nếu FAIL, đọc error message và fix.


Practice 2: Gate Decision Discipline

Scenario: Deliberately break 1 test để học cách dừng lại khi gate fail.

Bước 1: Break một test

bash
# Thêm test sai intentionally
cat >> test/business-logic.test.ts << 'EOF'

it('should fail intentionally for learning', () => {
  expect(true).toBe(false); // Lỗi!
});
EOF

Bước 2: Chạy test:gate (Expect FAIL)

bash
npm run test:gate

Output:

✗ test/business-logic.test.ts (345ms)
  ✗ should fail intentionally for learning
  
AssertionError: expected true to be false
  at test/business-logic.test.ts:245:8

Test Files  4 passed, 1 failed (5)
     Tests  14 passed, 1 failed (15)

Exit Code: 1

Bước 3: STOP - Không Deploy!

┌─────────────────────────────────────────┐
│  🛑 GATE FAILED - DO NOT PROCEED       │
│                                         │
│  Exit code: 1                          │
│  Tests failed: 1 out of 15             │
│  Status: BLOCKED                       │
└─────────────────────────────────────────┘

Dùng script để enforce:

bash
#!/bin/bash
# scripts/test-gate-check.sh

npm run test:gate
EXIT_CODE=$?

if [ $EXIT_CODE -ne 0 ]; then
  echo "🛑 Test gate failed. Exit code: $EXIT_CODE"
  echo "Do not proceed with deployment."
  exit 1
fi

echo "✅ Test gate passed. Safe to deploy."
exit 0
bash
chmod +x scripts/test-gate-check.sh
./scripts/test-gate-check.sh

Bước 4: Fix lỗi

bash
# Xóa test sai
git checkout test/business-logic.test.ts

# Hoặc fix cái lỗi thực tế
# ...

Bước 5: Chạy lại (Expect PASS)

bash
npm run test:gate

Output:

Test Files  5 passed (5)
     Tests  15 passed (15)

✅ All gates passed. Ready for deployment.

Practice 3: Evidence Before Claims

Scenario: Tạo evidence log để prove claims.

Bước 1: Tạo evidence template

File: docs/evidence-log.md

markdown
# Test Gate Evidence Log

## Buổi 9: April 24, 2026 - 15:30 UTC

### Gate Status: PASS ✅

#### Test Execution

- **Date & Time**: 2026-04-24 15:30:42 UTC
- **Git Commit**: `abc1234` (Test Gate Assembly: All 5 layers verified)
- **Branch**: main
- **Node Version**: v20.10.0
- **npm Version**: 10.2.3

#### Test Results

| Layer | Test File | Status | Pass | Fail | Duration |
|-------|-----------|--------|------|------|----------|
| 1 | frontend-safety.test.ts | ✅ | 3 | 0 | 234ms |
| 2 | api-routes.test.ts | ✅ | 3 | 0 | 456ms |
| 3 | business-logic.test.ts | ✅ | 3 | 0 | 345ms |
| 4 | i18n-sync.test.ts | ✅ | 1 | 0 | 125ms |
| 5 | security-scan.test.ts | ✅ | 2 | 0 | 98ms |
| **TOTAL** | | **✅** | **12** | **0** | **1.258s** |

#### Test Output

\`\`\`
✓ test/frontend-safety.test.ts (234ms)
✓ test/api-routes.test.ts (456ms)
✓ test/business-logic.test.ts (345ms)
✓ test/i18n-sync.test.ts (125ms)
✓ test/security-scan.test.ts (98ms)

Test Files  5 passed (5)
     Tests  12 passed (12)
\`\`\`

#### Security Checklist

- [x] No hardcoded secrets in src/
- [x] .env in .gitignore
- [x] process.env for API_KEY
- [x] i18n keys in parity

#### QA Sign-off

**Tested By**: DevOps Bot  
**Approved By**: Lead Engineer  
**Timestamp**: 2026-04-24T15:30:42Z  
**Ticket**: TASKFLOW-42

---

## Claims Require Evidence Table

| Claim | Evidence | Source |
|-------|----------|--------|
| "Tests passed" | test:gate PASS, Exit code 0 | npm run test:gate |
| "No security issues" | security-scan.test.ts PASS | test/security-scan.test.ts |
| "i18n sync" | i18n-sync.test.ts PASS, parity verified | test/i18n-sync.test.ts |
| "Ready to deploy" | All 5 layers PASS + evidence log | This file |

---

## Previous Buổis Evidence

See also:
- Buổi 8: `docs/evidence-log.md` (i18n & security fixes)
- Buổi 7: `docs/evidence-log.md` (business logic layer)

Bước 2: Chạy test:gate và capture output

bash
npm run test:gate > test-output.txt 2>&1
EXIT_CODE=$?

# Append to evidence log
cat >> docs/evidence-log.md << EOF

## Buổi 9: $(date -u +"%Y-%m-%d %H:%M:%S UTC")

### Gate Status: $([ $EXIT_CODE -eq 0 ] && echo "PASS ✅" || echo "FAIL ❌")

\`\`\`
$(cat test-output.txt)
\`\`\`

EOF

cat docs/evidence-log.md

Bước 3: Kiểm Tra evidence log

bash
cat docs/evidence-log.md

Expected:

# Test Gate Evidence Log

## Buổi 9: 2026-04-24 15:30:42 UTC

### Gate Status: PASS ✅

Test Files  5 passed (5)
Tests  12 passed (12)

Claims Require Evidence Table
| Claim | Evidence | Source |
|-------|----------|--------|
| "Ready to deploy" | All 5 layers PASS | test:gate output |

III. CHECKPOINT: 5 Layers Running with 0 Failures

Verify trước khi kết thúc buổi:

bash
# 1. Check 5 test files
ls -1 test/*test.ts | wc -l
# Expected: 5

# 2. Check test:gate script
grep -c "test:gate" package.json
# Expected: 1

# 3. Run gate
npm run test:gate
# Expected: Exit code 0, all PASS

# 4. Check evidence log
[ -f docs/evidence-log.md ] && echo "✅ Log exists" || echo "❌ Missing"

# 5. Security check
grep -c "FAKE_API_KEY" src/server.js
# Expected: 0 (hardcoded key removed)

IV. Script: Automated Gate Check

File: scripts/pre-deploy.sh

bash
#!/bin/bash
set -e

echo "🏗️ Test Gate Assembly - Pre-Deployment Check"
echo "============================================="

# Phase 1: Stack Detection
echo "[1/5] Stack Detection..."
[ -f "package.json" ] || { echo "❌ No package.json"; exit 1; }
[ -d "test" ] || { echo "❌ No test/ directory"; exit 1; }
echo "✅ Stack detected: Node.js + Vitest"

# Phase 2: Core Test Files
echo "[2/5] Core Test Files..."
TEST_COUNT=$(find test -name "*.test.ts" | wc -l)
if [ "$TEST_COUNT" -ge 5 ]; then
  echo "✅ Found $TEST_COUNT test files"
else
  echo "❌ Only $TEST_COUNT test files (need 5)"
  exit 1
fi

# Phase 3: Script Wiring
echo "[3/5] Script Wiring..."
grep -q "test:gate" package.json || { echo "❌ No test:gate script"; exit 1; }
echo "✅ test:gate script found"

# Phase 4: Secret Hygiene
echo "[4/5] Secret Hygiene..."
SECRETS=$(grep -r "API_KEY\s*=\s*['\"].*['\"]" src/ || true)
if [ -z "$SECRETS" ]; then
  echo "✅ No hardcoded secrets"
else
  echo "❌ Found hardcoded secrets:"
  echo "$SECRETS"
  exit 1
fi

# Phase 5: Run Gate
echo "[5/5] Running Test Gate..."
npm run test:gate || { echo "❌ Test gate failed"; exit 1; }

echo ""
echo "✅ ALL GATES PASSED - Ready to deploy"
echo "$(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> docs/deployment-log.txt
exit 0

Chạy:

bash
chmod +x scripts/pre-deploy.sh
./scripts/pre-deploy.sh

V. Key Takeaways

5 Phases recap:

  1. Stack Detection - Verify tech stack
  2. 4 Core Test Files - Frontend, API, Logic, i18n, Security
  3. Script Wiring - npm run test:gate orchestrates all
  4. Secret Hygiene - No hardcodes, use process.env
  5. Verification - Evidence log, gate decision

3 Iron Laws:

  1. NO DEPLOY without test:gate → Exit code 0 required
  2. NO CLAIMS without evidence → Evidence log mandatory
  3. NO FRAGILE FRONTEND → Input validation + sanitization

Gate Decision:

if (npm run test:gate === 0) {
  DEPLOY ✅
} else {
  STOP ❌ Fix issues first
}

VI. Homework

  1. Ensure npm run test:gate passes on your local machine
  2. Create docs/evidence-log.md with current gate status
  3. Run scripts/pre-deploy.sh and capture output
  4. Commit evidence to git:
    bash
    git add docs/evidence-log.md
    git commit -m "Test Gate Assembly: All 5 layers PASS"
    git push
  5. Share evidence link in team Slack

Next Buổi: Real-world deployment scenarios & incident post-mortems.

Powered by CodyMaster × VitePress