Sobes.tech
Middle+

Beszéljen a mikroservice szerződéses teszteléséről.

sobes.tech MI

Válasz az MI-től

A szerződés alapú tesztelés a mikro-szolgáltatások közötti interakció ellenőrzésére összpontosít az API (szerződés) szintjén. A cél annak biztosítása, hogy a fogyasztó (az API-t használó szolgáltatás) és a szolgáltató (az API-t nyújtó szolgáltatás) megfeleljenek egy adott "szerződésnek" (kérés/válasz séma, adatformátum, elvárások).

Fő elvek:

  • Fogyasztó-irányított: A tesztek a fogyasztó elvárásain alapulnak. A fogyasztó határozza meg, milyen adatokra és formátumokra van szüksége.
  • Kétirányú tesztelés: Ellenőrzi, hogy a fogyasztó (tud-e a jelenlegi szerződéssel dolgozni) és a szolgáltató (megfelel-e a megvalósítása az elvárásoknak) is megfelel-e.
  • Gyorsaság: A tesztek gyorsan végrehajtódnak, gyakran CI/CD csővezetékekben, mivel nem igényelnek minden függő szolgáltatás telepítését.

A folyamat általában a következőket foglalja magában:

  1. A fogyasztó létrehoz olyan teszteket, amelyek leírják az elvárásait a szolgáltató API-jával kapcsolatban. Ezek a tesztek "szerződést" generálnak.
  2. A szerződés közzéteszik (például központosított tárhelyen).
  3. A szolgáltató a közzétett szerződést használja az API megvalósításának ellenőrzésére. A teszteket (általában a szolgáltató oldalán) futtatja, amelyek ellenőrzik, hogy az API megfelel-e a szerződésnek.
  4. Ha eltérés van a fogyasztó elvárásai és a szolgáltató megvalósítása között, a teszt megbukik, jelezve a szerződés megsértését.

Eszközök:

  • Pact (legnépszerűbb)
  • Spring Cloud Contract
  • Swagger/OpenAPI validációs eszközökkel

Előnyök:

  • Korai hibák felismerése az integrációban: A problémák a telepítés előtt felismerhetők.
  • Csökkenti az integrációs tesztek szükségességét: Csökkenti a bonyolult és lassú végpont végig tesztek iránti függőséget.
  • Független tesztelés: Lehetővé teszi a szolgáltatások független tesztelését.
  • Elvárások egyértelmű meghatározása: Világosan meghatározza a szerződést a szolgáltatások között.

Hátrányok:

  • Nem helyettesíti teljes mértékben az integrációs teszteket (csak az API szintjén lévő interakciót ellenőrzi).
  • Szükség van a szerződések verziókezelésében való fegyelmezettségre.
  • Nehezebb lehet nagyon összetett szerződésekkel rendelkező szolgáltatások esetén.

Példa Pact használatával:

  1. A fogyasztó (például, Order Service) a Pact könyvtárat használva hoz létre consumer-oldali teszteket.
    // Példa consumer-oldali tesztre Pact JVM-mel
    @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 hívási logika
            HttpResponse response = Request.Get(mockServer.getUrl() + "/products/1").execute().returnResponse();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        }
    }
    
  2. A fogyasztói oldal tesztjeinek futtatásakor generálódik egy szerződésfájl (.json).
  3. Ez a szerződésfájl közzéteszik a Pact Brokerben vagy más központosított tárhelyen.
  4. A szolgáltató (Product Service) a Pact Provider Verifier könyvtárat használva ellenőrzi API megvalósítását a szerződés alapján, amit a Pact Brokerből kapott.
    // Szolgáltató teszt példája Pact Provider Verifier-rel
    @Provider("ProductService")
    @PactFolder("relative/path/to/pacts") // vagy 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() {
            // Az adatok állapotának előkészítése a szolgáltatónál
        }
    
        // A tesztelt szolgáltatás URL-jének hozzáadása
        @BeforeEach
        void beforeEach(PactVerificationContext context) {
            context.setTarget(new HttpTestTarget("localhost", 8080));
        }
    }
    
  5. A verifier meghívja a valódi API-t a szolgáltatónál a szerződés specifikációja szerint, és összehasonlítja a kapott választ a szerződésben megadott elvárással.