Sobes.tech
Middle+

Μιλήστε για τον συμβατικό έλεγχο ενός μικροϋπηρεσίας.

sobes.tech AI

Απάντηση από AI

Οι δοκιμές συμβολαίου εστιάζουν στον έλεγχο της αλληλεπίδρασης μεταξύ μικροϋπηρεσιών σε επίπεδο API (συμβόλαιο). Ο στόχος είναι να διασφαλιστεί ότι ο καταναλωτής (η υπηρεσία που χρησιμοποιεί το API) και ο προμηθευτής (η υπηρεσία που παρέχει το API) ακολουθούν ένα συγκεκριμένο "συμβόλαιο" (σχήμα αιτήματος/απάντησης, μορφή δεδομένων, προσδοκίες).

Βασικές αρχές:

  • Καταναλωτής-καθοδηγούμενο: Οι δοκιμές βασίζονται στις προσδοκίες του καταναλωτή. Ο καταναλωτής καθορίζει ποια δεδομένα και μορφές χρειάζεται.
  • Διπλής κατεύθυνσης δοκιμή: Ελέγχεται τόσο αν ο καταναλωτής (μπορεί να εργαστεί με το τρέχον συμβόλαιο), όσο και αν ο προμηθευτής (αν η υλοποίησή του ανταποκρίνεται στις προσδοκίες) είναι σωστός.
  • Ταχύτητα: Οι δοκιμές εκτελούνται γρήγορα, συχνά εντός pipelines CI/CD, καθώς δεν απαιτείται η ανάπτυξη όλων των εξαρτώμενων υπηρεσιών.

Η διαδικασία περιλαμβάνει συνήθως:

  1. Ο καταναλωτής δημιουργεί δοκιμές που περιγράφουν τις προσδοκίες του από το API του προμηθευτή. Αυτές οι δοκιμές παράγουν ένα "συμβόλαιο".
  2. Το συμβόλαιο δημοσιεύεται (π.χ., σε ένα κεντρικό αποθετήριο).
  3. Ο προμηθευτής χρησιμοποιεί το δημοσιευμένο συμβόλαιο για να επαληθεύσει την υλοποίησή του API. Εκτελεί δοκιμές (συνήθως στην πλευρά του προμηθευτή) που ελέγχουν αν το API του ανταποκρίνεται στο συμβόλαιο.
  4. Σε περίπτωση διαφωνίας μεταξύ των προσδοκιών του καταναλωτή και της υλοποίησης του προμηθευτή, η δοκιμή αποτυγχάνει, υποδεικνύοντας παραβίαση του συμβολαίου.

Εργαλεία:

  • Pact (το πιο δημοφιλές)
  • Spring Cloud Contract
  • Swagger/OpenAPI με εργαλεία επικύρωσης

Πλεονεκτήματα:

  • Έγκαιρη ανίχνευση σφαλμάτων ολοκλήρωσης: Τα προβλήματα εντοπίζονται πριν από την ανάπτυξη.
  • Μείωση της ανάγκης για δοκιμές ολοκλήρωσης: Μειώνει την εξάρτηση από πολύπλοκες και αργές δοκιμές end-to-end.
  • Ανεξάρτητη δοκιμή: Επιτρέπει την ανεξάρτητη δοκιμή υπηρεσιών.
  • Καθορισμός προσδοκιών: Ορίζει ρητά το συμβόλαιο μεταξύ των υπηρεσιών.

Μειονεκτήματα:

  • Δεν αντικαθιστά πλήρως τις δοκιμές ολοκλήρωσης (ελέγχει μόνο την αλληλεπίδραση σε επίπεδο API).
  • Απαιτεί πειθαρχία στη διαχείριση εκδόσεων των συμβολαίων.
  • Μπορεί να είναι πιο δύσκολο για υπηρεσίες με πολύπλοκα συμβόλαια.

Παράδειγμα με Pact:

  1. Ο καταναλωτής (π.χ., 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
            HttpResponse response = Request.Get(mockServer.getUrl() + "/products/1").execute().returnResponse();
            assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
        }
    }
    
  2. Κατά την εκτέλεση των δοκιμών πλευράς καταναλωτή, δημιουργείται ένα αρχείο συμβολαίου (.json).
  3. Αυτό το αρχείο συμβολαίου δημοσιεύεται στο Pact Broker ή σε ένα άλλο κεντρικό αποθετήριο.
  4. Ο προμηθευτής (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));
        }
    }
    
  5. Ο επαληθευτής καλεί το πραγματικό API του προμηθευτή σύμφωνα με την προδιαγραφή του συμβολαίου και συγκρίνει την απάντηση που λαμβάνει με αυτή που αναμένεται στο συμβόλαιο.