ทดสอบ MCP Server อัตโนมัติ 4 ชั้น จาก Unit Test ถึง CI พร้อมตัวอย่างจริง
โดย Nokka (นก-กา) | 23 กันยายน 2026
บทความนี้เขียนโดย AI (โมเดล glm-5.3 ของผู้ให้บริการ ollama-cloud) ผ่าน Hermes Agent จาก Nous Research ตรวจสอบและเรียบเรียงโดย Nokka
ปีนี้ผมเขียน MCP server หลายตัว และคำถามที่เจอบ่อยที่สุดจากคนที่เริ่มเล่นสายนี้คือ จะทดสอบยังไง ปัญหามันต่างจากเว็บแอปทั่วไป เพราะ MCP server มีสองชั้นที่ต้องตรวจพร้อมกัน คือชั้นโปรโตคอลที่คุยกับ client ตามกติกา กับชั้นตรรกะเครื่องมือที่ทำงานจริง รวมถึงชั้นที่สามที่คนมักลืมคือพฤติกรรมของ LLM ที่มาเรียกใช้ [1]
ผมรวบรวมแนวทางที่มีอยู่จริงในระบบนิเวศตอนนี้ ทั้งจากเครื่องมือทางการของโครงการ MCP เอง และแนวปฏิบัติที่ทีมพัฒนาใช้กันจริง จัดเป็นพีระมิดสี่ชั้นที่ไล่จากเร็วไปช้า แต่ละชั้นจับคนละประเภทของบั๊ก
ชั้นที่ 1 · Unit test ด้วย SDK ตรง ๆ เร็วที่สุด
ชั้นแรกคือการทดสอบตรรกะของเครื่องมือโดยไม่ต้องเปิดเซิร์ฟเวอร์จริง ทั้ง Python และ TypeScript SDK มีวิธีเชื่อม client กับ server ในหน่วยความจำเดียวกันโดยตรง
สำหรับ Python ตัวอย่างจากเอกสารทางการของ SDK เองใช้วิธีสร้าง client ครอบ object ของ server แล้วเรียกเครื่องมือผ่านมันได้เลย โดยตั้งค่าให้ exception ลอกขึ้นมาตรง ๆ เพื่อให้เทสตรวจจับ error ได้ง่าย [1]
from mcp import Client
async with Client(mcp, raise_exceptions=True) as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
# ผลลัพธ์เป็น CallToolResult ที่มี content และ structured_content
ฝั่ง TypeScript ใช้แนวคิดเดียวกันผ่าน InMemoryTransport ที่ SDK ทำคู่การเชื่อมต่อให้เอง ในเวอร์ชัน 2 โมดูลนี้ย้ายไปอยู่ในแพ็กเกจ client แล้ว ตามเอกสารทางการ [2]
import { InMemoryTransport } from '@modelcontextprotocol/client';
const [clientEnd, serverEnd] = InMemoryTransport.createLinkedPair();
await client.connect(clientEnd);
await server.connect(serverEnd);
ข้อดีคือเร็วมาก ไม่มี network ไม่มี subprocess และยังทดสอบ serialization กับ schema ได้จริง ข้อจำกัดคือไม่ครอบคลุมชั้น transport อย่าง stdio หรือ HTTP เลย ต้องมีชั้นถัดไปเสริม ข้อควรระวังสำหรับคนใช้ Python คือแพ็กเกจหลักเพิ่งอัปเดตใหญ่เมื่อปลายเดือนกรกฎาคม เปลี่ยนชื่อคลาสหลักจาก FastMCP เป็น MCPServer และถอด helper บางตัวออก โค้ดเก่าที่หยิบมาจากบทความเก่าอาจรันไม่ได้แล้ว [1]
ชั้นที่ 2 · Smoke test ผ่านหน้าจริงด้วย MCP Inspector
ถ้าอยากทดสอบแบบเปิดเซิร์ฟเวอร์จริง เครื่องมือทางการคือ MCP Inspector ซึ่งนอกจากหน้าจอให้คนลองกดแล้ว ยังมีโหมด command line ที่รันแบบไม่มีหน้าจอได้ ซึ่งเป็นความลับที่คนไม่ค่อยรู้ [3]
npx --yes @modelcontextprotocol/inspector@2.5.0 --cli node build/index.js \
--method tools/list --format json | \
jq -e '.result.tools | map(.name) | index("my_tool")'
คำสั่งนี้ถามชื่อ server ให้รันแล้วเรียกดูรายชื่อเครื่องมือ ถ้ามีเครื่องมือที่เราคาดหวังคำสั่งจะคืนสถานะสำเร็จ ไม่มีก็พังทันที เหมาะเป็นด่านแรกของ pipeline ตรวจว่า server ยังมีชีวิตและเปิดเผยเครื่องมือครบ
เหตุผลที่มันใช้ใน CI ได้จริงคือระบบ exit code ที่กำหนดไว้ชัดเจน
ชั้นที่ 3 · Conformance ตรวจกติกาโปรโตคอล
ชั้นที่สามตอบคำถามว่า server ของเราเวอร์ชันใหม่นี้ยังเล่นตามกติกา MCP ครบถ้วนไหม โครงการมีชุดทดสอบ conformance ทางการที่วัดการทำงานตามสเปก ทั้งการประกาศความสามารถ การจัดการ schema และการตอบสนองตามรูปแบบ [4]
ของใหม่ที่ทำให้ชั้นนี้เข้า pipeline ได้สะดวกคือ GitHub Action ทางการที่เรียกใช้ชุดทดสอบนี้ได้ตรง ๆ ในไฟล์ workflow ซึ่งทีมดูแล SDK ทางการของ Python และ Kotlin เองก็ใช้จริงใน repository ของตัวเอง [4]
- uses: modelcontextprotocol/conformance@v0.1.11
with:
mode: server
url: http://localhost:3001/mcp
suite: active
การเห็นทีมทางการใช้เครื่องมือของตัวเองเป็นสัญญาณที่ดี เพราะแปลว่า workflow นี้ถูกบำรุงรักษาต่อเนื่อง ไม่ใช่ของโชว์
ชั้นที่ 4 · ทดสอบว่า AI เรียกใช้ถูกต้อง
ชั้นสุดท้ายเป็นของที่ทดสอบยากที่สุด คือคุณภาพของการทำงานร่วมกับโมเดลจริง เครื่องมือของ server เราอาจถูกเรียกด้วยพารามิเตอร์ผิด ถูกเรียกตอนไม่ควรเรียก หรือ description ที่เขียนไว้ทำให้โมเดลเข้าใจผิด แนวทางที่ใช้กันคือให้ LLM ทดสอบ LLM โดยป้อนโจทย์จริงแล้วดูว่าโมเดลเลือกเครื่องมือถูกไหม ทำซ้ำหลายรอบแล้วดูอัตราความสำเร็จเชิงสถิติ [5]
นี่คือชั้นที่ทำให้ระบบนิเวศมีเครื่องมือฝั่งชุมชนเกิดขึ้นมารองรับ เช่น SDK ที่ช่วยเขียนแบบทดสอบที่มีโมเดลอยู่ในวงจร หรือตัวช่วยแบบ Jest สำหรับคนถนัดชุดเครื่องมือเดิม [6] ผมมองว่าสำหรับทีมส่วนใหญ่ ชั้นนี้คุ้มค่าหลังจากสามชั้นแรกเสถียรแล้ว เพราะค่าใช้จ่ายต่อรอบสูงและผลลัพธ์เป็นเชิงสถิติไม่ใช่คำตอบตายตัว
กับดักที่เจอบ่อยจากประสบการณ์รวบรวม
สามข้อนี้ทีมต่าง ๆ รายงานซ้ำ ๆ จนกลายเป็นบทเรียนคลาสสิกของงานสายนี้ [5]
สามกับดักที่ต้องจำ
ข้อแรก เครื่องมือที่ทำงานพังจะไม่ throw exception ตามสัญชาติของโค้ด แต่คืนค่า isError ที่ฝังอยู่ในผลลัพธ์ที่สำเร็จทางโปรโตคอล การทดสอบที่หวัง exception จะผ่านทั้งที่ของพัง ต้องเช็กฟิลด์นี้ทุกครั้ง
ข้อสอง ถ้า server ใช้ transport แบบ stdio การพิมพ์ข้อมูลออกทาง stdout ปกติจะทำให้ stream พังทั้งบรรทัด เพราะโปรโตคอลใช้ช่องทางนี้สื่อสาร ทุก log ต้องส่งไปทาง stderr เท่านั้น
ข้อสาม schema ของ input กับตรรกะจริงมักเติบโตไม่พร้อมกันจนเกิดช่องว่าง การเพิ่มพารามิเตอร์ในโค้ดแต่ลืมอัปเดต inputSchema ทำให้โมเดลส่งคำขอแบบที่ handler ไม่รู้จัก ชั้นทดสอบที่หนึ่งกับสามช่วยกันจับปัญหานี้ได้ดีที่สุด
ประกอบทั้งหมดเป็น pipeline เดียว
วิธีที่ผมแนะนำให้ทีมเริ่มต้นคือไล่ทีละชั้น อย่างประหยัดเวลา เริ่มจาก unit test ด้วย SDK ให้ครอบตรรกะหลัก ต่อด้วย Inspector CLI เป็นด่าน smoke test ใน CI แล้วค่อยเพิ่ม conformance เมื่อเริ่มมีผู้ใช้ภายนอก และปิดท้ายด้วยการวัดคุณภาพการเรียกใช้ด้วยโมเดลจริงเมื่อระบบนิเวศของ server เติบโตพอ
ข้อดีของช่วงเวลานี้คือเครื่องมือทั้งสามชั้นแรกเป็นของทางการหมด ไม่ต้องพึ่งของชุมชนที่อาจเลิกดูแล ทีมที่เขียนโปรโตคอลเองก็ใช้ workflow แบบเดียวกันนี้ใน repository ของตัวเอง จึงมั่นใจได้ว่าแนวทางนี้จะไม่กลายเป็นของล้าสมัยในเร็ววัน [1][3][4]
อ้างอิง:
[1] Model Context Protocol. "Testing - MCP Python SDK." py.sdk.modelcontextprotocol.io, 2026. https://py.sdk.modelcontextprotocol.io/get-started/testing/
[2] Model Context Protocol. "TypeScript SDK." github.com, 2026. https://github.com/modelcontextprotocol/typescript-sdk
[3] Model Context Protocol. "Inspector CLI smoke testing." github.com, 2026. https://github.com/modelcontextprotocol/inspector/blob/main/docs/cli-smoke-testing.md
[4] Model Context Protocol. "Conformance testing framework." github.com, 2026. https://github.com/modelcontextprotocol/conformance
[5] AgentCat. "Writing unit tests for MCP servers." agentcat.com, 2026. https://agentcat.com/guides/writing-unit-tests-mcp-servers/
[6] MCPJam. "MCPJam SDK documentation." docs.mcpjam.com, 2026. https://docs.mcpjam.com/sdk

Top comments (0)