Cypress är bra för front-end-testning, men det kan testa dina API: er effektivt också.
Cypress är ett populärt testramverk skräddarsytt för JavaScript-applikationer. Även om det i första hand är utformat för att testa UI-komponenter och interaktioner med UI-element i en webbläsare, är det också väl lämpad för att testa API: er. Du kan använda ramverket för att testa RESTful API: er via HTTP-förfrågningar och validera svar.
Cypress låter dig skriva omfattande tester som spänner över hela spektrumet av din webbapplikations arbetsflöde.
Komma igång med API-testning med Cypress
Cypress hjälper dig att verifiera att dina API: er fungerar som du förväntar dig. Denna process inkluderar vanligtvis att testa API: ns slutpunkter, indata och HTTP-svar. Du kan verifiera integrationen med alla externa tjänster och bekräfta att felhanteringsmekanismerna fungerar korrekt.
Att testa dina API: er säkerställer att de är funktionella, pålitliga och uppfyller behoven hos appar som är beroende av dem. Det hjälper till att identifiera och fixa buggar tidigt, vilket förhindrar att problem uppstår i produktionen.
Cypress är ett bra UI-testverktyg, som används av några av de populära JavaScript-ramverk. Dess förmåga att göra och testa HTTP-förfrågningar gör den lika effektiv vid testning av API: er.
Den gör detta genom att använda Node.js som sin motor för att göra HTTP-förfrågningar och hantera deras svar.
Du kan hitta detta projekts kod i dess GitHub förvaret.
Skapa ett Express.js REST API
För att starta, skapa en Express-webbserver, och installera det här paketet i ditt projekt:
npm install cors
Lägg sedan till Cypress-paketet till ditt projekt:
npm install cypress --save-dev
Äntligen, uppdatera din package.json fil för att inkludera detta testskript:
"test": "npx cypress open"
Definiera API-kontrollerna
I ett verkligt fall skulle du göra API-anrop för att läsa och skriva data från en databas eller ett externt API. Men för det här exemplet kommer du att simulera och testa sådana API-anrop genom att lägga till och hämta användardata från en array.
I rotkatalogen i din projektmapp skapar du en controllers/userControllers.js fil och lägg till följande kod.
Först, definiera a registrera användare kontrollfunktion som kommer att hantera användarregistreringsvägen. Det kommer att extrahera användarens data från begärandekroppen, skapa ett nytt användarobjekt och lägga till det i användare array. Om processen lyckas ska den svara med en 201-statuskod och ett meddelande som indikerar att den har registrerat användaren.
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!!' });
}
};
Lägg till en andra funktion—getUsers— för att hämta användardata från arrayen och returnera den som JSON-svar.
exports.getUsers = async (req, res) => {
try {
res.json(users);
} catch (error) {
console.error(error);
res.status(500).send({ message: 'An error occurred!!' });
}
};
Slutligen kan du också simulera inloggningsförsök. Lägg till den här koden i samma fil för att kontrollera om det angivna användarnamnet och lösenordet matchar någon användardata i användare array:
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!!' });
}
};
Definiera API-rutter
För att definiera rutterna för ditt Express REST API, skapa ett nytt routes/userRoutes.js fil i rotkatalogen och lägg till denna kod till den:
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;
Uppdatera filen Server.js
Uppdatera server.js fil för att konfigurera API enligt följande:
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;
Ställ in testmiljön
Med demo-API: et på plats är du redo att ställa in testmiljön. Starta utvecklingsservern med detta terminalkommando:
node server.js
Kör sedan testskriptkommandot i en separat terminal:
npm run test
Detta kommando startar Cypress-skrivbordsklienten, som tillhandahåller testmiljön. När den är öppen klickar du på E2E-testning knapp. End-to-end-tester säkerställer att du testar Express API som helhet, vilket innebär att Cypress kommer att ha tillgång till webbservern, rutterna och tillhörande kontrollerfunktioner.
Klicka sedan Fortsätta för att lägga till Cypress-konfigurationsfiler.
När installationsprocessen är klar bör du se en ny Cypress-mapp i ditt projekt. Cypress kommer också att lägga till en cypress.config.js fil som innehåller konfigurationsinställningarna för dina tester.
Fortsätt och uppdatera den här filen så att den inkluderar din serverbas-URL enligt följande:
const { defineConfig } = require("cypress");
module.exports = defineConfig({
chromeWebSecurity: false,
e2e: {
baseUrl: 'http://localhost: 5000',
setupNodeEvents(on, config) {
},
},
});
Skriv testfallen
Nu är du redo att skriva några testfall. Välj först webbläsaren där Cypress ska starta för att köra testerna från alternativen som finns tillgängliga på Cypress-klienten.
Klicka sedan på Skapa ny spec för att skapa din testfil och ange ett namn. Klicka sedan Skapa spec.
Öppna nu cypress/fixtures/example.json fil och uppdatera dess innehåll med följande användaruppgifter. Fixturer är filer som innehåller statisk testdata som du kan använda i testfallen.
{
"username": "testuser",
"password": "password123"
}
Cypress ger en cy.request metod för att göra HTTP-förfrågningar till en webbserver. Du kan använda den för att testa olika typer av HTTP-slutpunkter som hanterar olika operationer inklusive GET, POST, PUT och DELETE.
För att testa de tre API-rutter som du definierade tidigare, börja med att beskriva testfallet för registerslutpunkten. Detta testfall bör verifiera att slutpunkten fungerar korrekt genom att framgångsrikt registrera en ny användare och validera påståendena.
Öppna cypress/e2e/user.routes.spec.cy.js fil och uppdatera dess innehåll med följande kod.
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');
});
});
});
I det här testet kommer Cypress att ladda testdatan i fixturfilen och göra POST-förfrågningar till den angivna slutpunkten med data i förfrågningskroppen. Om alla påståenden godkänns kommer testfallet att godkännas. Annars kommer det att misslyckas.
Det är värt att notera att syntaxen för Cypress-tester mycket liknar syntaxen som används i Mocha-tester, som Cypress har anammat.
Beskriv nu testet för användare rutt. Testet bör verifiera att svaret innehåller användardata när förfrågningar görs till denna slutpunkt. För att uppnå detta, lägg till följande kod i beskriva testblock.
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);
});
});
});
Slutligen, inkludera ett testfall som testar inloggningsslutpunkten och bekräftar att svarsstatusen är 200, vilket indikerar ett lyckat inloggningsförsök.
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);
});
});
});
});
För att köra testerna, gå tillbaka till webbläsarversionen som hanteras av Cypress och välj den specifika testfil du vill köra.
Cypress testlöpare kommer att köra testerna och registrera deras resultat, och visar statusen godkänd eller underkänd för varje testfall.
Exemplen ovan illustrerar hur du kan testa olika rutter och deras motsvarande kontrollerfunktioner för att säkerställa deras funktionalitet och förväntade beteende. Även om det är viktigt att testa funktionaliteten hos API: er bör du inte begränsa testomfattningen enbart till denna aspekt.
En omfattande API-teststrategi bör också inkludera tester av prestanda, belastning och integration med andra tjänster. Genom att inkludera olika typer av testmetoder i din strategi kan du uppnå en grundlig testtäckning och säkerställa att dina API: er är både funktionella och pålitliga innan du distribuerar din kod till produktion.
Testa hela din webbupplevelse med Cypress
Cypress är ett fantastiskt verktyg för att testa webbapplikationer, som sömlöst täcker tester för både front-end och back-end.
Med dess användarvänliga testfunktioner kan du enkelt och snabbt sätta upp en testmiljö på en och samma plattform. Du kan sedan använda den för att noggrant testa olika aspekter av din applikation och garantera förstklassig prestanda.