September 16, 2020

Consumer-driven Contract testing

Consumer-driven Contract testing

Dạo gần đây, trên group Testing VN bạn của mình bảo muốn tìm hiểu về contract testing. Khi mình vào là đã thấy mọi người share rất nhiều tài liệu về tool để làm contract testing. Đối với mình, contract testing là cách suy nghĩ và communication, nó cần bạn hiểu về ý nghĩa cũng như kỹ thuật, và trường hợp sử dụng nhiều hơn là dùng tool. Sự thật là, nó chẳng dùng tool cũng có thể dễ dàng viết ra contract testing, miễn là nó phù hợp với team của bạn. Mình đã từng làm qua contract testing ở 2 công ty Atlassian và Ascend Tech VN, nên mình xin phép chia sẻ một số thành công và thất bại khi làm contract testing.


1/ "Consumer - driven" và những ý nghĩa mở rộng của nó

Khi nói về contract testing, người ta thường nghĩ đến "consumer-driven", tức là được viết hướng về người tiêu dùng, thường là do người tiêu dùng viết, và viết chủ yếu để bảo vệ consumer, người tiêu dùng. Tuy nhiên, dưới dạng là 1 hợp đồng (contract), nó sẽ bảo vệ cả 2. Contract testing được tạo ra để đảm bảo:

  • Với bên consumer, bên provider sẽ giao những gì mà họ cần và đã thỏa thuận trong bản hợp đồng
  • Với bên provider, nếu bên provider đã đảm bảo những mục (Ví dụ mục A,C,E), đúng như thỏa thuận, thì những mục khác, nếu có bất cứ thay đổi gì, bên consumer không được kiện! Nó giúp bên provider thoải mái hơn trong việc thay đổi sản phẩm của họ mà không phải lúc nào cũng lo sợ Backward compatibility

2/ Vì sao cần contract testing?

Contract testing trở nên quan trọng vì 1 provider, khi cung cấp 1 sản phẩm sẽ muốn phát triển và thay đổi sản phẩm của họ cho phù hợp với nhiều khách hàng (consumer). Nó dẫn đến hệ quả là khi bên provider sửa sản phẩm để chiều ý khách hàng B, thì sản phẩm đó không còn đúng như cái khách hàng A mong muốn nữa. Với mô hình microservices đang ngày càng mở rộng, tình huống này xảy ra rất nhiều trong quá trình phát triển sản phẩm.

Ngoài lợi điểm quan trọng nêu trên, nếu biết phối hợp tốt, contract testing còn có nhiều lợi điểm khác mà mình thấy khi áp dụng ở công ty:

  • Nếu bộ contract testing được public, cho cả 2 bên consumer và provider được dùng, thì bên provider sẽ được lợi. Ví dụ, khi grooming, PO bảo muốn change API A, field "username" thành "user_name", câu hỏi của team đương nhiên sẽ là "Đổi thế này khách hàng có bị ảnh hưởng không?" Nếu có bộ test của các consumer đưa cho, họ có thể dễ dàng change internal API spec và chạy thử bộ test trên cái vừa change đó. Nếu không sai tức là việc thay đổi an toàn. Nếu sai, chúng ta sẽ dễ dàng biết khách hàng nào ảnh hưởng, và tầm ảnh hưởng là như thế nào để dễ dàng deal.
  • Với consumer team, nó cũng trở thành 1 bản document rất tốt về việc ở service của tôi, tôi đã dùng field nào của API nào của service nào ? Sau này, việc maintainance và thay đổi sẽ trở nên minh bạch hơn nhờ có nó.

3/ Thể hiện contract bằng test case


Đó là điều chúng ta luôn mong muốn. Thể hiện contract ở dạng test case để có thể chạy automation. Tuy nhiên, trước khi đó, mình nói trước là có thể hiện nó được ở dạng test case được hay không, "Contract" là cần thiết. Bạn có thể chỉ viết 1 email, 1 document để thể hiện cái "contract" giữa 2 bên nếu chưa thể viết test được. Consumer driven contract testing là việc thỏa thuận giữa provider và consumer, không phụ thuộc vào hình dạng thể hiện nó.


Đây là cách mình implement contract testing, mà không dùng tool nào cả:

  • Mình tạo 1 Git folder để provider team có thể bỏ Json data sample vào trong đó, nó sẽ là bản data được dùng để đối chứng khi chạy contract test. Ở mỗi release, khi provider change API, bản sample này sẽ cần được cập nhật.

  • Sau đó, cho mỗi consumer, mình sẽ tạo ra 1 Git folder để chứa test của họ.
  • Testcase được structure bằng Service consume --> service provide --> API name
  • Trong test case: Bạn sẽ load data từ Git Json Contract, nó sẽ có dạng Json, và bạn sẽ verify cái cấu trúc bạn mong muốn có exist hay không, có phải là integer hay không.
  • Lưu ý, ở mức contract testing, bạn chỉ nên kiểm như thế, bạn không nên kiểm là data trả về có đúng 1 chuỗi hay con số nhất định không, nó sẽ làm mất ý nghĩa của contract testing.

4/ Suy nghĩ riêng về contract testing


Hiện giờ, mình thấy khi nói về contract testing, chúng ta đều nói về API. Tuy nhiên, khái niệm consumer - provider trong quá trình phát triển phần mềm có rất nhiều, ví dụ:

  • Design provide cho Front End 1 bản design. Thường là, trước khi có design đẹp đẽ bản sẽ có mock design, ở đó nó đảm bảo đầy đủ thuộc tính button, text và vị trí cho bạn, chỉ không có màu sắc và style đẹp đẽ. Đó cũng là 1 hình thức của Contract. Contract có thể note là đảm bảo bạn có button X, có id="btn_x",... để làm việc
  • QA provide cho Developer keyword để viết thành automation test. Trong đó, QA cũng phải nói rõ tên keywords là gì, keyword có bao nhiêu tham số, đầu ra đầu vào,... Cũng là 1 hình thức của Contract. Developer ở công ty Hải có thể dùng cái keyword thỏa thuận đó viết ra test case trước, và QA sẽ fullfill bằng cách làm hoàn chỉnh cái keyword kia. Và, khi team QA muốn đổi keyword tên, input, output cũng phải communicate rất nhiều


Thế, các bạn đã nghĩ đến việc làm contract testing cho những dạng contract này chưa?

Tất nhiên, tùy vào nhu cầu sử dụng và độ khó của việc communication, chúng ta hãy cân nhắc đến việc thực hiện contract testing cho những việc này. Mình hy vọng trong tương lai sẽ được nhìn thấy contract testing được áp dụng phổ biến và đa dạng hơn nữa.


Chúc các bạn thành công!

Nguồn: Nguyễn Dương Hải, Quality Director

Link bài gốc: https://www.linkedin.com/pulse/consumer-driven-contract-testing-nguyen-duong-hai/