Kā sākt vienību pārbaudīt JavaScript kodu

Mēs visi zinām, ka mums vajadzētu rakstīt vienības testus. Bet, salīdzinot ar faktisko ieviešanu, ir grūti zināt, ar ko sākt un cik daudz laika veltīt testiem. Tātad, ar ko sākt? Un vai tas attiecas tikai uz koda testēšanu, vai vienības testiem ir citas priekšrocības?

Šajā rakstā es paskaidrošu dažādos testu veidus un to, kādus ieguvumus vienību testēšana dod attīstības komandām. Es parādīšu Jest - JavaScript testēšanas sistēmu.

Dažādi testēšanas veidi

Pirms mēs iedziļināmies vienību testēšanas specifikā, es vēlos ātri veikt dažādu veidu testus. Ap viņiem bieži valda neskaidrības, un es neesmu pārsteigts. Dažreiz līnija starp tām ir diezgan plāna.

Vienības testi

Vienības testi pārbauda tikai vienu jūsu ieviešanas daļu. Vienība. Nav atkarību vai integrāciju, nav ietvara specifikas. Tās ir kā metode, kas atgriež saiti noteiktā valodā:

export function getAboutUsLink(language){ switch (language.toLowerCase()){ case englishCode.toLowerCase(): return '/about-us'; case spanishCode.toLowerCase(): return '/acerca-de'; } return ''; }

Integrācijas testi

Kādā brīdī jūsu kods sazinās ar datu bāzi, failu sistēmu vai citu trešo pusi. Tas pat varētu būt cits modulis jūsu lietotnē.

Šis ieviešanas gabals jāpārbauda ar integrācijas testiem. Viņiem parasti ir sarežģītāka iestatīšana, kas ietver testēšanas vides sagatavošanu, atkarību inicializēšanu utt.

Funkcionālie testi

Vienības testi un integrācijas testi sniedz pārliecību, ka jūsu lietotne darbojas. Funkcionālie testi aplūko lietotni no lietotāja viedokļa un pārbauda, ​​vai sistēma darbojas kā paredzēts.

Iepriekš redzamajā diagrammā redzat, ka vienības testi veido lielu lietojumprogrammas testēšanas komplekta pamatu. Parasti tie ir mazi, to ir daudz, un tie tiek izpildīti automātiski.

Tāpēc tagad nedaudz sīkāk iekļūsim vienību testos.

Kāpēc man vajadzētu traucēt rakstīšanas vienības testus?

Ikreiz, kad jautāju izstrādātājiem, vai viņi ir uzrakstījuši testus savai lietojumprogrammai, viņi man vienmēr saka: "Man viņiem nebija laika" vai "Man tie nav vajadzīgi, es zinu, ka tas darbojas".

Tāpēc es pieklājīgi pasmaidu un saku viņiem to, ko vēlos jums pateikt. Vienības testi nav tikai testēšana. Viņi jums palīdz arī citos veidos, lai jūs varētu:

Esiet pārliecināts, ka kods darbojas. Kad jūs pēdējo reizi veicāt koda maiņu, jūsu būvēšana neizdevās un puse no jūsu lietotnes vairs nedarbojās? Manējais bija pagājušajā nedēļā.

Bet tas joprojām ir labi. Patiesā problēma ir tad, kad būvēšana ir veiksmīga, izmaiņas tiek izvietotas un jūsu lietotne sāk būt nestabila.

Kad tas notiks, jūs sākat zaudēt uzticību savam kodam un galu galā vienkārši lūdzieties, lai lietotne darbotos. Vienības testi palīdzēs jums atklāt problēmas daudz ātrāk un iegūt pārliecību.

Pieņemiet labākus arhitektūras lēmumus. Kods mainās, bet daži lēmumi par platformu, moduļiem, struktūru un citi jāpieņem projekta agrīnajā stadijā.

Kad sākat domāt par vienības testēšanu jau pašā sākumā, tas palīdzēs labāk strukturēt kodu un panākt pareizu problēmu atdalīšanu. Jums nebūs kārdinājuma piešķirt vairākus pienākumus viena koda blokiem, jo ​​tie būtu murgi vienības pārbaudē.

Precīzi nosakiet funkcionalitāti pirms kodēšanas. Jūs uzrakstāt metodes parakstu un nekavējoties sākat to ieviest. Ak, bet kā būtu jānotiek gadījumā, ja parametrs ir nulle? Ko darīt, ja tā vērtība ir ārpus paredzētā diapazona vai tajā ir pārāk daudz rakstzīmju? Vai jūs izmetat izņēmumu vai atgriežat nulli?

Vienības testi palīdzēs jums atklāt visus šos gadījumus. Apskatiet vēlreiz jautājumus, un jūs atradīsit, ka tieši tas nosaka jūsu vienības testa gadījumus.

Esmu pārliecināts, ka vienību testu rakstīšanai ir daudz vairāk priekšrocību. Šīs ir tikai tās, kuras es atceros no savas pieredzes. Tie, kurus es iemācījos grūtāk.

Kā uzrakstīt savu pirmo JavaScript vienības testu

Bet atgriezīsimies pie JavaScript. Mēs sāksim ar Jest, kas ir JavaScript testēšanas sistēma. Tas ir rīks, kas nodrošina automātisku vienību testēšanu, nodrošina koda pārklājumu un ļauj mums viegli izsmiet objektus. Jestam ir pieejams arī Visual Studio Code paplašinājums.

Ir arī citas sistēmas, ja jūs interesē, varat tās pārbaudīt šajā rakstā.

npm i jest --save-dev 

Izmantosim iepriekš minēto metodi getAboutUsLinkkā ieviešanu, kuru vēlamies pārbaudīt:

const englishCode = "en-US"; const spanishCode = "es-ES"; function getAboutUsLink(language){ switch (language.toLowerCase()){ case englishCode.toLowerCase(): return '/about-us'; case spanishCode.toLowerCase(): return '/acerca-de'; } return ''; } module.exports = getAboutUsLink; 

Es to ievietoju index.jsfailā. Mēs varam rakstīt testus vienā un tajā pašā failā, taču laba prakse ir testu sadalīšana atsevišķā failā.

Kopējie nosaukšanas modeļi ietver {filename}.test.jsun {filename}.spec.js. Es izmantoju pirmo index.test.js:

const getAboutUsLink = require("./index"); test("Returns about-us for english language", () => { expect(getAboutUsLink("en-US")).toBe("/about-us"); }); 

Pirmkārt, mums jāimportē funkcija, kuru vēlamies pārbaudīt. Katrs tests tiek definēts kā testfunkcijas izsaukšana . Pirmais parametrs ir jūsu atsauces testa nosaukums. Otra ir bultiņas funkcija, kurā mēs saucam funkciju, kuru vēlamies pārbaudīt, un norādām, kuru rezultātu mēs sagaidām. Es

Šajā gadījumā mēs kā valodas parametru izsaucam getAboutUsLinkfunkciju ar en-US. Mēs sagaidām, ka rezultāts būs /about-us.

Tagad mēs varam instalēt Jest CLI globāli un palaist testu:

npm i jest-cli -g jest 

Ja redzat ar konfigurāciju saistītu kļūdu, pārliecinieties, vai jūsu package.jsonfails ir klāt. Ja jums nav, ģenerējiet vienu, izmantojot npm init.

Jums vajadzētu redzēt kaut ko līdzīgu šim:

 PASS ./index.test.js √ Returns about-us for english language (4ms) console.log index.js:15 /about-us Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.389s 

Lielisks darbs! Šis bija pirmais vienkāršais JavaScript vienības tests no sākuma līdz beigām. Ja instalējāt paplašinājumu Visual Studio Code, pēc faila saglabāšanas tas automātiski darbosies. Izmēģināsim, pagarinot testu ar šo rindu:

expect(getAboutUsLink("cs-CZ")).toBe("/o-nas"); 

Pēc faila saglabāšanas Jests informēs, ka pārbaude neizdevās. Tas palīdz atklāt potenciālās problēmas pat pirms izmaiņu veikšanas.

Papildu funkcionalitātes un izsmiekla pakalpojumu testēšana

Reālajā dzīvē getAboutUsLink metodes valodas kodi nebūtu konstanti tajā pašā failā. To vērtību parasti izmanto visā projektā, tāpēc tie tiks definēti viņu pašu modulī un importēti visās funkcijās, kurās tos izmanto.

import { englishCode, spanishCode } from './LanguageCodes' 

Jūs varat importēt šīs konstantes testā tāpat. Bet situācija kļūs sarežģītāka, ja jūs strādājat ar objektiem, nevis vienkāršām konstantēm. Apskatiet šo metodi:

import { UserStore } from './UserStore' function getUserDisplayName(){ const user = UserStore.getUser(userId); return `${user.LastName}, ${user.FirstName}`; } 

Šajā metodē tiek izmantoti importētie UserStore:

class User { getUser(userId){ // logic to get data from a database } setUser(user){ // logic to store data in a database } } let UserStore = new User(); export { UserStore } 

Lai pareizi pārbaudītu šo metodi, mums ir jāizsmej UserStore. Izspēles ir oriģinālā objekta aizstājējs. Tas ļauj mums nošķirt atkarības un reālos datus no pārbaudītās metodes ieviešanas, tāpat kā manekeni palīdz automašīnu, nevis reālu cilvēku sadursmes testos.

Ja mēs neizmantotu izspēli, mēs pārbaudītu gan šo funkciju, gan veikalu. Tas būtu integrācijas tests, un mums, iespējams, vajadzēs izsmiet izmantoto datu bāzi.

Ņirgāšanās par pakalpojumu

Lai ņirgātos par objektiem, jūs varat nodrošināt ņirgāšanās funkciju vai manuālu ņirgāšanos. Es koncentrēšos uz pēdējo, jo man ir vienkāršs un vienkāršs lietošanas gadījums. Bet jūtieties brīvi pārbaudīt citas Jest piedāvātās izsmiekla iespējas.

jest.mock('./UserStore', () => ({     UserStore: ({         getUser: jest.fn().mockImplementation(arg => ({             FirstName: 'Ondrej',             LastName: 'Polesny'         })), setUser: jest.fn()     }) })); 

Pirmkārt, mums jānorāda, par ko mēs ņirgājamies - ./UserStoremoduli. Tālāk mums jāatgriež izspēle, kurā ir visi eksportētie objekti no šī moduļa.

Šajā izlasē tas ir tikai Userobjekts, kas nosaukts UserStorear funkciju getUser. Bet reāli īstenojot, izspēles var būt daudz ilgākas. Jebkuras funkcijas, kas jums vienalga, testējot vienību, var viegli izsmiet jest.fn().

Funkcijas vienības tests getUserDisplayNameir līdzīgs iepriekš izveidotajam:

test("Returns display name", () => {     expect(getUserDisplayName(1)).toBe("Polesny, Ondrej"); }) 

Tiklīdz es saglabāju failu, Jests man saka, ka man ir 2 nokārtoti testi. Ja testus veicat manuāli, dariet to tūlīt un pārliecinieties, vai redzat to pašu rezultātu.

Kodu pārklājuma ziņojums

Tagad, kad mēs zinām, kā pārbaudīt JavaScript kodu, ir labi pārklāt pēc iespējas vairāk koda ar testiem. Un to ir grūti izdarīt. Galu galā mēs esam tikai cilvēki. Mēs vēlamies paveikt savus uzdevumus, un vienību pārbaudes parasti rada nevēlamu darba slodzi, kuru mums ir tendence nepamanīt. Kodu pārklājums ir rīks, kas palīdz mums ar to cīnīties.

Kodu pārklājums jums pateiks, cik lielu daļu no jūsu koda sedz vienības testi. Veikt, piemēram, manu pirmo vienības testu, pārbaudot getAboutUsLinkfunkciju:

test("Returns about-us for english language", () => {    expect(getAboutUsLink("en-US")).toBe("/about-us"); }); 

It checks the English link, but the Spanish version stays untested. The code coverage is 50%. The other unit test is checking the getDisplayName function thoroughly and its code coverage is 100%. Together, the total code coverage is 67%. We had 3 use cases to test, but our tests only cover 2 of them.

To see the code coverage report, type the following command into the terminal:

jest --coverage 

Or, if you're using Visual Studio Code with the Jest extension, you can run the command (CTRL+SHIFT+P) Jest: Toggle Coverage Overlay. It will show you right in the implementation which lines of code are not covered with tests.

By running the coverage check, Jest will also create an HTML report. Find it in your project folder under coverage/lcov-report/index.html.

Now, I don't have to mention that you should strive for 100% code coverage, right? :-)

Summary

In this article, I showed you how to start with unit testing in JavaScript. While it's nice to have your code coverage shine at 100% in the report, in reality, it's not always possible to (meaningfully) get there. The goal is to let unit tests help you maintain your code and ensure it always works as intended. They enable you to:

  • clearly define implementation requirements,
  • better design your code and separate concerns,
  • discover issues you may introduce with your newer commits,
  • and give you confidence that your code works.

The best place to start is the Getting started page in the Jest documentation so you can try out these practices for yourself.

Vai jums ir sava pieredze koda testēšanā? Es labprāt to dzirdētu, informētu mani Twitterī vai pievienotos kādai no manām Twitch straumēm.