paint-brush
Sådan genmonteres tests i en ReactJS-kodebaser uden testsved@matheusmarabesi
Ny historie

Sådan genmonteres tests i en ReactJS-kodebaser uden tests

ved Matheus Marabesi7m2025/02/13
Read on Terminal Reader

For langt; At læse

ReactJs mønstre kan være en kilde til fejl, når det kommer til strukturen af et komponenthierarki. At nedbryde disse komponenter er en udfordring, men det skal tages i betragtning for bedre vedligeholdelse af kodebasen. For professionel udvikling er den globale tilstand et grundlæggende krav, for reactjs applikationer er det ikke anderledes.
featured image - Sådan genmonteres tests i en ReactJS-kodebaser uden tests
Matheus Marabesi HackerNoon profile picture

At teste software og gøre det nemt at gøre det har været en interesse for mig i et par år nu. Denne interesse er nu mere fokuseret på frontend-applikationer, der plejede at være. Mere specifikt til reactjs-applikationer. Det er et par måneder siden, at jeg har dykket ned i en fem til ti år gammel reactjs-kode, der giver mig indsigt og udfordringer.


Jeg har personligt udviklet reactjs-kode i et par år nu; et af de første open source-projekter, jeg har delt, hedder testable . Den blev udgivet i 2020 eller deromkring, og siden da har jeg dedikeret en del af min læringsvej til reactjs.


For nylig har jeg arbejdet på andre open source-projekter, der fokuserer på testbarhedsdelen af ting såsom json-tool og text-tool ; begge applikationer er open source og implementeres på Snapcraft. Ud over dem kører jeg ofte eksperimenter i et depot kaldet reactjs-playground . Det er stedet, hvor jeg eksperimenterer med reactjs funktioner og dedikerer mine læringstimer til det. Den erfaring, jeg har opnået i disse år i close-source projekter og open source-projekter, gav mig et fundament, der giver mig mulighed for at identificere nogle almindelige faldgruber og fordele.

Faldgruber

Udviklere, der tilslutter sig reactjs-mønsteret og værktøjet, indser, at de byggeklodser, som biblioteket tilbyder, er nemme at forstå og komponere. Det mest abstrakte koncept for en komponent kan bruges til hurtigt at sammensætte brugergrænseflader. Det kan dog også være en kilde til fejl, når det kommer til strukturen af en komponents hierarki. Nedbrydning af systemer er et emne , der har været undersøgt i årevis.

Store komponenter

Størrelsen af abstraktionens enhed i software har også været genstand for debat; nogle hævder, at metoder og klasser bør have et lille antal linjer, mens andre foretrækker at have et større, velstruktureret stykke. Som i ethvert softwareprojekt uanset størrelsen, har jeg til hensigt at foretrække den størrelse, der giver mere kontekst og producerer mindre friktion på den kognitive belastning, mens koden læses.


Tilfældigheder eller ej, efter min erfaring finder jeg dette muligt, når jeg har veldefinerede grænser for det stykke kode, jeg arbejder på, sammen med den forretningsmæssige kontekst. Jeg har endnu ikke fundet det magiske tal for det, men min måling blev antallet af hop, jeg skal gøre mellem filer for at forstå, hvad jeg skal gøre.


Så mange hop som jeg skal gøre, jo mere har jeg brug for at holde konteksten og informationen i hovedet; dette bliver svært, mens kodebasen bibeholdes. At nedbryde disse komponenter er en udfordring, men det skal tages i betragtning for bedre vedligeholdelse af kodebasen.

Global stat

For faglig udvikling er den globale stat et grundlæggende krav; for reactjs-applikationer er det ikke anderledes. Den globale tilstand kan let ses af brugere af applikationen. Hvis du køber noget, og du tilføjer produktet til din indkøbskurv, kan du se antallet af varer, du har tilføjet; dette er den globale stat.


I reactjs-applikationer har den engang meget udbredte globale statsstyringspakke redux nu reduceret sin brug til fordel for mindre kontekster omkring grænser i applikationen. Fællesskabet har dog delt forskellige meninger om behovet for at bruge redux til global statsstyring; dette førte til nogle blogs om emnet:



På trods af tilbageslag fra fællesskabet har react-redux, som er et bibliotek, der bruges til at binde redux til reactjs-komponenter, haft sin adoption vokset i de sidste fem år i henhold til npm-tendenser . Den 1. februar 2025 er downloads vist i npm for redux 6.752.764.


Hvis du undrer dig over, hvad alternativet til det er, så er svaret reactjs kontekst og hooks med forespørgsler.


For applikationer, der er afhængige af redux-pakken, er det en udfordring i sig selv at slippe afsted med det. Den globale tilstand er en af de afhængigheder, der mindsker applikationens testbarhed. Efter min erfaring kommer den nødvendige globale kontekst ofte med øget kompleksitet af domæneviden. Selvom du måske bare vil teste en bestemt komponent eller et udsnit af din applikation, vil du ikke være i stand til det uden at dele de globale afhængigheder, som dette udsnit kræver.

Fordele

At vedtage reactjs til virksomhedsapplikationer på tidspunktet for skrivningen af dette stykke har været en korrekt beslutning for vedligeholdelse (på trods af det kritiske øjeblik, som Facebook havde, da det ændrede bibliotekslicensmodellen). ReactJs giver bagudkompatibilitet for API'er, der ikke længere bruges, hvilket gør langsigtet adoption til en af de vigtigste fordele.

Kontekster

Som om komponenter ikke er nok som et abstrakt koncept til at komme udenom, er kontekster også en af de fordele, som reactjs giver i forhold til test. Jeg uddyber mere om dette emne i et blogindlæg dedikeret til reactjs konteksttestning . Niveauet af indkapsling, som reactjs-konteksten giver, er en af de vigtigste fordele ved eftermontering af tests og muliggør refactoring i reactjs-kodebaser.


Da nedbrydning af komponenter og forretningslogik er en udfordring, er kontekster de værktøjer, der muliggør en bedre omstrukturering af koden. I testbarhedsdelen af tingene er dette også en fordel, da det er en mekanisme, der muliggør det reducerede antal test-dobbelt brugt, hvilket fører til en mere testbar kode.

Eftermonteringstests

Givet en sådan liste indtil videre, er testdelen forhåbentlig blevet klar, der afhænger af, hvordan kildekoden er struktureret, og hvordan grænserne for applikationen er blevet organiseret. Men så meget som testkoden afhænger af produktionskoden, kan testdoblingerne bruges til at afgrænse omfanget. Tankeprocessen for eftermontering af test er sammensat af et par enkle trin.


  1. Skriv en simpel testcase for den ønskede funktionalitet.
  2. Kør testcasen og se, at den fejler.

2.1. Bestod testen?

 2.1.1 - Yes → Check if the feedback is correct 2.1.2 - No → Provide the dependency without questioning
  1. Gå tilbage til 1.


Bemærk, at: Den her beskrevne tilgang ligner det, der beskrives som karakteriseringstesten beskrevet af Michael Feathers i

Arbejde effektivt med Legacy Code-bog.


Fremkomsten af LLM'er kan også give indsigt, mens du skriver de første tests og eftermonterer kodebaser uden nogen test. Hvert trin i denne strategi er beregnet til at være iterativt; det er også muligt at kombinere forskellige stilarter af TDD. Den foreslåede tilgang er ikke at stoppe med at gøre alt og eftermontere alle mulige testcases og alle mulige problemer, som kodebasen har, det er et puslespil. Hver testet funktionalitet er en brik, der passer ind i puslespillet.


Den samme fremgangsmåde foreslås til refaktorering. Udviklere bør være i stand til konstant at refaktorisere et stykke kode. Det er ikke et anderledes projekt, og det er ikke rettet mod kun at være dedikeret til det. Dens hovedmål er at gøre kodebasen bedre, end den var. Iterativt. Der er et par aspekter, der kan bruges til at eftermontere test i kodebaser, der ikke har nogen:


  • Ret en fejl - Dette er muligheden for at blive eksponeret for koden og for at forstå, hvordan den opfører sig. At rette fejlen er en del af problemet, men dette er også en mulighed for at karakterisere den aktuelle applikation.
  • Implementering af en ny funktionalitet - Dette er det samme som at rette en fejl, men tilgangen skifter en smule. Det er den samme tilgang som den, der blev foreslået af Kent Beck: "Gør forandringen let, så lav den nemme forandring." En ny funktionalitet er et sted, der afslører kodebasen for at foretage en ændring, før den nye funktion introduceres.


Kernen i denne tilgang er læringsprocessen; hvert trin i at lære kodebasen tages i betragtning.

LLM'er

Copilot kan bruges til at automatisere den første eksplorative test beskrevet i det foregående afsnit; efter tre regler, kan det komme i gang med at identificere afhængigheder og skrive et sæt omfattende test, der skal bruges som base.


Lad os tage Testable som et eksempel; det er en applikation, der blev skrevet for mere end fem år siden i reactjs og bruger enzym til test. For nutidens standard er biblioteket, der tog over, vitest eller spøg sammen med testbiblioteket. For at eftermontere testcaserne til testbare og drage fordel af LLM'er, kan vi bruge copilot til at hjælpe os med de tunge løft.


Testbar er sammensat af en gamified oplevelse, der har tilstand, niveauer og brugerprogression gennem forskellige udfordringer. Komponenten beskrevet i det følgende billede er den komponent, der bruges til at vise dialoger og til at navigere fremad i oplevelsens historie. Ved at bruge Copilot til vscode bad jeg den om at skrive en test med den produktionskode, vi er interesseret i:


Beder andenpilot om at skrive en testsag

Når den først indlæser spørgsmålet og analyserer koden, giver den svaret.

Copilot svar på testcasen

Sammen med svaret bemærkede Copilot, at jeg endnu ikke bruger et testbibliotek, og det foreslår, at jeg gør det, og derefter vises den genererede testcase. Kørs testcasen, som den er vist, bliver testen ikke bestået og markerer den som rød.


Mislykket test fra genereringskode

Dette punkt er vigtigt, fordi det viser, at yderligere opsætning skal tages i betragtning, og Copilot kunne ikke finde ud af det. De er som følger:

  • Importen er ikke korrekt; det skal rettes for at pege på den korrekte fil.
  • Opsætningen af indhold er ikke korrekt; filen var ikke muligt at gøre indholdet gyldigt for testcasen.


Det flow, der er beskrevet tidligere i dette afsnit, gælder også her. Feedback-sløjfen er nu at begynde at løse disse problemer og køre testene, indtil TDD-cyklussen er afsluttet.


Ressourcer