Sobes.tech
Middle+

Pastāstiet par mikroservisa līguma testēšanu.

sobes.tech AI

Atbilde no AI

Sadarbības testēšana koncentrējas uz mijiedarbības pārbaudi starp mikroservisiem API (līguma) līmenī. Mērķis ir pārliecināties, ka patērētājs (pakalpojums, kas izmanto API) un piegādātājs (pakalpojums, kas nodrošina API) ievēro noteiktu "līgumu" (pieprasījumu/atbilžu shēmu, datu formātu, gaidāmo).

Galvenie principi:

  • Patērētāja vadība: Testi balstās uz patērētāja gaidām. Patērētājs nosaka, kādus datus un formātus viņš nepiecieš.
  • Divvirzienu testēšana: Pārbauda gan patērētāja pusi (vai viņš spēj strādāt ar pašreizējo līgumu), gan piegādātāja pusi (vai tā īstenojums atbilst patērētāja gaidām).
  • Ātrums: Testi tiek veikti ātri, bieži CI/CD ķēdēs, jo tie neprasa visu atkarīgo pakalpojumu izvietošanu.

Process parasti ietver:

  1. Patērētājs izveido testus, kas apraksta viņa gaidas no piegādātāja API. Šie testi ģenerē "līgumu".
  2. Līgums tiek publicēts (piemēram, centralizētā repozitārijā).
  3. Piegādātājs izmanto publicēto līgumu API īstenošanas pārbaudei. Viņš palaidīs testus (parasti piegādātāja pusē), kas pārbauda, vai viņa API atbilst līgumam.
  4. Ja ir neatbilstības starp patērētāja gaidām un piegādātāja īstenojumu, tests neizdodas, norādot līguma pārkāpumu.

Rīki:

  • Pact (vispopulārākais)
  • Spring Cloud Contract
  • Swagger/OpenAPI ar validācijas rīkiem

Priekšrocības:

  • Agrīna kļūdu atklāšana integrācijā: Problēmas ar saderību tiek konstatētas vēl pirms izvietošanas.
  • Samazina integrācijas testu nepieciešamību: Samazina atkarību no sarežģītiem un lēniem gala testiem.
  • Neatkarīga testēšana: Ļauj testēt pakalpojumus neatkarīgi viens no otra.
  • Skaidrs gaidu definējums: Skaidri nosaka līgumu starp pakalpojumiem.

Trūkumi:

  • Neaizstāj pilnībā integrācijas testus (tikai pārbauda mijiedarbību API līmenī).
  • Prasa disciplīnu līgumu versiju pārvaldībā.
  • Var būt sarežģītākas ļoti sarežģītu līgumu pakalpojumiem gadījumā.

Piemērs ar Pact:

  1. Patērētājs (piemēram, Order Service) izmanto Pact bibliotēku, lai izveidotu patērētāja puses testus.
    // Patērētāja testa piemērs ar 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 izsaukšanas loģika ar mockServer
            // Pārbauda, vai patērētājs pareizi apstrādā mock atbildi
            HttpResponse response = Request.Get(mockServer.getUrl() + "/products/1").execute().returnResponse();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        }
    }
    
  2. Izpildot patērētāja puses testus, tiek ģenerēts līguma fails (.json).
  3. Šis līguma fails tiek publicēts Pact Broker vai citā centralizētā repozitārijā.
  4. Piegādātājs (Product Service) izmanto Pact bibliotēku (piemēram, Pact Provider Verifier), lai pārbaudītu API īstenojumu, balstoties uz līguma specifikāciju, kas saņemta no Pact Broker.
    // Piegādātāja testa piemērs ar Pact Provider Verifier
    @Provider("ProductService")
    @PactFolder("relative/path/to/pacts") // vai izmantot 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() {
            // Sagatavošanas loģika piegādātāja datu stāvokļa testam
        }
    
        // Pievienojam piegādātāja URL, kur darbojas testētā pakalpojuma
        @BeforeEach
        void beforeEach(PactVerificationContext context) {
            context.setTarget(new HttpTestTarget("localhost", 8080));
        }
    }
    
  5. Piegādātāja verifieris izsauc reālo piegādātāja API saskaņā ar līguma specifikāciju un salīdzina saņemto atbildi ar gaidāmo līgumā.

Sadarbības testēšana ir svarīga prakse, nodrošinot sistēmu uzticamību un uzturēšanu, kas balstīta uz mikroservisiem.