Contents

Jak testować interfejsy API REST Express.js przy użyciu Cypress

Cypress to popularny framework testowy dostosowany do aplikacji JavaScript. Chociaż jest on przeznaczony głównie do testowania komponentów UI i interakcji z elementami UI w przeglądarce, dobrze nadaje się również do testowania interfejsów API. Za jego pomocą można testować interfejsy API RESTful za pośrednictwem żądań HTTP i sprawdzać poprawność odpowiedzi.

Cypress umożliwia tworzenie obszernych zestawów testów obejmujących cały zakres operacyjny aplikacji internetowej, od inicjacji do zakończenia.

Pierwsze kroki z testowaniem API przy użyciu Cypress

Cypress umożliwia walidację interfejsu programowania aplikacji (API) w celu zapewnienia, że działa on zgodnie z zamierzonym projektem. W ramach tego procesu testowane są punkty końcowe API, parametry wejściowe i odpowiedzi protokołu transferu hipertekstu (HTTP). Dodatkowo weryfikowana jest kompatybilność z wszelkimi systemami zewnętrznymi oraz funkcjonalność mechanizmów obsługi błędów.

/pl/images/cypress-homepage.jpg

Zapewnienie funkcjonalności, niezawodności i przydatności do integracji aplikacji interfejsów API poprzez testowanie ma kluczowe znaczenie. Wczesna identyfikacja i naprawa wszelkich problemów zapobiegnie potencjalnym problemom pojawiającym się w działającym środowisku.

Cypress to świetne narzędzie do testowania interfejsu użytkownika, używane przez niektóre z popularnych frameworków JavaScript. Jego zdolność do tworzenia i testowania żądań HTTP sprawia, że jest równie skuteczny w testowaniu interfejsów API.

Aplikacja wykorzystuje Node.js jako technologię bazową do wykonywania żądań HTTP i efektywnego zarządzania odpowiadającymi im odpowiedziami.

Kod źródłowy tego projektu jest dostępny za pośrednictwem dedykowanego repozytorium GitHub.

Tworzenie interfejsu API Express.js REST

Aby rozpocząć proces, należy utworzyć serwer WWW Express jako podstawę i włączyć ten pakiet do struktury projektu.

 npm install cors 

Aby włączyć funkcjonalność Cypress do bieżącego projektu, należy wykonać szereg kroków, które obejmują instalację i konfigurację niezbędnych zależności. Proces ten obejmuje dodanie pakietu Cypress jako zasobu w pliku konfiguracyjnym lub repozytorium projektu, określenie jego wersji i lokalizacji w systemie oraz upewnienie się, że jest on odpowiednio zintegrowany z innymi komponentami i modułami w aplikacji. Gdy to zostanie osiągnięte, można rozpocząć korzystanie z Cypress do automatyzacji i testowania różnych aspektów procesu tworzenia oprogramowania, w tym interakcji użytkownika, wywołań API i żądań sieciowych.

 npm install cypress --save-dev 

Na koniec zmodyfikuj plik package.json , aby uwzględnić wyżej wymieniony skrypt testowy.

 "test": "npx cypress open" 

Zdefiniuj kontrolery API

Aby zademonstrować funkcjonalność naszej aplikacji w praktycznym scenariuszu, będziemy symulować proces wykonywania wywołań API w celu interakcji z bazą danych lub zewnętrznym interfejsem API. Podczas gdy rzeczywista implementacja obejmowałaby takie interakcje, dla jasności użyjemy tablicy do przechowywania i pobierania danych użytkownika w zakresie tego przykładu.

W głównym katalogu struktury folderów projektu utwórz podkatalog “controllers”, a w nim wygeneruj plik “userControllers.js”. W tym pliku umieść następującą zawartość.

Rzeczywiście, zacznijmy od stworzenia

 const users = [];

exports.registerUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const newUser = { username, password };
    users.push(newUser);
    res.status(201).send({ message: 'User registered successfully' });
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
};

Zmodyfikuj istniejącą funkcję getAllUsers , aby uwzględnić dodatkową funkcjonalność, która pobiera dane użytkownika z tablicy i zwraca je w postaci odpowiedzi JSON. Ta nowa funkcja jest określana jako getUsers .

 exports.getUsers = async (req, res) => {
  try {
    res.json(users);
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
}; 

Podsumowując, można wykonywać symulowane próby logowania poprzez włączenie określonego fragmentu kodu do dostarczonego skryptu. Ta dodatkowa funkcjonalność pozwala na sprawdzenie, czy dany zestaw poświadczeń poprawnie odpowiada informacjom przechowywanym w tablicy “users”.

 exports.loginUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const user = users.find((u) =>
           u.username === username && u.password === password);

    if (user) {
      res.status(200).send({ message: 'Login successful' });
    } else {
      res.status(401).send({ message: 'Invalid credentials' });
    }
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'An error occurred!!' });
  }
}; 

Definiowanie tras API

Aby ustalić konfigurację routingu dla aplikacji RESTful opartej na Express, należy wygenerować nowy plik o nazwie “routes/userRoutes.js” znajdujący się w katalogu głównym projektu. Ten konkretny plik będzie zawierał następującą zawartość:

 const express = require('express');
const router = express.Router();
const userControllers = require('../controllers/userControllers');

const baseURL = '/v1/api/';

router.post(baseURL \\+ 'register', userControllers.registerUser);
router.get(baseURL \\+ 'users', userControllers.getUsers);
router.post(baseURL \\+ 'login', userControllers.loginUser);

module.exports = router; 

Zaktualizuj plik server.js

Zmodyfikuj zawartość pliku server.js , dostosowując jego konfigurację zgodnie z poniższymi specyfikacjami:

 const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

const userRoutes = require('./routes/userRoutes');
app.use('/', userRoutes);

app.listen(port, () => {
  console.log(`Server is listening at http://localhost:${port}`);
});

module.exports = app;

Konfiguracja środowiska testowego

Aby utworzyć środowisko testowe dla demonstracyjnego interfejsu programowania aplikacji (API), rozpocznij inicjalizację serwera deweloperskiego, wykonując wspomnianą instrukcję terminala.

 node server.js 

Następnie wykonaj skrypt testowy za pomocą pliku wykonywalnego “test” z innego okna terminala lub konsoli:

 npm run test 

Wykonanie tej instrukcji zainicjuje wdrożenie aplikacji desktopowej Cypress, która służy jako platforma ewaluacyjna. Po pomyślnej instalacji należy przejść do zakładki “E2E Testing” i aktywować ją, klikając wskazany przycisk. Kompleksowa ocena obejmuje kompleksową ocenę całego interfejsu Express API, w tym serwera WWW, konfiguracji tras i powiązanych modułów funkcyjnych sterownika.

/pl/images/cypress-testing-ui-client.jpg

Przejdź dalej, klikając “Kontynuuj” w celu włączenia plików konfiguracyjnych Cypress.

/pl/images/cypress-configuration-files.jpg

Po pomyślnym zakończeniu procedury wstępnej konfiguracji, użytkownicy powinni zaobserwować obecność nowo utworzonego katalogu Cypress w swoim projekcie. Dodatkowo, Cypress automatycznie generuje plik cypress.config.js, który zawiera parametry konfiguracyjne zestawu testowego.

Zachęcamy do modyfikacji tego dokumentu poprzez włączenie adresu bazowego serwera w następujący sposób:

 const { defineConfig } = require("cypress");

module.exports = defineConfig({
  chromeWebSecurity: false,
  e2e: {
    baseUrl: 'http://localhost:5000',
    setupNodeEvents(on, config) {
     },
  },
}); 

Pisanie przypadków testowych

Aby rozpocząć pisanie przypadków testowych za pomocą Cypress, zacznij od wybrania żądanej przeglądarki internetowej do testowania spośród dostępnych opcji w interfejsie Cypress.

/pl/images/testing-browsers-options.jpg

Po kliknięciu przycisku “Create new spec”, należy podać tytuł przypadku testowego, a następnie kliknąć opcję “Create spec”.

/pl/images/new-spec-file.jpg

Prosimy o edycję zawartości pliku “cypress/fixtures/example.json” poprzez wprowadzenie podanych poświadczeń użytkownika. Pliki urządzeń służą jako repozytoria stacjonarnych danych testowych, które można wykorzystać w zestawach testów.

 {
  "username": "testuser",
  "password": "password123"
} 

Cypress oferuje wszechstronne podejście do wykonywania żądań HTTP za pomocą wbudowanego polecenia cy.request . Ta funkcja umożliwia programistom interakcję z różnymi typami punktów końcowych HTTP obsługujących różne funkcje, takie jak GET, POST, PUT i DELETE.

Aby zweryfikować funkcjonalność trzech wcześniej zaimplementowanych punktów końcowych API, musimy rozpocząć od sformułowania scenariusza testowego dla procesu rejestracji. Głównym celem tego scenariusza testowego będzie potwierdzenie, że punkt końcowy działa zgodnie z przeznaczeniem, skutecznie tworząc nowe konto użytkownika i weryfikując powiązane asercje.

Otwórz plik “cypress/e2e/user.routes.spec.cy.js” i zastąp jego istniejącą zawartość dostarczonym fragmentem kodu poniżej:javascriptdescribe(‘User Routes’, () => {it(‘powinien mieć odpowiedni pasek nawigacyjny na urządzeniach mobilnych’, (done) => {cy.visit(’/’)cy. get(’#app-title’).should(‘have.text’, ‘My Website’);cy.get(‘burger’).click();cy.get(’#menu-toggle’).should(‘be.visible’);cy.get(’#profile-btn’).click({ force: true });cy.url().should(‘include’, ‘/dashboard’);cy.get(’#nav-links li:nth-child(1) a’).

 describe('User Routes', () => {
  it('registers a new user', () => {
     cy.fixture('example').then((testUser) => {
       cy.request({
        method: 'POST',
        url: `${baseUrl}/v1/api/register`,
         body: testUser,
       }).then((response) => {
         expect(response.status).to.eq(201);
         expect(response.body.message).to.eq('User registered successfully');
      });
    });
  }); 

Podczas wykonywania tej oceny Cypress wykorzysta informacje zawarte w pliku konfiguracji do wygenerowania serii żądań POST skierowanych do wyznaczonego punktu końcowego, wraz ze szczegółami zawartymi w treści żądania. Jeśli każde z twierdzeń zostanie zweryfikowane jako dokładne, instancja testowa zostanie uznana za udaną i zaliczoną. I odwrotnie, jeśli jakakolwiek asercja nie spełnia ustalonych kryteriów, ogólny przypadek testowy zostanie uznany za nieudany i oznaczony jako nieudany.

Testy Cypress są zbudowane przy użyciu składni podobnej do tej stosowanej w testach Mocha, ponieważ Cypress zintegrował ten framework testowy.

Aby zweryfikować, czy odpowiedź wygenerowana przez użytkowników punkt końcowy dostarcza odpowiednich informacji o użytkowniku po otrzymaniu żądania we wspomnianej lokalizacji, konieczne jest uwzględnienie następujących środków w obejmującym opisie zestawu testów.

   it('gets users data and the username matches test data', () => {
    cy.fixture('example').then((expectedUserData) => {
      cy.request({
        method: 'GET',
        url: `${baseUrl}/v1/api/users`,
      }).then((response) => {
        expect(response.status).to.eq(200);
        const username = response.body[0].username;
        expect(username).to.eq(expectedUserData.username);
      });
    });
  }); 

Wreszcie, należy uwzględnić scenariusz testowy w celu oceny punktu końcowego logowania i potwierdzenia, że status odpowiedzi HTTP wynosi 200, co oznacza udaną próbę logowania.

   it('logs in a user', () => {
     cy.fixture('example').then((loginData) => {
      cy.request({
        method: 'POST',
        url: `${baseUrl}/v1/api/login`,
         body: loginData,
       }).then((response) => {
        expect(response.status).to.eq(200);
      });
    });
  });
}); 

Aby wykonać testy, przejdź z powrotem do aplikacji internetowej monitorowanej przez Cypress i wybierz konkretny skrypt testowy, który chcesz wykonać spośród dostępnych.

/pl/images/spec-files-on-cypress-client.jpg

Wykonanie programu uruchamiającego testy Cypress spowoduje przetestowanie i udokumentowanie wyników dla każdego indywidualnego przypadku testowego, wyświetlając, czy zostały one zaliczone, czy nie.

/pl/images/user-routes-test-cases-1.jpg

Aby kompleksowo ocenić wydajność i niezawodność interfejsu API, kluczowe jest rozszerzenie zakresu testowania poza zwykłe badanie jego aspektów funkcjonalnych. Badając dodatkowe warstwy interakcji między interfejsem programowania aplikacji a innymi komponentami zaangażowanymi w przetwarzanie żądań lub odpowiedzi, można uzyskać bardziej kompleksową ocenę ogólnej wydajności i efektywności systemu.

Wszechstronne podejście do testowania API obejmuje nie tylko funkcjonalność, ale także aspekty takie jak wydajność, skalowalność i integracja z systemami zewnętrznymi. W tym celu włączenie różnorodnych metod testowania do strategii testowania jest niezbędne do osiągnięcia wyczerpującego pokrycia testami oraz zapewnienia niezawodności i stabilności interfejsów API aplikacji przed ich wdrożeniem w środowisku rzeczywistym.

Testowanie całego doświadczenia sieciowego przy użyciu Cypress

Cypress to wyjątkowe źródło do łatwej oceny aplikacji internetowych, obejmujące kompleksową ocenę zarówno interfejsu użytkownika, jak i komponentów po stronie serwera.

Wykorzystanie naszych intuicyjnych narzędzi testowych pozwala na łatwe stworzenie kompleksowego środowiska testowego w ramach jednej platformy. Umożliwia to kompleksową ocenę różnych aspektów oprogramowania, zapewniając optymalną funkcjonalność i wyjątkową wydajność.