Cypress doskonale nadaje się do testowania front-endu, ale może również skutecznie testować interfejsy API.
Cypress to popularny framework testowy dostosowany do aplikacji JavaScript. Chociaż jest przeznaczony głównie do testowania komponentów interfejsu użytkownika i interakcji z elementami interfejsu użytkownika w przeglądarce, jest również przeznaczony dobrze nadaje się do testowania interfejsów API. Możesz użyć platformy do testowania interfejsów API RESTful za pośrednictwem żądań HTTP i sprawdzania poprawności odpowiedzi.
Cypress umożliwia pisanie kompleksowych testów obejmujących pełne spektrum przepływu pracy aplikacji internetowej.
Rozpoczęcie testowania API przy użyciu Cypress
Cypress pomaga sprawdzić, czy interfejsy API działają zgodnie z oczekiwaniami. Proces ten zazwyczaj obejmuje testowanie punktów końcowych interfejsu API, danych wejściowych i odpowiedzi HTTP. Możesz zweryfikować integrację z dowolnymi usługami zewnętrznymi i upewnić się, że mechanizmy obsługi błędów działają poprawnie.
Testowanie interfejsów API gwarantuje, że są funkcjonalne, niezawodne i spełniają potrzeby zależnych od nich aplikacji. Pomaga wcześnie identyfikować i naprawiać błędy, zapobiegając występowaniu problemów na produkcji.
Cyprys to świetne narzędzie do testowania interfejsu użytkownika, używane przez niektórych popularne frameworki JavaScript. Jego zdolność do tworzenia i testowania żądań HTTP sprawia, że jest równie skuteczny w testowaniu interfejsów API.
Robi to, używając Node.js jako silnika do wysyłania żądań HTTP i obsługi ich odpowiedzi.
Kod tego projektu znajdziesz w jego pliku GitHub magazyn.
Utwórz interfejs API REST Express.js
Rozpocząć, utwórz serwer WWW Expressi zainstaluj ten pakiet w swoim projekcie:
npm install cors
Następnie dodaj pakiet Cypress do swojego projektu:
npm install cypress --save-dev
Na koniec zaktualizuj swój pakiet.json plik zawierający ten skrypt testowy:
"test": "npx cypress open"
Zdefiniuj kontrolery API
W prawdziwym przypadku wykonywałbyś wywołania API w celu odczytu i zapisu danych z bazy danych lub zewnętrznego API. Jednak w tym przykładzie będziesz symulować i testować takie wywołania API, dodając i pobierając dane użytkownika z tablicy.
W katalogu głównym folderu projektu utwórz plik kontrolery/userControllers.js plik i dodaj następujący kod.
Najpierw zdefiniuj a zarejestruj użytkownika funkcja kontrolera, która będzie zarządzać ścieżką rejestracji użytkowników. Wyodrębni dane użytkownika z treści żądania, utworzy nowy obiekt użytkownika i doda go do użytkownicy szyk. Jeśli proces się powiedzie, powinien odpowiedzieć kodem statusu 201 i komunikatem informującym, że zarejestrował użytkownika.
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!!' });
}
};
Dodaj drugą funkcję —pobierzUżytkownicy— aby pobrać dane użytkownika z tablicy i zwrócić je jako odpowiedź JSON.
exports.getUsers = async (req, res) => {
try {
res.json(users);
} catch (error) {
console.error(error);
res.status(500).send({ message: 'An error occurred!!' });
}
};
Na koniec możesz także symulować próby logowania. W tym samym pliku dodaj ten kod, aby sprawdzić, czy podana nazwa użytkownika i hasło pasują do jakichkolwiek danych użytkownika w pliku użytkownicy szyk:
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!!' });
}
};
Zdefiniuj trasy API
Aby zdefiniować trasy dla interfejsu API Express REST, utwórz nowy plik Routes/userRoutes.js plik w katalogu głównym i dodaj do niego ten kod:
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
Zaktualizuj serwer.js plik, aby skonfigurować API w następujący sposób:
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;
Skonfiguruj środowisko testowe
Po uruchomieniu demonstracyjnego interfejsu API możesz skonfigurować środowisko testowe. Uruchom serwer programistyczny za pomocą tego polecenia terminala:
node server.js
Następnie uruchom polecenie skryptu testowego w osobnym terminalu:
npm run test
To polecenie uruchomi klienta komputerowego Cypress, który zapewnia środowisko testowe. Po otwarciu kliknij Testowanie E2E przycisk. Kompleksowe testy zapewniają, że testujesz Express API jako całość, co oznacza, że Cypress będzie miał dostęp do serwera WWW, tras i powiązanych funkcji kontrolera.
Następnie kliknij Kontynuować aby dodać pliki konfiguracyjne Cypress.
Po zakończeniu procesu instalacji powinieneś zobaczyć nowy folder Cypress w swoim projekcie. Cypress doda również cypress.config.js plik zawierający ustawienia konfiguracyjne dla Twoich testów.
Śmiało, zaktualizuj ten plik, aby zawierał podstawowy adres URL serwera w następujący sposób:
const { defineConfig } = require("cypress");
module.exports = defineConfig({
chromeWebSecurity: false,
e2e: {
baseUrl: 'http://localhost: 5000',
setupNodeEvents(on, config) {
},
},
});
Napisz przypadki testowe
Teraz możesz już napisać kilka przypadków testowych. Najpierw wybierz przeglądarkę, w której uruchomi się Cypress, aby uruchomić testy z opcji dostępnych w kliencie Cypress.
Następnie kliknij Utwórz nową specyfikację, aby utworzyć plik testowy i podać nazwę. Następnie kliknij Utwórz specyfikację.
Teraz otwórz cypress/fixtures/example.json plik i zaktualizuj jego zawartość przy użyciu następujących poświadczeń użytkownika. Fixtures to pliki zawierające statyczne dane testowe, których można używać w przypadkach testowych.
{
"username": "testuser",
"password": "password123"
}
Cyprys zapewnia cy.żądanie metoda wysyłania żądań HTTP do serwera WWW. Można go używać do testowania różnych typów punktów końcowych HTTP, które zarządzają różnymi operacjami, w tym GET, POST, PUT i DELETE.
Aby przetestować trzy zdefiniowane wcześniej trasy API, zacznij od opisania przypadku testowego dla punktu końcowego rejestru. Ten przypadek testowy powinien sprawdzić, czy punkt końcowy działa poprawnie, pomyślnie rejestrując nowego użytkownika i sprawdzając potwierdzenia.
Otworzyć cypress/e2e/user.routes.spec.cy.js plik i zaktualizuj jego zawartość za pomocą następującego kodu.
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');
});
});
});
W tym teście Cypress załaduje dane testowe do pliku urządzenia i wyśle żądania POST do określonego punktu końcowego z danymi w treści żądania. Jeśli wszystkie twierdzenia zostaną spełnione, przypadek testowy zostanie zaliczony. W przeciwnym razie zakończy się niepowodzeniem.
Warto zauważyć, że składnia testów Cypress bardzo przypomina składnię używaną w testach Mocha, którą przyjął Cypress.
Teraz opisz test dla użytkownicy trasa. Test powinien sprawdzić, czy odpowiedź zawiera dane użytkownika, gdy żądania są wysyłane do tego punktu końcowego. Aby to osiągnąć, dodaj następujący kod w pliku opisać blok testowy.
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);
});
});
});
Na koniec dołącz przypadek testowy, który przetestuje punkt końcowy logowania i potwierdzi, że stan odpowiedzi wynosi 200, co oznacza pomyślną 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 uruchomić testy, wróć do wersji przeglądarki zarządzanej przez Cypress i wybierz konkretny plik testowy, który chcesz uruchomić.
Osoba przeprowadzająca testy Cypress przeprowadzi testy i zapisze ich wyniki, pokazując status pozytywnego lub negatywnego wyniku każdego przypadku testowego.
Powyższe przykłady ilustrują, jak można testować różne trasy i odpowiadające im funkcje kontrolera, aby zapewnić ich funkcjonalność i oczekiwane zachowanie. Choć testowanie funkcjonalności API jest niezbędne, nie należy ograniczać zakresu testowania wyłącznie do tego aspektu.
Kompleksowa strategia testowania API powinna obejmować także testy wydajności, obciążenia i integracji z innymi usługami. Włączając różne rodzaje metod testowania zgodnie ze swoją strategią możesz osiągnąć dokładny zakres testów i upewnić się, że interfejsy API są zarówno funkcjonalne, jak i niezawodne, przed wdrożeniem kodu w środowisku produkcyjnym.
Testowanie całego doświadczenia internetowego przy użyciu Cypress
Cypress to fantastyczne narzędzie do testowania aplikacji webowych, płynnie obejmujące testy zarówno front-endu, jak i backendu.
Dzięki przyjaznym dla użytkownika funkcjom testowym możesz łatwo i szybko skonfigurować środowisko testowe na jednej platformie. Można go następnie użyć do dokładnego przetestowania różnych aspektów aplikacji i zagwarantowania najwyższej wydajności.