จากการแบ่งปันเรื่อง การทดสอบนั้น มีคำถามเรื่องของ Contract testing มันคืออะไร ? ทำไมต้องใช้ด้วย ? ทำอย่างไรบ้าง ? เลยทำการแบ่งปันให้กับทางทีมไว้นิดหน่อย
โดยปกติแล้ว service ต่าง ๆ จะติดต่อสื่อสารผ่าน API
และมักจะเป็น RESTFul API นั่นเอง ดังนั้นทั้งผู้สร้างและผู้ใช้ API มั่นใจว่า API มันยังคงทำงานตามที่ตกลงร่วมกัน ทั้งสองฝั่งคือ
ผู้สร้าง API หรือ Provider ผู้ใช้งาน API หรือ Consumer
ทั้งสองฝั่งจำเป็นต้องมีขั้นตอนการทำงานร่วมกัน หรือการติดต่อสื่อสารกันอยู่อย่างเสมอ ตั้งแต่เริ่มสร้าง API เลยว่าเช่น
Endpoint ชื่ออะไร
Request และ Response มีหน้าตาอย่างไร
ในขั้นตอนนี้ Provider จะทำการสร้าง specification ของ API ขึ้นมา
จากนั้นแต่ละ Consumer จะสร้างข้อตกลงหรือสัญญา (Contract) กับ Provider ขึ้นมา แต่ละ consumer จะมี API เท่าที่ใช้งานเท่านั้น
ดังนั้นถ้าฝั่ง Provider ทำการเปลี่ยนแปลง API ใด ๆ ก็ตาม ก็จะรู้ทันทีว่า ส่งผลกระทบต่อ Consumer ใดบ้าง ทำให้มีความมั่นใจก่อน publish API ออกมา นี่มันคือการทำงานแบบ Proactive สุด ๆ ไม่ใช่ Reactive คือให้ทาง Consumer แจ้งปัญหากลับมา !! ส่วนฝั่ง Consumer ก็สามารถทดสอบผ่าน Contract ที่สร้างขึ้นมาได้เลย ถ้า Contract test มีปัญหาหรือไม่ผ่านแล้ว นั่นหมายความว่า การเปลี่ยนแปลงจากฝั่งของ Provider ก่อให้เกิดปัญหานั่นเอง
ประโยชน์ที่ได้รับคือ
เมื่อมีการเปลี่ยนแแปลง API ใด ๆ ก็ตาม ทำให้เรารู้ปัญหาได้อย่างรวดเร็ว แต่จำเป็นต้องกำหนดขั้นตอนการทำงานร่วมกัน ว่าถ้ามีการเปลี่ยนแปลง specification ของ API ใด ๆ แล้ว ต้องทำการทดสอบ Contract ต่าง ๆ ก่อนเสมอ ในขั้นตอนนี้ ถ้าทำงานเป็นแบบอัตโนมัติจะดีมาก ๆ
ทำไมต้องใช้ Contract testing กันด้วย ?
เนื่องจากปัญหาที่เกิดจาก Integration และ End-to-End testing นั่นเอง ที่ต้องใช้เวลาในการเตรียมการเยอะมาก ทำให้กว่าจะรู้ว่ามีปัญหา ต้องมีขั้นตอนการเตรียมการหรือพิธีกรรมมากมาย ยิ่งเข้าสู่โลกของ Microservices แล้วนั้น ยิ่งก่อให้เกิดปัญหามากมายตามมา แบบเท่าทวีคูณ
บางคนอาจจะบอกว่า เราก็ทำ Component testing ด้วยนะ
แต่มันคือการจำลอง API ต่าง ๆ ตามที่เราเข้าใจ แถมถ้าฝั่ง provider เปลี่ยนแปลง มักจะไม่ update ให้ฝั่ง consumer รู้อีกด้วย !! ส่งผลให้ผลการทดสอบมักจะไม่น่าเชื่อถือ มันไม่ใช่ปัญหาของเครื่องมือ แต่มันคือปัญหาเรื่อง collaboration และ communication ของทีมและองค์กร ดังนั้นก็ต้องแก้ไขให้ตรงจุด !!
แนวคิดดูดี แต่ลองมาดูตัวอย่างกันนิดหน่อย
Contract testing มีเครื่องมือและ framework หลายตัวเลย ทั้ง Pact, Pacto และ Spring Cloud Contract เ กิดมาเพื่อ Contract testing โดยเฉพาะ แต่ดูท่าทางจะยากไปสักหน่อย เลยลองใช้เครื่องมือง่าย ๆ เช่น Postman มาลองสร้างหน่อย Postman สามารถทำได้แต่ไม่ดีเท่า 3 ตัวที่บอกนะครับ มาเริ่มกันดีกว่า
ดังนั้นลองมาปรับปรุงขั้นตอนการทำงานตาม Contract testing กัน
มีขั้นตอนดังนี้
ขั้นตอนที่ 1 Provider ทำการสร้างและ publish API ออกมา
มักเป็นการออกแบบและสร้างจาก Provider ใน Postman นั้นคือการสร้าง Collection + Request ด้วย ในขั้นตอนนี้จะถูกเรื่องว่า Provider/Producer contract
ขั้นตอนที่ 2 ทั้งสองฝั่งทำการสร้าง contract หรือข้อตกลงรวมกัน
เป็นการสร้างข้อตกลงร่วมกันระหว่าง Provider และ Consumer นั่นคือการเขียน test และ assertion นั่นเอง เพื่อใช้ตรวจสอบว่า Request และ Response มีข้อตกลงร่วมกันอย่างไร เช่น
โครงสร้างของข้อมูลที่ส่งกลับ
Response code
Parameters ต่าง ๆ
รูปแบบของข้อมูล
จากนั้นทำการบันทึกไว้ ซึ่งจะเรียกว่า Consumer contract เป็น contract หรือข้อตกลงร่วมกันว่า แต่ละ consumer นั้นตกลงการทำงานกับ provider อย่างไร ใน Postman ก็คือการสร้าง Collection +Request ขึ้นมา และทำการเขียน test ต่าง ๆ ขึ้นมา รวมทั้งมี examples อีกด้วย
ขั้นตอนที่ 3 เมื่อทาง Provider ทำการเปลี่ยนแปลงหรือแก้ไขใด ๆ
ต้องทำการทดสอบ Consumer contract ที่มีให้ผ่านทั้งหมด เพื่อทำให้มั่นใจว่า การเปลี่ยนแปลงการทำงานภายใน ไม่ส่งผลต่อ consumer ทั้งหมด (Compatibility) หรือถ้ามีปัญหาเกิดขึ้น จะได้คุยหรือเปลี่ยนข้อตกลงใหม่กับทาง comsumer นั้น ๆ
ขั้นตอนที่ 4 ทางฝั่ง Consumer สามารถใช้ Consumer Contract ไปใช้งานได้เลย
นำเอา contract ที่สร้างขึ้นมา ไปทำการสร้าง Mock หรือทดสอบได้เลย ถ้าใน Postman ก็คือการสร้าง Mock Collection นั่นเอง
ตัวอย่างของ Colelction ดูได้จากที่นี่ GitHub:Up1