Test dine Enonic-apper med Jest og Mock XP
Få verdifull innsikt i å benytte Jest sammen med Mock XP for å sikre at dine Enonic-applikasjoner kjører smertefritt.
Written by Thomas Sigdestad on
Få verdifull innsikt i å benytte Jest sammen med Mock XP for å sikre at dine Enonic-applikasjoner kjører smertefritt.
Written by Thomas Sigdestad on
Vi holdt nylig en Meetup på kontoret vårt, hvor Alan Semenov, VP Engineering i Enonic, holdt en presentasjon om testing av Enonic-apper med Jest og Mock XP.
Tidligere har vi fått tilbakemeldinger som antyder at vår tilnærming til testing av JavaScript-kode kan trenge forbedring. Vi har hørt dere, og som svar dykker vi ned i prosessen med å skrive effektive tester for Enonic-apper. Ukonvensjonelt nok starter vi med en FAQ-seksjon for å svare på vanlige spørsmål og legge et solid grunnlag før vi går inn i detaljene.
Jest er et åpen kildekode testingsrammeverk laget med JavaScript for JavaScript. Selv om det hovedsakelig er designet for JavaScript-rammeverk, kan det også brukes med andre språk, forutsatt at de er JavaScript-baserte. Jest er foretrukket av flere grunner:
Jest lar deg skrive tester for både klientside og serverside kode. Det støtter integrasjon med forskjellige rammeverk, inkludert React, Redux, Vue, Angular, Next.js og Nuxt.js. Støtten strekker seg utover disse, da det finnes tutorials, guider og kodeeksempler tilgjengelig for mange andre rammeverk.
Å sette opp Jest er enkelt og fleksibelt, enten du bruker JavaScript eller TypeScript.
For JavaScript, installerer du simpelthen Jest. Det legges til i din `package.json`, og du er klar til å starte.
For TypeScript bruker du `ts-jest`, som inkluderer både Jest og de nødvendige typedefinisjonene. Det anbefales å bruke guiden for å generere konfigurasjonsfilen. Guiden vil stille spørsmål om ditt rammeverk og lagringsplass for tester, og deretter generere konfigurasjonsfilen for deg. Hvis du foretrekker å ikke bruke guiden, kan du manuelt konfigurere Jest ved å referere til dokumentasjonen for relevante konfigurasjonsegenskaper.
Deretter legger du til et skript i din `package.json` for å kjøre tester, vanligvis kalt "test." For hyppige testkjøringer, inkluder `--no-cache` for å sikre at tester alltid kjøres.
For å integrere Jest med Gradle i et XP-miljø, legg til en Gradle-oppgave som lenker til NPM-skriptet. Denne oppgaven kjører Jest-testene hver gang byggeprosessen utløses. Skriptet skal være `npm run test`. Hvis du ikke ønsker at tester skal kjøres ved hver bygging, kan du utelate denne linjen. Dette oppsettet sikrer at tester bare hoppes over hvis det ikke er noen endringer i enten testkoden eller kildekoden som testes.
Til slutt legger du til en konfigurasjon i ditt Gradle-oppsett for å sikre at Jest-tester inkluderes hver gang Gradles testoppgave kjøres. Dette sikrer omfattende testing ved å inkludere Jest-tester sammen med eventuelle andre tester du måtte kjøre, som Java-tester eller backend-tester.
Syntaksen til Jest er enkel og involverer tre nøkkelmetoder: `describe`, `test` og `expect`.
Matchers er metoder som lar deg påstå forskjellige forhold. Vanlige matchers inkluderer `toBe`, `toEqual`, `toBeTruthy`, `toBeFalsy`, `toBeNull`, og andre. Matchers kan også inverteres ved hjelp av `.not`. For eksempel, `expect(value).not.toEqual(something)` sjekker om verdien ikke er lik en spesifikk verdi.
Her er et enkelt eksempel for å illustrere syntaksen:
```javascript
describe('Basic Math Operations', () => {
test('adds 2 + 2 to equal 4', () => {
expect(2 + 2).toBe(4);
});
test('object assignment', () => {
const data = { one: 1 };
data['two'] = 2;
expect(data).toEqual({ one: 1, two: 2 });
});
test('true is truthy', () => {
expect(true).toBeTruthy();
});
test('false is falsy', () => {
expect(false).toBeFalsy();
});
test('null is null', () => {
expect(null).toBeNull();
});
test('value is not 5', () => {
expect(4).not.toBe(5);
});
});
```
I dette eksemplet:
For å sammenligne objekter, bruk `toEqual` i stedet for `toBe`, da `toBe` er for primitivverdier. Matcherene `toBeTruthy` og `toBeFalsy` brukes for å teste boolske verdier.
Denne syntaksen gjør det enkelt å skrive og forstå tester, og sikrer at koden din oppfører seg som forventet.
For å starte med en enkel test, la oss ta et eksempel på en Fibonacci-sekvensgenerator. Vi vil sikre at den returnerer riktig sekvens for et gitt antall elementer. Her er hvordan du kan teste det i TypeScript ved hjelp av Jest:
```typescript
import { describe, expect, test } from '@jest/globals';
import { generateFibonacci } from './path-to-your-code';
describe('Fibonacci Sequence Generator', () => {
test('generates the first ten Fibonacci numbers', () => {
expect(generateFibonacci(10)).toEqual([0, 1, 1, 2, 3, 5, 8, 13, 21, 34]);
});
});
```
Denne enkle testen sjekker at funksjonen `generateFibonacci` korrekt returnerer de første ti Fibonacci-tallene.
La oss deretter diskutere mocking. Mocking er avgjørende for å isolere kodenheten som testes, og sikre at den ikke kaller eksterne avhengigheter. Dette er forskjellig fra "spying", som bare sjekker om en metode ble kalt uten å erstatte den.
Her er et eksempel på mocking av en funksjon:
Her er hvordan du kan mocke `sanitize`-metoden ved hjelp av Jest:
```typescript
import { describe, expect, test, jest } from '@jest/globals';
import { yourFunction } from './path-to-your-code';
import * as libCommon from 'libxpm-common';
jest.mock('libxpm-common', () => ({
sanitize: jest.fn()
}));
describe('Your Function Tests', () => {
test('uses the mocked sanitize method', () => {
libCommon.sanitize.mockImplementation(() => 'mocked output');
const result = yourFunction('input that requires sanitization');
expect(result).toBe('expected result based on mocked sanitize');
expect(libCommon.sanitize).toHaveBeenCalledWith('input that requires sanitization');
});
});
```
I dette eksemplet:
Ved å mocke avhengigheter kan du fokusere på å teste koden din isolert uten å bekymre deg for den faktiske implementasjonen av eksterne metoder. Denne tilnærmingen sikrer at testene dine er pålitelige og ikke avhenger av oppførselen til eksterne biblioteker.
Trenger du å mocke hele Enonic XP API? Den gode nyheten er at du ikke trenger å gjøre dette manuelt. Vi har laget en NPM-modul kalt Mock XP, som forenkler prosessen.
Mock XP er designet for å hjelpe deg med å kjøre tester uten å trenge det faktiske XP-miljøet. Dette er spesielt nyttig for CI/CD-pipelines på plattformer som GitHub, hvor XP kanskje ikke kjører. Mock XP mocker for tiden ni kjerne-APIer og er tilgjengelig i versjon 1.0.
Her er hvordan du bruker Mock XP:
Her er et grunnleggende eksempel:
```typescript
import { libnode } from 'mock-xp';
import { server } from 'mock-xp';
const mockServer = new server();
const repo = mockServer.createRepo('test-repo');
const nodeInstance = libnode.forServer(mockServer);
// Nå kan du bruke metoder fra libnode, som connect, create, etc.
nodeInstance.connect();
```
Dette oppsettet lar deg bruke kjerne XP-metoder uten å ha XP kjørende. Det sikrer at testene dine fokuserer utelukkende på koden din.
Her er et mer komplekst eksempel for å illustrere hvordan Mock XP kan brukes til å opprette og verifisere noder:
```typescript
import { libnode } from 'mock-xp';
import { server } from 'mock-xp';
const mockServer = new server();
const nodeInstance = libnode.forServer(mockServer);
const createdNode = nodeInstance.createNode({ name: 'example-node' });
const expectedNode = { name: 'example-node' };
expect(createdNode).toEqual(expectedNode);
```
I dette eksemplet:
På denne måten sikrer du at testene dine er isolert fra det faktiske XP-miljøet, slik at du kan fokusere på funksjonaliteten til koden din uten å bekymre deg for den underliggende XP-infrastrukturen. Dette er spesielt nyttig for å opprettholde en robust testpakke som kan kjøre i forskjellige miljøer, inkludert CI/CD-pipelines.
Når du arbeider med React for klientsidetesting, er det viktig å sette opp et miljø som etterligner nettleseren, inkludert objekter som vindu og dokument. Du må justere Jest-konfigurasjonen for å bruke riktig miljø, vanligvis Jest DOM for klientsidetesting, i motsetning til Node for serversidetesting.
Start med å installere React og de nødvendige pakkene. En enkel React-komponent, som en som rendrer "Hello World", kan fungere som et grunnleggende eksempel. Testoppsettet innebærer å importere komponenten og bruke React Test Renderer til å simulere rendering av komponenten uten en nettleser. Du kan deretter bruke Jest til å verifisere den rendrede utgangen, og sikre at den inneholder de forventede elementene og teksten.
Under vår integrasjon med Jest etablerte vi flere beste praksiser:
I tillegg introduserte vi en TypeScript Starter som forenkler prosessen med å kjøre Jest-tester. Denne starteren er et minimalistisk oppsett, uten tidligere eksempelkode, slik at du kan legge til din kode og tester som automatisk gjenkjennes og kjøres av Jest.
I denne demonstrasjonen viste Alan hvordan du kan kjøre tester uten å ha Enonic XP kjørende. Først vil vi bruke kommandoen `enonic create` for å opprette et nytt eksempelprosjekt. I dette eksempelet kalte vi det "eksempel Jest." Det spesifikke navnet er ikke avgjørende her. Vi vil bruke en ren sandkasse, og det er ikke nødvendig å starte denne sandkassen siden vi ikke kjører XP.
For å illustrere navigerte Alan til prosjektkatalogen for å vise oss strukturen. Dette er en faktisk XP-app, ikke et mock-oppsett. Kildekoden inneholder klient- og servertester, med noen klientsidetester inkludert.
La oss nå kjøre testene ved hjelp av Gradle. Siden dette er første kjøring, vil det installeres noen nødvendige NPM-biblioteker. Når det er gjort, vil NPM-testene kjøre, og vise at alle testene består uten at XP kjører. Dette er fordelaktig fordi det eliminerer behovet for å starte en XP-instans, og sparer tid. I dette tilfellet tok testene 1,5 sekunder å fullføre. For sammenligning, i et større prosjekt med over tusen tester, tok det rundt fem sekunder, noe som viser effektiviteten til denne tilnærmingen.
Q: Kan du kjøre NPM-tester direkte?
A: Ja, du kan bruke `NPM run test`.
Q: Kan du kjøre tester med CLI?
A: Ja, du kan bruke kommandoen `enonic project test`.
Når det gjelder ytelsestesting, er det integrasjon med K6 for ytelsestesting, tradisjonelt brukt til dette formålet. Selv om ytelsestesting har vært en vurdering i flere år, har det ennå ikke blitt fullstendig integrert, men det står på listen. Du kan fortsatt bruke K6 i dine pipelines for nå.
Oppsummert, kan du effektivt kjøre tester uten XP, ved å utnytte verktøy som Gradle og NPM, og utforske ytelsestesting med K6 i dine arbeidsflyter.
Få enda mer innsikt 🤓