Contact
Line : comsiam
Contact
Line : comsiam

Google Gemini สามารถช่วยสร้าง Unit Test จาก Source Code ที่มีอยู่ได้ โดยผู้ใช้สามารถส่ง Function, Class, Module หรือ Codebase ให้ Gemini วิเคราะห์ แล้วสั่งให้สร้าง Test Case สำหรับ Normal Case, Boundary Case, Invalid Input, Error Case และ Regression Bug ได้อัตโนมัติ
อย่างไรก็ตาม คำว่า “อัตโนมัติ” ในที่นี้หมายถึง Gemini ช่วย Generate Test Code จาก Context ที่ให้มา ไม่ได้หมายความว่า Test ทุกชุดจะถูก Run และยืนยันว่าถูกต้องโดยอัตโนมัติเสมอไป หลัง Gemini สร้าง Test แล้ว Developer ยังต้องนำ Test ไป Run ด้วย Test Framework และ Environment จริงของ Project
Workflow ที่เหมาะสมคือ อ่าน Code → ระบุ Expected Behavior → สร้าง Test Cases → Generate Unit Test → Run → ตรวจ Failure → ปรับ Test/Code → Run ทั้ง Test Suite
Unit Test คือการทดสอบส่วนเล็ก ๆ ของโปรแกรมแยกจากระบบทั้งหมด
Unit อาจเป็น
ตัวอย่าง Function
def calculate_total(price, quantity):
return price * quantity
Unit Test จะตรวจว่า Function นี้คืนค่าถูกต้องหรือไม่เมื่อได้รับ Input ต่าง ๆ
เช่น
price = 100
quantity = 2
expected = 200
จุดประสงค์คือจับ Bug ให้เร็ว ก่อน Code ถูกนำไปรวมกับระบบส่วนอื่น
ได้ Gemini สามารถช่วย
ถ้า Project มีหลายไฟล์ สามารถให้ Gemini อ่าน Code Folder หรือ GitHub Repository เพื่อเข้าใจ Dependency และ Test Style เดิมของ Project ก่อนสร้าง Test เพิ่มได้
คำสั่งนี้กว้างเกินไป
Gemini อาจ
ควรเริ่มด้วย
“อ่าน Function นี้ก่อน แล้วอธิบาย Behavior ที่ควรถูก Test โดยยังไม่เขียน Test Code”
เมื่อได้รายการ Test Case แล้วจึงสั่งสร้าง Code
ใช้ Prompt นี้ได้กับหลายภาษา
“ช่วยสร้าง Unit Test สำหรับ Code นี้
Language:
[ระบุภาษา]
Test Framework:
[ระบุ Framework ที่ Project ใช้อยู่]
Source Code:
[แนบ Code]
Expected Behavior:
[อธิบาย Requirement]
ให้ทำตามลำดับ:
ห้ามสร้าง Function หรือ API ที่ไม่มีอยู่จริงใน Project”
Prompt นี้ช่วยให้ Gemini ไม่กระโดดไปสร้าง Test Code ทันที
Unit Test ที่ดีไม่ได้ตรวจว่า
Code ปัจจุบันทำอะไร
เพียงอย่างเดียว
แต่ต้องตรวจว่า
Code ควรทำอะไรตาม Requirement
สมมติ Function
def discount(price, percent):
return price - percent
ถ้า Requirement คือ
“percent หมายถึงเปอร์เซ็นต์ส่วนลด”
ผลลัพธ์ของ
price = 1000
percent = 20
ควรเป็น
800
แม้ Code ปัจจุบันจะคืน
980
Gemini จึงต้องรู้ Requirement เพื่อสร้าง Test ที่จับ Bug ได้
ตัวอย่าง Function
def divide(a, b):
return a / b
ก่อน Generate Unit Test ให้ Gemini สร้าง Case เช่น
10 / 2 = 5
5 / 2 = 2.5
-10 / 2 = -5
0 / 5 = 0
ต้องกำหนดว่า
ตาม Requirement
นี่คือเหตุผลว่าทำไม Test Design ควรมาก่อน Test Code
Normal Case คือสถานการณ์ที่ผู้ใช้หรือโปรแกรมใช้งานตามปกติ
ตัวอย่าง Function คำนวณราคา
price = 500
quantity = 2
Expected
1000
Prompt
“สร้าง Happy Path หรือ Normal Case ที่สำคัญที่สุดก่อน”
อย่ามีแต่ Edge Case จนลืม Behavior หลักของ Function
Bug จำนวนมากเกิดตรงค่าขอบเขต
ตัวอย่าง Requirement
“ผู้ใช้อายุ 18 ปีขึ้นไปสมัครได้”
ควร Test
17
18
19
ไม่ใช่ Test แค่
20
30
Prompt
“ค้นหาค่าขอบเขตทั้งหมดจาก Condition ใน Function นี้ และสร้าง Test ก่อนและหลัง Boundary”
เหมาะกับ
ตัวอย่าง Function รับจำนวนสินค้า
Input ที่ควรตรวจอาจมี
0
-1
None
"10"
"abc"
[]
ขึ้นกับภาษากับ Requirement
Prompt
“แยก Invalid Input ที่ Application ควร Reject ออกจาก Input ที่ควร Convert อัตโนมัติ”
อย่าให้ Gemini ตัดสินเองว่า String "10" ควรถูก Convert เป็น Number หรือ Error หาก Requirement ไม่ได้กำหนด
สมมติ Function อ่านไฟล์
อาจเกิด
Unit Test ควรตรวจว่า Code
อย่างไรตาม Design
Prompt
“สร้าง Unit Test ที่ตรวจ Error Contract ของ Function นี้ แทนการตรวจเพียงว่า Code ไม่ Crash”
Python มี Test Framework หลายแบบ เช่น
unittestpytestหาก Project ใช้ Framework อยู่แล้วควรใช้ตัวเดิม
ตัวอย่าง Source
def add(a: int, b: int) -> int:
return a + b
Test ด้วย pytest
from app import add
def test_add_two_positive_numbers():
assert add(2, 3) == 5
Prompt
“เขียน pytest สำหรับ Function add() โดยสร้าง Test Case สำหรับ Positive, Negative และ Zero”
ควรตรวจ Existing Test ก่อนเสมอ
หาก Case ใช้ Logic เดียวกันแต่ Input ต่าง สามารถใช้ Parameterization ตาม Framework
ตัวอย่าง pytest
import pytest
from app import add
@pytest.mark.parametrize(
("a", "b", "expected"),
[
(2, 3, 5),
(0, 0, 0),
(-2, 3, 1),
],
)
def test_add(a, b, expected):
assert add(a, b) == expected
Prompt
“รวม Test Case ที่มี Structure เดียวกันเป็น Parameterized Test โดยยังให้ชื่อและข้อมูลอ่านเข้าใจง่าย”
ช่วยลด Test Code ซ้ำ
JavaScript Project อาจใช้ Framework เช่น
ต้องให้ Gemini ตรวจ package.json และ Test Config ก่อน
ตัวอย่าง Function
export function multiply(a, b) {
return a * b;
}
แนวคิด Test
import { multiply } from "./math.js";
test("multiplies two numbers", () => {
expect(multiply(3, 4)).toBe(12);
});
แต่ Syntax จริงควรตรงกับ Framework ของ Project
Prompt
“ตรวจ package.json ก่อน แล้วใช้ Test Framework ที่ติดตั้งอยู่แล้ว ห้ามเพิ่ม Framework ใหม่”
PHP Project จำนวนมากใช้ PHPUnit
ตัวอย่าง Source
function calculateTotal(float $price, int $quantity): float
{
return $price * $quantity;
}
ก่อน Generate Test ควรให้ Gemini ตรวจ
composer.jsonPrompt
“สร้าง PHPUnit Test สำหรับ Function นี้โดยใช้ Version และ Project Structure เดิม ห้ามสร้าง Namespace ใหม่โดยเดาเอง”
ช่วยลดปัญหา Test Code ถูกแต่ Run ไม่ได้ใน Project จริง
ไม่ว่าจะเป็น
Test Framework สามารถเปลี่ยน Syntax และ API ตาม Version
ดังนั้นควรส่ง
Language Version
Framework
Framework Version
Existing Test Example
ให้ Gemini ก่อน
โดยเฉพาะ Project เก่าที่อาจไม่ได้ใช้ Syntax รุ่นล่าสุด
นี่เป็นหนึ่งในวิธีที่ดีที่สุด
ส่ง Test File ตัวอย่างของ Project แล้วสั่ง
“อ่าน Test ที่มีอยู่ก่อน แล้วสร้าง Test ใหม่โดยใช้ Style, Naming, Fixture, Mock และ Assertion Pattern เดียวกัน”
ข้อดีคือ Test ใหม่เข้ากับ Codebase เดิมมากกว่า
เช่น Project อาจมี Convention
tests/unit/
tests/integration/
หรือ Naming
test_user_service.py
UserServiceTest.php
user.service.test.js
Gemini ควรยึดรูปแบบเดิม
ชื่อที่ไม่ดี
test1
test_user
test_function
ชื่อที่ดีกว่า
test_returns_zero_when_cart_is_empty
หรือ
rejects_order_when_stock_is_insufficient
Prompt
“ตั้งชื่อ Test ให้บอก Behavior และ Condition โดยไม่อิงชื่อ Implementation ภายในเกินจำเป็น”
ชื่อ Test ที่ดีทำให้ Test Suite ทำหน้าที่เป็น Documentation ได้ด้วย
สมมติ Function ภายในใช้
sort()
ถ้า Requirement คือ
“คืนรายการเรียงตามราคา”
Test ควรตรวจ Output เรียงถูก
ไม่จำเป็นต้องตรวจว่า Function เรียก sort() กี่ครั้ง
เพราะถ้า Refactor Algorithm ในอนาคต Behavior ยังเหมือนเดิม Test ไม่ควร Fail
หลักคือ
Test What, not How
ในกรณีที่ไม่จำเป็นต้องล็อก Implementation
Mock ใช้แทน Dependency ที่ไม่ต้องการเรียกจริงใน Unit Test
ตัวอย่าง Dependency
สมมติ Function
createOrder()
↓
saveDatabase()
↓
sendEmail()
Unit Test ของ Business Logic อาจไม่ต้องส่ง Email จริง
จึง Mock Email Service
Over-mocking ทำให้ Test ผ่านแม้ Integration จริงพัง
Prompt
“ระบุเฉพาะ Dependency ที่จำเป็นต้อง Mock และอธิบายว่าทำไม ส่วน Pure Function หรือ Value Object ไม่ต้อง Mock”
หลักง่าย ๆ คือ
Mock Boundary
ไม่ใช่ Mock ทุก Function
หาก Unit Test เรียก External API จริง อาจเกิด
ควร Mock API Response ใน Unit Test
ส่วนการทดสอบ API จริงอาจอยู่ใน
ตาม Architecture
ถ้า Unit Test Business Logic แล้วต้องเปิด Database จริงทุกครั้ง Test อาจไม่ใช่ Unit Test ที่แยกจาก Dependency แล้ว
แต่ไม่ใช่ว่า Database ห้ามใช้ในการ Test ทั้งหมด
ควรแบ่ง
แยก Logic
ตรวจการทำงานร่วมกับ Database จริงหรือ Test Database
การแบ่ง Layer ทำให้ Test Suite มีจุดประสงค์ชัด
Prompt
“สำหรับ Test Case นี้ช่วยจัดประเภทก่อนว่าเหมาะเป็น Unit Test, Integration Test หรือ End-to-End Test พร้อมเหตุผล”
ตัวอย่าง
“User Login ต้องตรวจ Password Hash + Database + Session”
อาจมีหลาย Layer
ไม่ควรบังคับทุกอย่างให้เป็น Unit Test
นี่เป็น Use Case ที่มีประโยชน์มากที่สุดของ Gemini
สมมติ Bug คือ
“User ที่ไม่มี Profile ทำให้หน้า Account Crash”
Workflow
ต้อง Fail ก่อน
ต้อง Pass
Prompt
“สร้าง Regression Test สำหรับ Bug นี้ โดย Test ต้อง Fail กับ Code ปัจจุบันและ Pass หลัง Root Cause ถูกแก้”
วิธีนี้ช่วยป้องกัน Bug เดิมกลับมา
ถ้าสร้าง Regression Test แล้ว Test ผ่านทั้งที่ Bug ยังมีอยู่
อาจแปลว่า
อย่ารีบแก้ Production Code
ควรตรวจ Test ก่อน
Code Coverage ช่วยบอกว่า Test Execute Code ส่วนใดบ้าง
ตัวเลขอาจอยู่ในรูป
Statement Coverage
Branch Coverage
Function Coverage
Line Coverage
แต่ Coverage สูงไม่ได้หมายความว่า Test ดีเสมอไป
Project อาจมี Coverage 100% แต่ Assertion อ่อนมากจนจับ Bug ไม่ได้
ดังนั้นควรใช้ Coverage เป็น Signal ไม่ใช่ Goal เพียงอย่างเดียว
AI อาจสร้าง Test จำนวนมากเพียงเพื่อ Execute ทุกบรรทัด
แต่ Test อาจไม่มีคุณค่าทาง Business
Prompt ที่ดีกว่า
“ดู Coverage Gap แล้วเลือก Test Case ที่มีความเสี่ยงทาง Business สูงที่สุดก่อน”
Priority ควรเป็น
Critical Behavior
↓
Error Handling
↓
Boundary
↓
Regression
↓
Less-important code
ตัวอย่าง
def shipping_fee(total):
if total >= 1000:
return 0
return 50
ถ้า Test มีเพียง
total = 1500
ก็ Test ได้เพียง Branch หนึ่ง
ควรมีอีก Case
total = 500
และ Boundary
total = 1000
999
Prompt
“ค้นหา Condition ทุก Branch แล้วสร้าง Test ครอบคลุม Boundary ของแต่ละ Branch”
Function ที่มี Input/Expected Output จำนวนมากเหมาะกับ Test Table
ตัวอย่าง
| Input | Expected |
|---|---|
| 0 | 0 |
| 1 | 10 |
| 10 | 100 |
| -1 | Error |
Gemini สามารถช่วยสร้างตารางก่อนแปลงเป็น Parameterized Test
ทำให้ Review Business Rule ได้ง่าย
Function ที่ใช้
now()
today()
currentTime()
อาจ Test ยาก เพราะผลเปลี่ยนตามเวลา
แนวทางที่ดีคือแยก Clock Dependency ออกจาก Business Logic ตาม Architecture
Prompt
“Refactor Function นี้ให้ Test เรื่องเวลาได้โดยไม่พึ่งเวลาจริงทุกครั้ง และสร้าง Test สำหรับก่อน/หลัง Deadline”
ไม่ควรใช้ Sleep เพื่อ Test Logic เวลาโดยไม่จำเป็น
ถ้า Function ใช้ Random
Test อาจ Pass บ้าง Fail บ้าง
เรียกว่า Flaky Test
Prompt
“ตรวจ Function นี้ว่ามี Random Dependency หรือไม่ และออกแบบให้ Test Deterministic โดยไม่เปลี่ยน Behavior ที่ผู้ใช้เห็น”
อาจใช้ Seed หรือ Dependency Injection ตามภาษาและ Architecture
Flaky Test คือ Test ที่
Code ไม่เปลี่ยน
แต่บางครั้ง Pass
บางครั้ง Fail
สาเหตุอาจมาจาก
Prompt
“วิเคราะห์ Test นี้ว่ามี Source ของ Non-determinism ตรงไหน”
Gemini สามารถช่วยลดพื้นที่ค้นหาได้
Test ที่สร้าง File, Record หรือ State อาจต้อง Cleanup หลัง Test
หากไม่ Cleanup
Test อื่นอาจได้รับผลกระทบ
ควรใช้ Setup/Teardown, Fixture หรือ Transaction Pattern ตาม Framework
Prompt
“ตรวจว่า Test นี้มี Shared State หรือ Resource ที่ต้อง Cleanup หลัง Test หรือไม่”
สามารถใช้ Gemini สร้าง Test ให้ Security Requirement เช่น
User A ห้ามอ่าน Order ของ User B
quantity ติดลบต้อง Reject
Role ที่ไม่อยู่ใน Allowlist ต้อง Reject
Expired Token ต้องไม่ผ่าน
Test แบบนี้ช่วยล็อก Security Behavior ไว้ใน Codebase
ไม่ควรเพียงตรวจว่า
“มี Error”
ถ้า Error Contract สำคัญควรตรวจ
ตัวอย่างแนวคิด
divide by zero
→ ValueError
แต่ไม่ควรล็อก Error Message รายละเอียดมากเกินไปหากข้อความไม่ใช่ Public Contract
Case ที่มักตกหล่น เช่น
[]
{}
""
None/null
Prompt
“ตรวจทุก Collection/String Input และสร้าง Empty Case หาก Meaningful ตาม Requirement”
Empty Input เป็น Edge Case ที่พบ Bug บ่อย
ระบบบางประเภทต้องตรวจ Duplicate เช่น
Prompt
“สร้าง Unit Test หรือ Integration Test สำหรับ Duplicate Request ตาม Layer ที่เหมาะสม”
โดยเฉพาะระบบที่ต้องมี Idempotency
ระบบที่คำนวณ
ต้องกำหนด
ให้ชัด
Prompt
“สร้าง Test สำหรับค่าการเงินโดยเน้น Rounding Boundary และไม่ใช้ Float Comparison แบบที่ไม่เหมาะกับภาษานี้”
Application ที่รองรับภาษาไทยหรือหลายภาษาอาจต้อง Test
ตัวอย่าง
"กรุงเทพฯ"
"ทดสอบ 😊"
Prompt
“เพิ่ม Unicode Test Case โดยไม่เปลี่ยน Requirement ของระบบ”
สำหรับเว็บไซต์ของ comsiam Test ข้อมูลภาษาไทยมีประโยชน์มาก เพราะ Code ที่ผ่านเฉพาะข้อความภาษาอังกฤษอาจยังมีปัญหากับ Encoding หรือ Length Logic ได้
หาก Project อยู่บน GitHub สามารถ Import Repository เข้า Gemini Apps แล้วสั่ง
“อ่าน Test Structure ที่มีอยู่ก่อน แล้วค้นหา Service ที่ยังขาด Unit Test”
จากนั้น
“สร้าง Test เฉพาะ UserService โดยใช้ Framework, Mock Style และ Naming เดิมของ Repository”
ข้อดีคือ Gemini เห็น
มากกว่าการ Copy Function เดียว
หาก Code ยังอยู่ในเครื่อง สามารถใช้ Code Folder เป็น Context
Prompt
“อ่าน Code Folder นี้และหา Module ที่มี Business Logic แต่ไม่มี Test จาก Test Folder ที่มีอยู่”
จากนั้นจัด Priority ตาม
ไม่จำเป็นต้อง Generate Test ให้ทุก File พร้อมกัน
Gemini Canvas ปัจจุบันสามารถสร้างและแก้ Code ได้
สามารถใช้ Workflow
Source Code
↓
Canvas
↓
Generate Test
↓
Review
↓
แก้ Test
Canvas ยังมี Code View และ Console สำหรับ App/Code ในสภาพแวดล้อมที่รองรับ
แต่ Unit Test Suite ของ Project จริงยังควรถูก Run ด้วย Test Runner และ Runtime ของ Project เช่น
pytest
npm test
phpunit
หรือคำสั่งที่ Project กำหนด
ไม่ควรถือว่า Test ผ่านเพียงเพราะ Gemini สร้าง Code ได้โดยไม่มี Error ในคำตอบ
Prompt
“ตรวจ Project Config แล้วบอกคำสั่งที่ใช้ Run Unit Test โดยอ้างจาก Configuration ที่มีอยู่ ห้ามเดาคำสั่งถ้าไม่มีข้อมูล”
ตัวอย่างอาจเป็น
pytest
หรือ
npm test
หรือคำสั่งอื่น
แต่ต้องยืนยันจาก Project จริง
ส่ง
Prompt
“Test นี้ Fail หลัง Run
Expected:
[…]
Actual:
[…]
Failure:
[…]
วิเคราะห์ก่อนว่า:
อย่าแก้ Test ให้ Pass โดยอัตโนมัติ”
นี่สำคัญมาก
เพราะ AI มีแนวโน้มแก้ Assertion เพื่อทำให้ Test ผ่าน ทั้งที่ Production Code อาจมี Bug
ตัวอย่าง
Test คาด
800
Code คืน
980
วิธีที่ผิดคือเปลี่ยน Test เป็น
expected = 980
เพียงเพื่อให้ Test ผ่าน
ต้องกลับไปดู Requirement ก่อนว่าอะไรถูก
กฎคือ
Test Failure คือหลักฐานให้ตรวจ ไม่ใช่สิ่งที่ต้องกำจัดทุกกรณี
หลังเพิ่ม Test หรือแก้ Code
อย่ารันเพียง Test ใหม่
ควร Run
New Test
↓
Related Tests
↓
Full Test Suite
ตามขนาด Project
เพราะ Patch อาจทำ Test อื่นพัง
ทดสอบ Unit แยกจาก Dependency สำคัญ
ทดสอบหลาย Component ทำงานร่วมกัน
ตัวอย่าง
Unit
calculateTotal()
Integration
OrderService
+
Database
Gemini ควรช่วยเลือก Test Level ให้เหมาะกับ Requirement แทนการ Mock ทุก Dependency
End-to-End หรือ E2E ทดสอบ Flow จากมุมผู้ใช้มากกว่า
ตัวอย่าง
เปิดเว็บ
↓
Login
↓
เพิ่มสินค้า
↓
Checkout
↓
เห็น Order Success
Unit Test เร็วและเจาะ Logic
E2E ครอบคลุมระบบกว้างกว่าแต่ช้ากว่า
Project ที่ดีมักต้องใช้ Test หลายระดับตามความเสี่ยง
แนวคิดโดยทั่วไปคือมี
E2E Tests
▲
Integration Tests
▲
Unit Tests
Unit Test มักมีจำนวนมากและเร็ว
Integration น้อยลง
E2E เลือกเฉพาะ Flow สำคัญ
แต่สัดส่วนจริงควรปรับตาม Architecture ไม่จำเป็นต้องยึดตัวเลขตายตัว
ไม่ควร Test ตามลำดับไฟล์เสมอไป
Prompt
“จัดอันดับ Function ที่ควรมี Unit Test ก่อนโดยพิจารณา:
ทำให้ Test Investment ไปอยู่จุดที่คุ้มค่ากว่า
ตัวอย่าง
ควรมี
มากกว่าการ Test Getter/Setter ที่ไม่มี Logic
ควร Test Behavior เช่น
Unauthenticated → Reject
Authenticated User → Allowed
Normal User → Admin Action Reject
Admin → Allowed
Expired Session → Reject
ตาม Architecture จริง
ได้
Prompt
“Review Test Suite นี้ด้าน:
ยังไม่แก้ Code ให้จัดอันดับปัญหาก่อน”
จากนั้น Refactor ทีละกลุ่ม
อย่าถือว่า
Production Code = อาจผิด
Test Code = ถูกเสมอ
Test อาจ
จึงควร Review Test เช่นเดียวกับ Production Code
ถ้าต้องการตรวจว่า Test แข็งแรงจริงหรือไม่ มีแนวคิด Mutation Testing
คือเปลี่ยน Code เล็กน้อยโดยตั้งใจ เช่น
>
เปลี่ยนเป็น
>=
แล้วดูว่า Test จับได้หรือไม่
ถ้า Mutated Code ยังทำ Test ผ่าน อาจแปลว่า Test ไม่ครอบคลุม Behavior นั้น
Gemini สามารถช่วยอธิบาย Mutation Candidate ได้ แต่การ Run ควรใช้ Tool ที่เหมาะสมใน Project
Test 500 ตัวไม่ได้แปลว่าดีกว่า Test 50 ตัว
ถ้า 500 Test
จะเพิ่ม Maintenance Cost
Quality สำคัญกว่า Quantity
รู้ว่า Test อะไร
Run ซ้ำได้ผลเดียวกัน
ไม่พึ่ง Test อื่น
เหมาะกับการ Run บ่อย
ตรวจ Behavior ที่สำคัญ
Developer อ่านรู้เรื่อง
จับ Bug ได้จริง
Mock เฉพาะที่จำเป็น
ครอบคลุมความเสี่ยง
ไม่ผูก Implementation มากเกินไป
AI อาจเลือกผิด
Test อาจล็อก Bug เดิมไว้
Style ไม่เข้ากับ Project
Test ไม่มีความหมาย
Refactor แล้ว Test พังโดยไม่จำเป็น
ได้ Test ปริมาณมากแต่คุณภาพต่ำ
ซ่อน Bug จริง
พลาดจุดที่ Bug เกิดบ่อย
Generate สำเร็จไม่ได้แปลว่า Test ผ่าน
Test Code เองก็อาจผิดได้
แนวทางที่แนะนำคือ
ใช้ของ Project เดิม
Function/Class ที่ต้อง Test
Expected Behavior
ยึด Style เดิม
ยังไม่เขียน Code
ตรวจ Case ให้ครบ
ตาม Framework
ใช้เฉพาะที่จำเป็น
ใน Environment จริง
อย่ารีบแก้ Assertion
ตาม Root Cause
ตรวจ Regression
ก่อน Merge
ใช้เป็น Signal
ไม่ดูเพียงจำนวน Test
สำหรับ Code ที่ใช้บน comsiam Workflow นี้เหมาะกว่าการให้ Gemini Generate Test ทั้ง Project ในครั้งเดียว เพราะสามารถตรวจได้ว่าแต่ละ Test กำลังป้องกัน Bug หรือ Business Rule อะไรจริง ๆ
“อ่าน Function นี้แล้วสร้าง Test Case ก่อน โดยยังไม่เขียน Test Code”
“ค้นหา Condition และ Boundary ทั้งหมด แล้วสร้าง Case ก่อนและหลังค่าขอบเขต”
“อ่าน Test File นี้แล้วสร้าง Test ใหม่ตาม Naming, Fixture และ Assertion Pattern เดิม”
“สร้าง pytest สำหรับ Function นี้โดยไม่เพิ่ม Dependency ใหม่”
“ตรวจ package.json แล้วใช้ Test Framework ที่ Project มีอยู่ ห้ามเดา Framework”
“สร้าง PHPUnit Test ตาม Namespace และ Autoload ของ Project เดิม”
“ระบุ Dependency ที่ต้อง Mock และอธิบายว่าทำไมก่อนสร้าง Mock”
“สร้าง Test ที่ Fail กับ Bug ปัจจุบันและ Pass หลังแก้ Root Cause”
“วิเคราะห์ว่า Test Fail เพราะ Production Code, Test Code, Mock หรือ Requirement ก่อนแก้อะไรก็ตาม”
“Review Test Suite นี้ด้าน Over-mocking, Flaky Test, Weak Assertion และ Duplicate Setup”
ได้ Gemini สามารถช่วยวิเคราะห์ Code สร้าง Test Case และ Generate Unit Test Code ตามภาษาและ Test Framework ที่กำหนด
การ Generate Test กับการ Run Test เป็นคนละขั้นกัน ใน Project จริงควรนำ Test ไป Run ด้วย Test Runner และ Environment ของ Project เพื่อยืนยันว่า Test Compile/Execute และผ่านจริง
ควรอย่างมาก โดยเฉพาะ Project ที่มี Framework อยู่แล้ว เพราะ Syntax, Fixture และ Mock API แตกต่างกัน
ได้ และเป็นหนึ่งใน Use Case ที่มีประโยชน์มาก โดยควรสร้าง Test ที่ Reproduce Bug และ Fail ก่อนแก้ จากนั้นต้อง Pass หลัง Root Cause ถูกแก้
ไม่เสมอ Coverage บอกว่า Code ส่วนใดถูก Execute แต่ไม่ได้ยืนยันว่า Assertion มีคุณภาพหรือ Business Rule สำคัญถูกตรวจครบ
ไม่ควรถือว่าถูกต้อง 100% Test Code สามารถมี Bug หรือ Assertion ผิดได้ ต้อง Review และ Run จริงเช่นเดียวกับ Production Code
วิธีให้ Gemini เขียน Unit Test อัตโนมัติที่ได้ผลดีที่สุดไม่ใช่การสั่งให้ Generate Test จำนวนมากทันที แต่ควรเริ่มจาก Requirement → Source Code → Existing Test Style → Test Cases → Unit Test Code → Run → Review
Gemini สามารถช่วยหา Normal Case, Boundary Case, Invalid Input, Error Case และ Regression Case ได้ รวมถึงช่วยเขียน Test สำหรับ Framework ต่าง ๆ แต่ต้องระบุ Framework และ Version ของ Project ให้ชัดเพื่อป้องกัน Test Code ที่ไม่เข้ากับ Environment
สิ่งสำคัญคือ Test ต้องตรวจ Behavior ที่ถูกต้องตาม Requirement ไม่ใช่เพียงล็อก Behavior ของ Code ปัจจุบัน เพราะถ้า Production Code มี Bug แล้วให้ Geminiสร้าง Test จาก Code อย่างเดียว AI อาจสร้าง Test ที่ยืนยัน Bug นั้นแทนที่จะจับ Bug
หลัง Generate Test ต้อง Run ด้วย Test Runner จริง ตรวจ Failure และ Run Full Test Suite ก่อน Merge ทุกครั้ง Google เองก็แนะนำให้ Review และ Test Code ที่ Generative AI ช่วยสร้างอย่างระมัดระวังเพื่อค้นหา Error, Bug และ Vulnerability
แนวทางของ comsiam คือใช้ Gemini ช่วยลดเวลาออกแบบ Test Case และเขียน Boilerplate ส่วนคุณภาพของ Unit Test ยังต้องถูกพิสูจน์ด้วย Requirement, Runtime และความสามารถในการจับ Regression จริง