Sobes.tech
Middle+

mikroxidmətin müqavilə testindən danışın.

sobes.tech Süni İntellekt

AI-dan cavab

Şərtname əsaslı testlər, mikroxidmətlər arasında API səviyyəsində (şərtname) qarşılıqlı əlaqəni yoxlamağa yönəlib. Məqsəd — istifadəçi (API-dən istifadə edən xidmət) və təminatçı (API-ni təqdim edən xidmət) müəyyən "şərtname" (sorğu/cavab sxemi, məlumat formatı, gözləntilər) riayət etdiklərindən əmin olmaq.

Əsas prinsiplər:

  • İstifadəçi-yonəldilmiş: Testlər istifadəçinin gözləntilərinə əsaslanır. İstifadəçi hansı məlumatlar və formatlar lazım olduğunu müəyyən edir.
  • İki tərəfli test: Həm istifadəçinin (mövcud şərtname ilə işləyə bilirmi), həm də təminatçının (onun həyata keçirilməsi istifadəçinin gözləntilərinə uyğundurmu) yoxlanmasını əhatə edir.
  • Sürət: Testlər sürətlə yerinə yetirilir, çox vaxt CI/CD boru xətlərində, çünki bütün asılı xidmətlərin yerləşdirilməsini tələb etmir.

Proses adətən aşağıdakı mərhələləri əhatə edir:

  1. İstifadəçi, təminatçının API-dən gözləntilərini təsvir edən testlər yaradır. Bu testlər "şərtname" yaradır.
  2. Şərtname (məsələn, mərkəzləşdirilmiş depozitorda) yayımlanır.
  3. Təminatçı, yayımlanmış şərtname əsasında API-nin həyata keçirilməsini yoxlayır. O, testləri işə salır (adətən təminatçı tərəfində), və API-nin şərtnameyə uyğun olub-olmadığını yoxlayır.
  4. Əgər istifadəçinin gözləntiləri ilə təminatçının həyata keçirilməsi arasında fərq olarsa, test uğursuz olur və şərtname pozuntusu göstərilir.

Alətlər:

  • Pact (ən məşhuru)
  • Spring Cloud Contract
  • Swagger/OpenAPI və validasiya alətləri

Üstünlüklər:

  • İnteqrasiya xətalarının erkən aşkarlanması: Problemlər yerləşdirmədən əvvəl aşkar edilir.
  • İnteqrasiya testlərinin ehtiyacını azaldır: Çətin və yavaş keçən son-əldə testlərinə olan asılılığı azaldır.
  • Müstəqil test: Xidmətləri bir-birindən müstəqil test etməyə imkan verir.
  • Gözləntilərin aydın müəyyənləşdirilməsi: Xidmətlər arasında şərtnameyi açıq şəkildə müəyyən edir.

Çətinliklər:

  • Tam inteqrasiya testlərinin yerini tutmur (yalnız API səviyyəsində qarşılıqlı əlaqəni yoxlayır).
  • Şərtnamələrin versiyalaşdırılmasında intizam tələb edir.
  • Çox mürəkkəb şərtnamələrə malik xidmətlər üçün çətin ola bilər.

Pact ilə istifadə nümunəsi:

  1. İstifadəçi (məsələn, Order Service) Pact kitabxanasından istifadə edərək consumer-tərəfli testlər yaradır.
    // Pact JVM ilə consumer-tərəfli test nümunəsi
    @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 çağırış logikası
            HttpResponse response = Request.Get(mockServer.getUrl() + "/products/1").execute().returnResponse();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        }
    }
    
  2. İstifadəçi-tərəfli testlər yerinə yetiriləndə şərtname faylı (.json) yaradılır.
  3. Bu şərtname faylı Pact Broker və ya digər mərkəzləşdirilmiş depozitora yerləşdirilir.
  4. Təminatçı (Product Service) Pact Provider Verifier kitabxanasından istifadə edərək API-nin həyata keçirilməsini şərtname əsasında yoxlayır.
    // Təminatçı üçün nümunə test
    @Provider("ProductService")
    @PactFolder("relative/path/to/pacts") // və ya Pact Broker istifadə edin
    public class ProductServiceVerificationTest {
    
        @TestTemplate
        @ExtendWith(PactVerificationInvocationContextProvider.class)
        public void verifyPact(PactVerificationContext context) {
            context.verifyInteraction();
        }
    
        @State("a product with id 1 exists")
        public void productWithId1Exists() {
            // Test üçün məlumatların vəziyyətini hazırlamaq
        }
    
        // Test edilən xidmətin URL-ini əlavə edin
        @BeforeEach
        void beforeEach(PactVerificationContext context) {
            context.setTarget(new HttpTestTarget("localhost", 8080));
        }
    }
    
  5. Verifier, təminatçının real API-ni çağırır və alınan cavabı şərtname ilə müqayisə edir.