Middle+
მიკროწესვრის კონტრაქტული ტესტირების შესახებ ისაუბრეთ.
sobes.tech AI
პასუხი AI-სგან
კონტრაქტული ტესტირება ორიენტირებულია მიკროსერვისების ურთიერთქმედების შემოწმებაზე მათი API (კონტრაქტის) დონეზე. მიზანია დარწმუნება, რომ მომხმარებელი (სერვისი, რომელიც იყენებს API-ს) და მიმწოდებელი (სერვისი, რომელიც უზრუნველყოფს API-ს) იცავენ გარკვეულ "კონტრაქტს" (სქემა მოთხოვნის/პასუხის, მონაცემთა ფორმატი, მოლოდინები).
ძირითადი პრინციპები:
- მომხმარებელი-კონტრაქტი: ტესტები ეფუძნება მომხმარებლის მოლოდინებს. მომხმარებელი განსაზღვრავს, რა მონაცემები და ფორმატები სჭირდება.
- ორმხრივი ტესტირება: შემოწმება, მუშაობს თუ არა მომხმარებლის მხარე (შესაძლებელია თუ არა მას მუშაობა მიმდინარე კონტრაქტთან), ასევე მიმწოდებლის მხარე (შესაბამისია თუ არა მისი რეალიზაცია მომხმარებლის მოლოდინებს).
- სწრაფობა: ტესტები სწრაფად სრულდება, ხშირად CI/CD-ის ჩარჩოებში, რადგან არ საჭიროებს ყველა დამოკიდებული სერვისის განთავსებას.
პროცესი ჩვეულებრივ მოიცავს:
- მომხმარებელი ქმნის ტესტებს, რომლებიც აღწერენ მის მოლოდინებს მიმწოდებლის API-ზე. ეს ტესტები ქმნის "კონტრაქტს".
- კონტრაქტი გამოქვეყნდება (მაგალითად, ცენტრალიზებულ საცავში).
- მიმწოდებელი იყენებს გამოქვეყნებულ კონტრაქტს თავისი API-ის რეალიზაციის ვალიდაციისთვის. ის იწყებს ტესტებს (სხვადასხვა მხარიდან), რომლებიც ამოწმებენ, შეესაბამება თუ არა მისი API კონტრაქტს.
- თუ მომხმარებლის მოლოდინები და მიმწოდებლის რეალიზაცია არ ემთხვევა, ტესტი ჩავარდება და კონტრაქტის დარღვევა გამოიწვევს.
საშუალებები:
- Pact (ყველაზე პოპულარული)
- Spring Cloud Contract
- Swagger/OpenAPI და ვალიდაციის ინსტრუმენტები
უპირატესობები:
- სწრაფი შეცდომების გამოვლენა ინტეგრაციაში: პრობლემები იპოვება განთავსებამდე.
- ინტეგრაციის ტესტების საჭიროების შემცირება: ამცირებს დამოკიდებულებას რთული და ნელი სრული ტესტებისგან.
- საკუთარი ტესტირება: საშუალებას აძლევს სერვისებს დამოუკიდებლად ტესტირებას.
- მოლოდინების მკაფიო განსაზღვრა: მკაფიოდ განსაზღვრავს კონტრაქტს სერვისებს შორის.
მოხერხებულობები:
- არ აყვანილობს სრულყოფილ ინტეგრაციის ტესტებს (მხოლოდ API დონეზე ურთიერთქმედებას).
- საჭიროებს კონტრაქტების ვერსიების კონტროლს.
- შეიძლება იყოს რთული ძალიან რთული კონტრაქტების მქონე სერვისებისთვის.
მაგალითი Pact-ის გამოყენებით:
- მომხმარებელი (მაგალითად,
Order Service) იყენებს Pact ბიბლიოთეკას, რათა შექმნას მომხმარებლის მხარის ტესტები:// მომხმარებლის ტესტის მაგალითი Pact JVM-ით @ExtendWith(PactConsumerTestExt.class) @PactTestFor(providerName = "ProductService", port = "8080") public class ProductServiceContractTest { @Pact(consumer = "OrderService") public RequestResponsePact createPact(PactDslWithRequest r) { return r.given("a product with id 1 exists") .uponReceiving("a request for product by id") .path("/products/1") .method("GET") .willRespondWith() .status(200) .headers(Map.of("Content-Type", "application/json")) .body(new PactDslJsonBody() .stringValue("id", "1") .stringValue("name", "Laptop") .numberType("price", 1200.00)) .toPact(); } @Test void testGetProductById(MockServer mockServer) throws IOException { // API-ის გამოძახების ლოგიკა mockServer-ის საშუალებით // შემოწმება, რომ მომხმარებელი სწორად ახდენს მოკ-პასუხის დამუშავებას HttpResponse response = Request.Get(mockServer.getUrl() + "/products/1").execute().returnResponse(); assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); } } - მომხმარებლის ტესტების შესრულებისას გენერირდება კონტრაქტის ფაილი (
.json). - ეს ფაილი გამოქვეყნდება Pact Broker-ზე ან სხვა ცენტრალიზებულ საცავში.
- მიმწოდებელი (
Product Service) იყენებს Pact ბიბლიოთეკას (მაგ., Pact Provider Verifier) თავისი API-ის რეალიზაციის ვალიდაციისთვის კონტრაქტის საფუძველზე, რომელიც მიღებულია Pact Broker-დან:// მიმწოდებლის ტესტის მაგალითი Pact Provider Verifier-ით @Provider("ProductService") @PactFolder("relative/path/to/pacts") // ან Pact Broker public class ProductServiceVerificationTest { @TestTemplate @ExtendWith(PactVerificationInvocationContextProvider.class) public void verifyPact(PactVerificationContext context) { context.verifyInteraction(); } @State("a product with id 1 exists") public void productWithId1Exists() { // მონაცემების მომზადების ლოგიკა სერვისისთვის } // სერვისის URL-ის დამატება, სადაც ტესტირებადი სერვისი მუშაობს @BeforeEach void beforeEach(PactVerificationContext context) { context.setTarget(new HttpTestTarget("localhost", 8080)); } } - მიმწოდებლის მხარეზე ვალიდატორი რეალურ API-ს იძახის კონტრაქტის სპეციფიკაციის შესაბამისად და პასუხს ადარებს კონტრაქტში განსაზღვრულს.
კონტრაქტული ტესტირება მნიშვნელოვანი პრაქტიკაა სერვისებზე დაფუძნებული სისტემების სანდოობისა და შენარჩუნების უზრუნველსაყოფად.