ข้ามไปยังเนื้อหา

การทดสอบและเครื่องมือ

การเขียนโค้ดเป็นเพียงครึ่งหนึ่งของงาน การรู้วิธีทดสอบ ดีบัก วัดผล และตั้งค่าสภาพแวดล้อม Node.js จะเปลี่ยนสคริปต์ที่ทำงานได้ให้กลายเป็นแอปพลิเคชันที่ดูแลรักษาง่ายและพร้อม production

Node 24 (LTS ตัวปัจจุบัน) มี test runner ในตัว, type stripping สำหรับไฟล์ .ts, inspector protocol ที่ทรงพลัง, และ perf_hooks สำหรับจับเวลา ซึ่งหมายความว่าคุณทำได้มากโดยไม่ต้องติดตั้งอะไรเพิ่มเติม

สายสถานะ (ก.ย. 2026)ใช้กับอะไร
Node 22Maintenance LTS (ถึง เม.ย. 2027)แอป production ที่มีอยู่แล้ว — require(esm), type stripping ตั้งแต่ 22.18
Node 24Active LTS (เป็น LTS ตั้งแต่ ต.ค. 2025)แอป production ใหม่ — คอร์สนี้ยึดเวอร์ชันนี้
Node 26Current (เป็น LTS ตั้งแต่ ต.ค. 2026)ลอง Temporal, Iterator.concat(), Undici 8

Node 18 และ 20 หมดอายุ (end-of-life) แล้ว เมื่อบทเรียนบอกว่า “Node 22+” หมายถึงฟีเจอร์นั้นมีในทุกสายที่ยังรองรับ

บทเรียนหัวข้อ
Built-in Test Runnernode:test, node:assert, test(), describe/it, node --test
การดีบักnode --inspect, Chrome DevTools, breakpoints, เมธอดต่าง ๆ ของ console
ประสิทธิภาพperf_hooks, performance.now(), PerformanceObserver, การหลีกเลี่ยงการบล็อก
Ecosystem และ ToolchainTypeScript runners, ESLint/Prettier/Biome, nodemon, env files
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"]
toolchain ของโปรเจกต์ Node.js: source code ไหลผ่าน linter, TypeScript runner, test runner, debugger, และเครื่องมือวัดประสิทธิภาพ

Built-in ของ Node ครอบคลุมความต้องการพื้นฐานได้เกือบทั้งหมด นี่คือแนวทางการตัดสินใจเบื้องต้น:

Terminal window
# Zero dependencies — use the built-in runner
node --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 mode
npx tsx watch src/app.ts
# Lint + format in one tool (zero config)
npx biome check --apply src/

ทุกความสามารถที่โมดูลนี้ครอบคลุมมีอยู่ใน binary node ที่คุณมีอยู่แล้ว ลองเช็กจริงบน Node 24:

Node.js
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

แต่ละบทในโมดูลนี้ตอบคำถามคนละมุมเกี่ยวกับ 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
คำถามสี่ข้อเกี่ยวกับ process เดียวกัน: ถูกต้อง, ดีบักได้, เร็วพอ, ส่งขึ้น production ได้
ตัวเลือกข้อดีต้นทุน
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 เขียนเรียกใช้ 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 ให้จับมัน

Node.js เวอร์ชันไหนที่แนะนำ built-in node:test runner เป็นครั้งแรก?
โมดูล built-in ใดที่ใช้วัดเวลาการทำงานใน Node.js?
บน Node 24 รันไฟล์ TypeScript โดยตรงโดยไม่ต้อง build ได้อย่างไร?
โค้ดนี้พิมพ์อะไรบน Node 24? import { test } from 'node:test'; console.log(typeof test);
CI script รันด้วย node --test --test-only นักพัฒนาลืมลบ test.only(...) ไว้ในเทสต์หนึ่งตัวหลัง debug เสร็จแล้ว push ขึ้นไป จะเกิดอะไรขึ้น?
ทำไมโมดูลนี้ถึงสอน node:test / --inspect / perf_hooks ก่อนพูดถึงเครื่องมือ third-party ใด ๆ?