มีคำถามเกี่ยวกับการทดสอบระบบงานกับพวก Database ชนิดต่าง ๆ
ทั้ง RDBMS (Relational DataBase Management System)
ทั้ง NoSQL เช่น Document, Key-value, Column และ Graph
อีกทั้ง Time series
ว่าจะทดสอบกันอย่างไรดี ?
ต้องทำการ mock/stub database ไหม ?
ต้องเขียน code อย่างไรเพื่อให้ทดสอบได้ง่าย (Testable) ?
ต้องทำอย่างไร ???

แต่ก่อนที่จะลงมือทำนั้น
ลองมาคิดก่อนสิว่า มีวิธีการอะไร อย่างไรบ้าง ?
และแต่ละวิธีเป็นอย่างไร มีข้อดีข้อเสียอะไรบ้าง ?
จากนั้นจึงมาตัดสินใจว่าจะทำอย่างไรต่อไป

1. การใช้ Mock หรือ Stub Database ไปเลย

เราสามารถทำการสร้าง Mock database ขึ้นมาได้
ซึ่งถ้าส่วนการจัดการข้อมูลกับ Database อยู่ที่ DAO (Data Access Object) หรือ Repository แล้ว
เราสามารถทำการสร้าง interface คั่น
จากนั้นในการทดสอบก็สามารถสร้าง implementation class มาจาก interface ได้เลย
จากนั้นทำการส่ง implementation class นั้นเข้ามายัง DAO
เราเรียกวิธีการนี้แบบหล่อ ๆ ว่า Dependency Injection (DI)

แต่วิธีการนี้จะทำได้เฉพาะ Unit test เท่านั้น
ส่วน integration test ยังไม่ได้ตอบโจทย์
โดยวิธีการนี้ผมชอบเรียกว่า การทดสอบภายในบ้านของระบบที่เราควบคุมได้
ดังนั้นสิ่งที่ต้องการมากขึ้นเพื่อความมั่นใจก็คือ integration test และ end-to-end test

2. การใช้งาน Embedded database

นั่นคือการใช้งาน Database ชนิดเดียวกัน
ทำการ start และ shutdown ในทุก ๆ ชุดการทดสอบได้
ส่วนใหญ่จะเป็น In-memory data ซึ่งทำงานได้อย่างรวดเร็ว
ตัวอย่างเช่น H2, HSQLDB, SQLite, Derby เป็นต้น

แต่วิธีการนี้ก็ไม่ได้การันตีว่า
ถ้าทดสอบผ่านแล้ว จะสามารถทำงานบน Database จริง ๆ ได้ทั้งหมดนะ !!
แต่การันตีเพียงพฤติกรรมการทำงานมันจะถูกต้องตามที่คาดหวังเท่านั้น
ยกตัวอย่างเรื่องของ constraint ต่าง ๆ เป็นต้น

3. ใช้งาน Database จริง ๆ ไปในแต่ละ environment ที่ต้องการ

ตัวอย่างเช่น Development, Testing และ Staging เป็นต้น
แต่ปัญหาที่ตามมาก็คือ ข้อมูลและ state ต่าง ๆ นั้น
ต้องทำการ clean up เมื่อทำการทดสอบเสร็จสิ้นแล้วเสมอ
นั่นคือ สามารถทดสอบซ้ำแล้วซ้ำอีกได้

ถ้าทำไม่ได้ มันก็ยากต่อการทดสอบอย่างแน่นอน
และอาจจะเป็นเหตุผลในการไม่ทำ ก็เป็นไปได้

4. ทดสอบแบบ End-to-End test ไปเลย

ทำการทดสอบในมุมมองของผู้ใช้งานไปเลย ทั้ง UI และ API
ซึ่งทำหลังจากที่ deploy ใน enviroment ที่ต้องการเสร็จแล้ว
ทำให้เรามั่นใจมาก ๆ ว่าระบบทำงานได้ตามที่คาดหวัง
แต่การเตรียมการก็ไม่ง่ายเลย
ทั้งเรื่องของข้อมูล
ทั้งเรื่องของ server
ทั้งเรื่องของการติดตั้ง

จะเห็นได้ว่าวิธีการที่ 3 และ 4 มันยากต่อการเตรียมการมาก

แต่ด้วยเทคโนโลยีต่าง ๆ พัฒนาไปอย่างมาก
มาจนถึงยุคของ Containerization
มีเครื่องมือมากมายให้ใช้งาน ยกตัวอย่างเช่น Docker หรือ Moby
ทำให้เราสามารถสร้าง container ของระบบงานที่ต้องการใช้ในการทดสอบได้ง่ายและสะดวกขึ้น
ทั้ง Database container
ทั้ง Web server container
ซึ่งใช้ได้ตั้งแต่ developer => development ไปจนถึง production server
ทำการสร้างและลบได้บ่อยเท่าที่ต้องการ
แต่จริง ๆ ก็ไม่ง่ายขนาดนั้น ต้องมาวางแผนและลงมือทดลองกันก่อนนะ

มาถึงตรงนี้จะเห็นได้ว่ามีวิธีการที่หลากหลาย

ต่างมีข้อดีและข้อเสีย
คำถามคือ สิ่งที่คุณต้องการคืออะไร ?
คำถามคือ ต้องการทดสอบอะไร ?
คำถามคือ ต้องการทดสอบเพื่ออะไร ?

ขอให้สนุกกับการ coding ครับ