จากการแบ่งปันเรื่อง การทดสอบนั้น
มีคำถามเรื่องของ 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