การทดสอบและเครื่องมือ
ทำไม tooling ถึงสำคัญ
หัวข้อที่มีชื่อว่า “ทำไม tooling ถึงสำคัญ”การเขียนโค้ดเป็นเพียงครึ่งหนึ่งของงาน การรู้วิธีทดสอบ ดีบัก วัดผล และตั้งค่าสภาพแวดล้อม Node.js จะเปลี่ยนสคริปต์ที่ทำงานได้ให้กลายเป็นแอปพลิเคชันที่ดูแลรักษาง่ายและพร้อม production
Node 24 (LTS ตัวปัจจุบัน) มี test runner ในตัว, type stripping สำหรับไฟล์ .ts, inspector protocol ที่ทรงพลัง, และ perf_hooks สำหรับจับเวลา ซึ่งหมายความว่าคุณทำได้มากโดยไม่ต้องติดตั้งอะไรเพิ่มเติม
สาย release ของ Node ในปี 2026
หัวข้อที่มีชื่อว่า “สาย release ของ Node ในปี 2026”| สาย | สถานะ (ก.ย. 2026) | ใช้กับอะไร |
|---|---|---|
| Node 22 | Maintenance LTS (ถึง เม.ย. 2027) | แอป production ที่มีอยู่แล้ว — require(esm), type stripping ตั้งแต่ 22.18 |
| Node 24 | Active LTS (เป็น LTS ตั้งแต่ ต.ค. 2025) | แอป production ใหม่ — คอร์สนี้ยึดเวอร์ชันนี้ |
| Node 26 | Current (เป็น LTS ตั้งแต่ ต.ค. 2026) | ลอง Temporal, Iterator.concat(), Undici 8 |
Node 18 และ 20 หมดอายุ (end-of-life) แล้ว เมื่อบทเรียนบอกว่า “Node 22+” หมายถึงฟีเจอร์นั้นมีในทุกสายที่ยังรองรับ
สิ่งที่โมดูลนี้ครอบคลุม
หัวข้อที่มีชื่อว่า “สิ่งที่โมดูลนี้ครอบคลุม”| บทเรียน | หัวข้อ |
|---|---|
| Built-in Test Runner | node:test, node:assert, test(), describe/it, node --test |
| การดีบัก | node --inspect, Chrome DevTools, breakpoints, เมธอดต่าง ๆ ของ console |
| ประสิทธิภาพ | perf_hooks, performance.now(), PerformanceObserver, การหลีกเลี่ยงการบล็อก |
| Ecosystem และ Toolchain | TypeScript runners, ESLint/Prettier/Biome, nodemon, env files |
ภาพรวม toolchain
หัวข้อที่มีชื่อว่า “ภาพรวม toolchain”flowchart TB
subgraph Project["Your Node.js Project"]
direction TB
Source["Source code (.ts / .js / .mjs)"]
Lint["Linter / Formatter"]
TSR["TypeScript runner"]
TestRunner["Test runner"]
Debugger["Debugger"]
Perf["Performance"]
Source --> Lint --> TSR --> TestRunner --> Debugger --> Perf
end
Lint --> LintTools["ESLint, Prettier, Biome"]
TSR --> TSRTools["node file.ts (built-in type stripping); tsx for enum etc."]
TestRunner --> TestTools["node:test (built-in) or Vitest / Jest"]
Debugger --> DebuggerTools["node --inspect + Chrome DevTools"]
Perf --> PerfTools["perf_hooks, PerformanceObserver"] เลือกใช้อะไรดี
หัวข้อที่มีชื่อว่า “เลือกใช้อะไรดี”Built-in ของ Node ครอบคลุมความต้องการพื้นฐานได้เกือบทั้งหมด นี่คือแนวทางการตัดสินใจเบื้องต้น:
# Zero dependencies — use the built-in runnernode --test src/**/*.test.js
# TypeScript without a build step (Node 22.18+ / 24 — type stripping is on by default)node src/app.ts
# Run a package.json script without npm (Node 22+)node --run dev
# Faster HMR + watch modenpx tsx watch src/app.ts
# Lint + format in one tool (zero config)npx biome check --apply src/สิ่งที่มีอยู่แล้ว ไม่ต้องติดตั้งอะไรเพิ่ม
หัวข้อที่มีชื่อว่า “สิ่งที่มีอยู่แล้ว ไม่ต้องติดตั้งอะไรเพิ่ม”ทุกความสามารถที่โมดูลนี้ครอบคลุมมีอยู่ใน binary node ที่คุณมีอยู่แล้ว ลองเช็กจริงบน Node 24:
Output (verified on Node 24)
node:test available: true
perf_hooks available: true
global fetch available: true
type stripping (.ts files) is on by default on Node 24 -- no flag neededแบบจำลองความคิด (Mental Model)
หัวข้อที่มีชื่อว่า “แบบจำลองความคิด (Mental Model)”แต่ละบทในโมดูลนี้ตอบคำถามคนละมุมเกี่ยวกับ process ตัวเดียวกัน — มองเป็นเลนส์ 4 อันที่ส่องไปที่ node binary เดียวกัน ไม่ใช่เครื่องมือ 4 ชิ้นที่แยกจากกัน:
flowchart TB Q1["Is my code correct?"] -->|"node:test + node:assert"| L1["Built-in Test Runner"] Q2["Why did it do that?"] -->|"--inspect, console.*, uncaughtException"| L2["Debugging"] Q3["Is it fast enough?"] -->|"perf_hooks, --cpu-prof, worker_threads"| L3["Performance"] Q4["How do I run/ship it?"] -->|"--env-file, --watch, node --run, Docker"| L4["Ecosystem & Toolchain"] L1 --> Ship["Code you can trust in production"] L2 --> Ship L3 --> Ship L4 --> Ship
Trade-offs
หัวข้อที่มีชื่อว่า “Trade-offs”| ตัวเลือก | ข้อดี | ต้นทุน |
|---|---|---|
Built-in node:test / perf_hooks / --inspect | ไม่ต้องติดตั้ง ไม่มี config ที่ต่างกันไปในแต่ละเครื่อง ทำงานเหมือนกันทุกที่ที่มี Node | สะดวกน้อยกว่าเครื่องมือที่ ecosystem โตแล้ว (ไม่มี coverage UI, ไม่มี watch mode filter ให้ทันที) |
| Third-party (Vitest, ESLint, pino, tsx) | DX ดีกว่า, มี plugin ecosystem, มีฟีเจอร์ที่ Node ยังไม่ stabilize | ต้องติดตั้ง, pin เวอร์ชัน, ตรวจ audit และอัปเดตอยู่เสมอ — และ lockfile ที่ทุกคนต้องเชื่อใจ |
| เรียนรู้ built-in ก่อน | การดีบักโค้ดที่ AI เขียนหรือโค้ดที่ไม่คุ้นเคยไม่ต้องพึ่งว่า “repo นี้ใช้ test framework ตัวไหน” | ต้องพิมพ์มากกว่านิดหน่อยในสิ่งที่ framework จะให้เป็น syntax sugar (เช่น expect().toBe() เทียบกับ assert.equal()) |
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- “ต้องใช้ Jest หรือ Mocha ถึงจะเขียนเทสต์จริงจังใน Node ได้” — ความจริง:
node:testมีมาตั้งแต่ Node 18 และภายใน Node 24 ก็ครอบคลุมทั้ง mocking, fake timers, snapshot, และ coverage โดยไม่ต้องมี dependency แม้แต่ตัวเดียว - “TypeScript ต้องมี build step ถึงจะรันบน Node ได้” — ความจริง: Node 24 strip type annotation ตอนโหลดไฟล์เป็นค่าเริ่มต้น ต้องใช้
tsx/ts-node/tscเฉพาะ syntax ที่ต้อง แปลง (enum, decorator) ไม่ใช่แค่ลบทิ้ง - “perf_hooks / node —inspect / node:test เป็นของ experimental หรือไม่เสถียร” — ความจริง: ทั้งสามตัวเป็น API ที่ stable แล้ว มีแค่ฟีเจอร์ย่อยบางตัว (coverage, ส่วนเสริมบางอย่างของ test runner) ที่ยังต้องใช้ flag
--experimental-ซึ่งแต่ละบทจะระบุไว้ชัดเจน
อ่านโค้ดที่ AI เขียน
หัวข้อที่มีชื่อว่า “อ่านโค้ดที่ AI เขียน”- โค้ดที่ AI เขียนเรียกใช้
jest/mocha/chaiเป็น dependency สำหรับงานที่node:test+node:assertทำได้อยู่แล้วหรือไม่? นี่ไม่ใช่บั๊ก แต่เป็นสัญญาณว่าโค้ดที่ถูกสร้างมาไม่ได้คิดถึง Node 24 - มีการเพิ่ม
ts-nodeหรือ bundler สำหรับไฟล์.tsธรรมดาที่มีแค่ type annotation (ไม่มีenum, ไม่มี decorator) หรือไม่?node file.tsทำงานได้อยู่แล้วโดยไม่ต้องมีสิ่งเหล่านั้น - มีการเรียก Node built-in ที่อยู่หลัง flag
--experimental-(test coverage, module mocks) โดยไม่พูดถึง flag หรือ warning ที่มันพิมพ์ออกมาหรือไม่? ถ้ารันโค้ดตามที่แสดงจะ crash หรือทำงานแบบเงียบ ๆ ไม่ได้ผล
🐛 หา bug ในโค้ดนี้
import { test } from 'node:test';import assert from 'node:assert/strict';
// package.json: "test": "node --test"test('creates a user', async function() {const user = await createUser({ name: 'Ada' });assert.equal(user.name, 'Ada');});
test.only('debugging this one locally', function() {assert.ok(true);});เฉลย
test.only ทำเครื่องหมายเทสต์เดียวให้รันแบบเฉพาะเจาะจง — แต่จะมีผลจริงก็ต่อเมื่อรันตัวรันด้วย --test-only (หรือ run({ only: true })) เท่านั้น script ใน package.json ข้างบนเป็น node --test ธรรมดา ดังนั้นถ้าไม่มี --test-only ทั้งสองเทสต์ก็ยังรันตามปกติ .only ไม่มีผลอะไรเลย และดูเผิน ๆ ก็ไม่มีอะไรผิดปกติในเครื่อง อันตรายที่แท้จริงคือสถานการณ์ตรงข้าม: CI script ที่ใส่ --test-only ไว้ตลอดเวลา ถ้าลืมลบ test.only หลังจาก debug เสร็จแล้ว push ขึ้นไป จะทำให้เทสต์อื่นทั้งหมดในไฟล์นั้นถูกข้ามไปแบบเงียบ ๆ ตลอดกาล — และ CI ก็ยังเขียวอยู่ทั้งที่ regression ในเทสต์ที่ถูกข้ามไม่เคยถูกจับได้เลย ให้ค้นหา .only ในไฟล์เทสต์ก่อน commit ทุกครั้ง หรือตั้ง lint ให้จับมัน