หากคุณมี OpenAPI หรือ GraphQL schema, Schemathesis สามารถเปลี่ยน schema นั้นให้เป็นชุดทดสอบจำนวนมากได้โดยไม่ต้องเขียน assertion เองทุกเคส เครื่องมือนี้อ่านสเปก สร้างอินพุตตาม constraint ยิงคำขอไปยัง API ที่รันอยู่ และรายงานจุดที่ response ขัดกับสัญญา บทความนี้สรุปวิธีติดตั้ง รัน ใช้งานใน CI และวาง Schemathesis ร่วมกับการทดสอบเชิงฟังก์ชันและ การทดสอบสัญญา (contract testing) ใน Apidog
Schemathesis คืออะไร?
Schemathesis เป็นเครื่องมือโอเพนซอร์สบน Python สำหรับสร้างการทดสอบ API จาก schema โดยตรง คุณชี้ไปที่ OpenAPI หรือ GraphQL definition แล้ว Schemathesis จะสร้าง test cases จาก type, format, required field, enum, minimum/maximum และ constraint อื่น ๆ ที่ประกาศไว้ในสเปก
Schemathesis สร้างบน Hypothesis ซึ่งเป็นไลบรารี property-based testing สำหรับ Python และเผยแพร่ภายใต้ใบอนุญาต MIT
หลักการใช้งานคือ:
- ใช้ schema เป็น source of truth
- สร้าง request จาก schema
- ส่ง request ไปยัง API จริง
- ตรวจสอบว่า response ตรงกับ schema หรือไม่
- รายงานเคสที่ทำให้ API ล่มหรือผิดสัญญา
ตัวอย่างปัญหาที่มักเจอ:
- API ตอบ
500จาก input ที่ควรถูกจัดการเป็น4xx - response body ไม่ตรงกับ schema
- status code ไม่ได้ประกาศไว้ใน OpenAPI
- content type ไม่ตรงกับที่สเปกระบุ
- workflow แบบหลายขั้นตอนทำให้ state ผิดพลาด
คุณสามารถรันผ่าน CLI ด้วยคำสั่ง schemathesis run หรือชื่อย่อ st run และถ้าต้องการผูกกับ test suite เดิม ก็สามารถใช้งานร่วมกับ pytest ได้เช่นกัน
Property-Based Testing คืออะไร?
การทดสอบ API แบบทั่วไปมักเป็น example-based testing:
POST /users
Content-Type: application/json
{
"email": "user@example.com",
"age": 30
}
จากนั้นคุณ assert response ที่คาดไว้ เช่น 201 Created หรือ field บางตัวใน JSON วิธีนี้ดีสำหรับ business case ที่รู้ล่วงหน้า แต่ครอบคลุมเฉพาะเคสที่คุณเขียนเอง
property-based testing เปลี่ยนจากการเขียนตัวอย่างตายตัวเป็นการนิยาม “คุณสมบัติที่ควรเป็นจริงเสมอ” แล้วให้เครื่องมือสร้าง input จำนวนมากเพื่อหาทางทำลายคุณสมบัตินั้น
สำหรับ Schemathesis property หลักคือ:
request ที่ถูกต้องตาม schema ไม่ควรทำให้ server ล่ม และ response ต้องไม่ละเมิด schema
ตัวอย่างเช่น หาก OpenAPI ระบุว่า field หนึ่งเป็น integer และมี minimum: 1 Schemathesis อาจลองค่าอย่าง:
1- ค่าขอบเขต
- ตัวเลขขนาดใหญ่
- payload ที่ถูกต้องตาม schema แต่กดดัน validation logic
- ลำดับ request ที่ทำให้ state ผิดพลาด
เมื่อเจอ failure, Hypothesis จะ “ย่อ” input ให้เล็กที่สุดเท่าที่ทำให้ bug เกิดซ้ำได้ คุณจึงได้ repro case ที่อ่านง่าย ไม่ใช่ payload สุ่มขนาดใหญ่
สิ่งนี้ต่างจาก Monkey Testing เพราะ monkey testing มักโยน input แบบสุ่มเข้าระบบ ส่วน property-based testing ใช้ schema เป็นตัวกำหนดขอบเขต input และรู้ว่าผลลัพธ์ควรสอดคล้องกับอะไร
ติดตั้ง Schemathesis
Schemathesis เป็น Python package ดังนั้นต้องมี Python 3 และ pip
ติดตั้งด้วย:
pip install schemathesis
ตรวจสอบว่า CLI ใช้งานได้:
st --version
หรือ:
schemathesis --version
ถ้าคุณใช้ uv และไม่ต้องการติดตั้งถาวร สามารถรันผ่าน:
uvx schemathesis --version
รัน Schemathesis กับ OpenAPI URL
หาก API ของคุณ expose OpenAPI schema ผ่าน URL เช่น /openapi.json ให้รันได้ทันที:
st run http://127.0.0.1:8000/openapi.json
Schemathesis จะอ่าน schema, ค้นหา operations ทั้งหมด และยิง request ไปยัง server ตาม base URL ที่ระบุใน schema
ถ้าต้องการดู option ทั้งหมดของเวอร์ชันที่ติดตั้ง:
st run --help
ควรตรวจสอบ help ของเวอร์ชันจริงเสมอ เพราะชื่อ flag และค่า default อาจเปลี่ยนระหว่าง major version
รันกับ schema ที่อยู่ในไฟล์
ถ้า schema อยู่ในเครื่อง เช่น openapi.yaml หรือ openapi.json ให้ส่ง path ของไฟล์และกำหนด URL ของ API จริงด้วย --url
st run ./openapi.yaml --url http://127.0.0.1:8000
ตัวอย่างโครงสร้างโปรเจกต์:
my-api/
├── openapi.yaml
├── src/
└── tests/
รันจาก root ของโปรเจกต์:
st run ./openapi.yaml --url http://localhost:3000
รันกับ API ที่ต้องใช้ Authorization
ถ้า API ต้องมี token ให้ส่ง header เข้าไป:
st run http://127.0.0.1:8000/openapi.json \
--header 'Authorization: Bearer your-token'
หรือถ้าต้องใช้หลาย header:
st run ./openapi.yaml \
--url http://127.0.0.1:8000 \
--header 'Authorization: Bearer your-token' \
--header 'X-Tenant-ID: demo'
แนวทางที่ใช้จริงใน CI คือเก็บ token ใน environment variable:
st run ./openapi.yaml \
--url "$API_BASE_URL" \
--header "Authorization: Bearer $API_TOKEN"
อ่านผลลัพธ์จาก Schemathesis
เมื่อเจอ failure, Schemathesis จะพิมพ์ข้อมูลที่ใช้ reproduce ได้ เช่น:
- HTTP method
- endpoint
- query/path/body ที่ส่งไป
- header ที่เกี่ยวข้อง
- status code ที่ได้
- error message
- response validation error
แนวทางการ debug:
- copy request ที่ Schemathesis รายงาน
- replay ด้วย
curl, Postman, Apidog หรือ client ที่คุณใช้ - ตรวจสอบว่า bug อยู่ที่ implementation หรือ schema
- แก้ code หรือแก้ OpenAPI spec
- รัน
st runซ้ำ
ถ้า response ผิด schema อย่ารีบแก้ test ก่อน ให้เช็กก่อนว่า:
- schema เก่ากว่า implementation หรือไม่
- implementation ส่ง field เกิน/ขาดหรือไม่
- status code นั้นควรถูกเพิ่มใน OpenAPI หรือไม่
- error response format ถูกประกาศไว้ครบหรือยัง
สิ่งที่ Schemathesis ตรวจจับได้
| ปัญหา | ลักษณะที่พบ |
|---|---|
| Server error | request ทำให้เกิด 500 แทนที่จะเป็น response ที่จัดการแล้ว เช่น 400
|
| Schema violation | response body ไม่ตรงกับ schema ของ status code นั้น |
| Status code mismatch | API ตอบ status code ที่ไม่ได้ประกาศในสเปก |
| Content-type mismatch | response content type ไม่ตรงกับ OpenAPI |
| Stateful bug | endpoint เดี่ยวผ่าน แต่ล้มเหลวเมื่อเรียงเป็น workflow หลายขั้นตอน |
ตัวอย่างเช่น API อาจผ่านเมื่อทดสอบ GET /users/{id} อย่างเดียว แต่เมื่อรัน workflow แบบ:
POST /usersPATCH /users/{id}GET /users/{id}DELETE /users/{id}
อาจพบว่า state หลัง PATCH ไม่ถูกต้อง หรือ GET ส่ง response ที่ไม่ตรง schema
Schemathesis รองรับ stateful testing โดยอาศัยข้อมูลในสเปก เช่น link ระหว่าง operation เพื่อสร้างลำดับ request แบบ state machine
ปรับแต่งด้วย Hooks
ใน API จริง มักมีเงื่อนไขที่ schema อธิบายได้ไม่ครบ เช่น:
- ต้องมี tenant เฉพาะ
- ต้อง login ก่อน
- field บางตัวต้องสัมพันธ์กับข้อมูลในระบบ
- endpoint บางกลุ่มยังไม่พร้อมให้ fuzz
Schemathesis มี hooks ซึ่งเป็น Python function สำหรับปรับแต่งพฤติกรรม เช่น:
- กรอง operation ที่จะทดสอบ
- ปรับข้อมูลที่ generate
- เพิ่ม custom checks
- เพิ่ม header หรือ context เฉพาะระบบ
แนวคิดคือใช้ schema เป็นฐาน แล้วเติม logic ที่จำเป็นสำหรับระบบจริงผ่าน hook แทนการแก้ schema ให้ผิดความหมาย
เพิ่ม Schemathesis เข้า CI
ตัวอย่าง GitHub Actions แบบง่าย:
name: schemathesis
on:
pull_request:
push:
branches:
- main
jobs:
api-fuzzing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Schemathesis
run: pip install schemathesis
- name: Run API server
run: |
# แทนที่ด้วยคำสั่ง start API ของโปรเจกต์คุณ
python -m my_api &
sleep 5
- name: Run Schemathesis
run: |
st run ./openapi.yaml --url http://127.0.0.1:8000
สำหรับ API ที่ต้องใช้ secret:
- name: Run Schemathesis
env:
API_TOKEN: ${{ secrets.API_TOKEN }}
run: |
st run ./openapi.yaml \
--url http://127.0.0.1:8000 \
--header "Authorization: Bearer $API_TOKEN"
เริ่มจากรันกับ environment ที่ควบคุมได้ก่อน เช่น local test server หรือ staging ที่ใช้ข้อมูลทดสอบ ไม่ควรยิง fuzzing ใส่ production โดยตรงถ้ายังไม่ได้จำกัด scope และ rate ให้ชัดเจน
ควรใช้ Schemathesis เมื่อใด?
Schemathesis เหมาะเมื่อคุณมี OpenAPI หรือ GraphQL schema ที่ค่อนข้างแม่น และต้องการเพิ่ม coverage สำหรับ edge cases โดยไม่ต้องเขียน test case เองจำนวนมาก
เหมาะเป็นพิเศษเมื่อ:
- คุณดูแล OpenAPI specification และต้องการตรวจว่า server ทำตามจริง
- คุณต้องการจับ
500ที่ไม่ได้จัดการ - API มี workflow แบบ stateful
- ต้องการเพิ่ม fuzzing layer ใน CI
- ทีมใช้ Python,
pipหรือpytestอยู่แล้ว
ไม่เหมาะถ้า:
- schema ไม่ละเอียด
- schema ล้าสมัย
- response schema ไม่ได้ประกาศ error format ไว้ชัดเจน
- ต้องการตรวจ business logic เฉพาะเคส เช่น ส่วนลดคำนวณถูกหรือไม่
Schemathesis ไม่ได้แทนที่ functional tests เพราะการรู้ว่า API “ไม่ล่ม” ไม่เท่ากับการรู้ว่า API “คำนวณถูกต้อง” คุณยังต้องมี test แบบ example-based สำหรับ business behavior ที่สำคัญ
Schemathesis และ Apidog: ใช้ร่วมกันอย่างไร
Apidog และ Schemathesis แก้คนละปัญหา
Apidog เป็นแพลตฟอร์มสำหรับออกแบบ ดีบัก ทดสอบ mock และสร้างเอกสาร API ส่วน Schemathesis เป็น property-based fuzzer ที่ใช้ schema เพื่อสร้าง request จำนวนมากและตรวจว่า API ทำตามสัญญาหรือไม่
Apidog ไม่ได้ทำ property-based fuzzing ฟีเจอร์ที่ใกล้เคียงคือ monkey testing ซึ่งส่ง input แบบสุ่มเพื่อหา error แต่ไม่เหมือน Schemathesis ที่ generate input จาก constraint ใน schema และ validate response กลับกับ schema
ตารางนี้ช่วยแบ่งหน้าที่ให้ชัดเจน:
| ขั้นตอนของเวิร์กโฟลว์ | Schemathesis | Apidog |
|---|---|---|
| Property-based fuzzing จากสเปก | ใช่ เป็นฟีเจอร์หลัก | ไม่ |
| ออกแบบ API และแก้ไขสเปกแบบ visual | ไม่ | ใช่ |
| Functional API testing แบบ example-based | จำกัด | ใช่ |
| Contract testing เทียบกับสเปก | บางส่วน ผ่าน schema validation | ใช่ มี workflow เฉพาะ |
| Mock server จาก schema | ไม่ | ใช่ |
| CI test runner | ใช่ st run
|
ใช่ apidog run
|
| เอกสาร API ที่สร้างอัตโนมัติ | ไม่ | ใช่ |
workflow ที่ใช้งานได้จริง:
- ออกแบบและดูแล OpenAPI spec ใน Apidog
- สร้าง functional test cases สำหรับ business flow หลัก
- สร้าง mock server เพื่อให้ frontend หรือ consumer ทดสอบได้เร็วขึ้น
- รัน test เหล่านั้นใน CI ด้วย
apidog run - เพิ่ม Schemathesis เพื่อ fuzz schema เดียวกัน
- ใช้ failure จาก Schemathesis เพื่อแก้ implementation หรือปรับ schema ให้ตรงจริง
ผลลัพธ์คือคุณได้ test สองชั้น:
- Apidog ตรวจว่า API ทำงานถูกต้องในเคสที่รู้ล่วงหน้า
- Schemathesis ค้นหา edge cases ที่คุณอาจไม่ได้เขียนเอง
ถ้าเป้าหมายคือเปลี่ยนสเปกให้เป็นชุดทดสอบที่รันได้ ไม่ใช่ fuzzing อย่างเดียว Apidog สามารถ สร้างชุดการทดสอบ API จาก OpenAPI specs ของคุณได้โดยตรง และคุณสามารถ ดาวน์โหลด Apidog เพื่อลอง workflow นี้ได้
คำถามที่พบบ่อย
Schemathesis ฟรีหรือไม่?
ฟรี Schemathesis เป็นโอเพนซอร์สภายใต้ใบอนุญาต MIT และ CLI สามารถติดตั้งได้ด้วย:
pip install schemathesis
เครื่องมือหลักที่ใช้รันในเครื่องหรือใน CI ไม่มีค่าใช้จ่าย นอกจากนี้ยังมีบริการเชิงพาณิชย์แบบโฮสต์สำหรับทีมที่ต้องการประสบการณ์แบบ managed
schemathesis run กับ st run ต่างกันอย่างไร?
ไม่ต่างกัน st เป็นชื่อย่อของ schemathesis
สองคำสั่งนี้ทำงานเหมือนกัน:
schemathesis run ./openapi.yaml --url http://localhost:8000
st run ./openapi.yaml --url http://localhost:8000
ใช้แบบที่ทีมคุณอ่านง่ายและใส่ใน CI ได้สะดวก
Schemathesis แทนที่ functional API tests ได้ไหม?
ไม่ได้ และไม่ควรใช้แทนกัน
Schemathesis ตรวจว่า API ไม่ล่มและ response ไม่ขัดกับ schema แต่ไม่ได้ตรวจ business logic เฉพาะ เช่น:
- ส่วนลดคำนวณถูกหรือไม่
- สิทธิ์ผู้ใช้ถูกใช้ตาม policy หรือไม่
- workflow ทางธุรกิจให้ผลลัพธ์ตรงตาม requirement หรือไม่
สำหรับกรณีเหล่านี้ คุณยังต้องใช้ functional tests และ การทดสอบสัญญา (contract testing) แบบ example-based ซึ่งสามารถสร้างและรันใน Apidog ได้
ให้มอง Schemathesis เป็น fuzzing layer เพิ่มเติม ไม่ใช่ตัวแทน test suite เดิม
Schemathesis ใช้กับ GraphQL ได้หรือไม่?
ได้ Schemathesis รองรับทั้ง OpenAPI และ GraphQL schemas สำหรับ GraphQL เครื่องมือจะสร้าง query จาก type definition ใน schema และตรวจ response ในแนวทางเดียวกับ REST API ที่กำหนดด้วย OpenAPI
บทสรุป
Schemathesis เหมาะสำหรับเพิ่ม property-based fuzzing ให้ API ที่มี OpenAPI หรือ GraphQL schema อยู่แล้ว มันช่วยค้นหา 500, schema mismatch, status code ที่ไม่ได้ประกาศ และ edge cases ที่ test แบบเขียนเองมักพลาด โดยเพิ่มเข้า CI ได้ด้วยคำสั่ง st run
แต่ Schemathesis ไม่ได้ครอบคลุมการออกแบบ API, mock server, เอกสาร, functional tests หรือ business assertions
แนวทางที่ practical คือใช้ Apidog สำหรับออกแบบสเปก สร้าง functional tests, mock และเอกสาร รัน workflow ด้วย apidog run จากนั้นเพิ่ม Schemathesis เพื่อ fuzz schema เดียวกันและค้นหา edge cases เพิ่มเติม
หากต้องการเริ่มจากฝั่งออกแบบและ functional testing ให้ ดาวน์โหลด Apidog แล้วใช้ Schemathesis เป็น fuzzing layer เสริมใน CI

Top comments (0)