Dette indlæg er alene udtryk for skribentens egen holdning.

Check dit JavaScript

4. juni 2013 kl. 09:186
Artiklen er ældre end 30 dage
Manglende links i teksten kan sandsynligvis findes i bunden af artiklen.

Jeg har ikke tal på, hvor mange gange Findbugs har reddet os fra at få sendt error-prone Java-kode ud af huset; det er utroligt rart at vide, at man har en pedantisk fætter siddende på Jenkins og overvåge éns mindste commit.

Nu begynder vi efterhånden at få en del mere JavaScript-kode i produktet også, og det har naget mit bekymrede alter ego, at denne del af koden ikke blev udsat for samme tur i vridemaskinen.

Til statisk check af JavaScript er der umiddelbart tre muligheder at vælge imellem:

  • Closure-compileren (der egentlig er et værktøj til optimering af JavaScript)

  • JSLint (som navnet antyder, inspireret af værktøjet link til checking af C-kode)

  • JSHint (der er en fork af JSLint)

JSHint forkede fra JSLint pga. en voldsom utilfredshed med den manglende konfigurerbarhed af JSLint; det er rart at kunne bestemme, hvor nøjeregnende checkeren skal være med visse stilistiske elementer.

Artiklen fortsætter efter annoncen

Både JSLint og JSHint er skrevet i JavaScript, og kan bruges som online-værktøj, hvilket er nyttigt til at afprøve konceptet, men ikke optimalt til automatiseret test. JSHint inkluderer et “browser bundle” med en JavaScript-fil, der eksponerer en global JSHINT-funktion, som man kan kalde direkte, men der er også mulighed for at køre det som et node.js-program, eller ved brug af Rhino.

Især node-udgaven virker rigtigt nem at bruge, men da vi pt. ikke har en test-server med node har jeg indtil videre valgt at køre det på den måde, at jeg genererer en HTML-fil med JSHints browser bundle inkluderet + en CDATA-sektion, der indeholder det script, der skal checkes, og får noget JavaScript til at generere en resultatside. Dette kan så køres igennem vores sædvanlige test-framework, der loader en side op i en browser og udtrækker resultatet - her kan man f.eks. benytte PhantomJS, Selenium eller måske HtmlUnit.

Så nu har vi en JUnit-test, der knækker, hvis nogen er for sløset med semikolonerne eller andet. :-)

Det er dog ikke helt let at finde ud af at sammenstille den rette konfiguration til JSHint. En del options er dokumenteret på deres hjemmeside, men som regel når man får en warning eller error, er der inkluderet en error code (eks. “W117”), som man ikke har nogen måde at mappe til de mere generelle options (eks. “undef”). Der findes ingen dokumentation på disse error codes - andet end hvis man læser source-koden - men man kan dog i det mindste konfigurere JSHint til, at man ikke vil advares om bestemte error codes.

Artiklen fortsætter efter annoncen

Optimalt set bør man sørge for, at alle dependencies er inkluderet i den kode, der checkes, så man kan benytte sig af at teste for, om man kommer til at referere til nogen udefinerede variable. Da jQuery er så udbredt, har JSHint heldigvis en option, der automatisk definerer de globals, som jQuery definerer, samt en option, der definerer det “sædvanlige” browser-miljø af indbyggede objekter.

Jeg savner dog checks for browser-inkompatibilitet - nogle af disse burde kunne findes ved statisk checking. F.eks. havde vi for nylig en bug, hvor et stykke JavaScript satte en property ved navn "new" på et objekt. Den går ikke i IE8, der ikke tillader reserverede ord som property-navne. Men den slags ups'ere fanger JSHint altså ikke.

Jeg er ikke færdig med at finde ud af, hvordan vi kan få bedre styr på vores JavaScript (tips modtages gerne), men her var da et skridt på vejen. :-)

6 kommentarer.  Hop til debatten
Denne artikel er gratis...

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.

Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.

Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.

Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.

Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger
6
5. juni 2013 kl. 19:22

Endnu et værktøj til at holde øje med vedligeholdelsesvenligheden af din JavaScript-kode:http://ariya.ofilabs.com/2013/01/javascript-code-complexity-visualization.html

Vi bruger Karma, som Theo Andersen nævner, på CI serveren. (Det gamle navn "Testacular" har vi haft meget sjov med, da en på holdet konsekvent sagde forkert:-) )

Angående options på JSHint, så gjorde vi det, at vi bad alle på teamet om at sætte sig ind i dem, og komme med deres besyv om hvilke checks der skal køres med. Vi lavede et google spreadsheet hvor man indtastede sine stemmer og kommentarer. Vi blev eninge til sidst, men det gav en god diskussion (nogle af dem kan være en smagssag).

Vi bruger også .jshintrc og .jshintignore filerne som Peter Mûller nævner. De virker både i sublime og webstorm, og også med JSHint som node.js modul.

Husk at køre JSHint på alt din kode, også dine tests. Da vi slog det til på tests, fand vi fejl i vores tests.

JSHint kører sammen med CSSLint og hele testsuiten hver gang en udvikler laver et git push hos os ("npm test" via en lidt kode i .bashrc https://gist.github.com/Muscula/5661367)

Og JSHint kører selvfølgelig også på CI-serveren.

Pt. har vi Selenium tests skrevet i dotNet, til automatiserede acceptance tests (klikke rundt i app'en). Men vi er ved at kigge på Webdriver.js, Casper.js og zombie.js til disse (nok kun een af dem).

På serversiden (Node.js) har performancetests med JMeter allerede vist sit værd. Og jeg overvejer om man også burde stressteste sin clientside JavaScript på en eller anden måde, for at fange memoryleaks, dårlig oprydning osv.

5
5. juni 2013 kl. 18:36

Til test af javascript over flere browsere vil jeg foreslå Karma hvilket er et værktøj hvorved man kan pushe javascript kode der testes til mange browsere på samme tid, lokalt på sin egen computer. (Minder om jstestdriver hvis nogen skulle kende det). Det hed tidligere Testacular, men de ændrede det lidt uheldige navn.. :o). Men Karma tillader at man kan køre unit tests på lige så mange browsere som man kobler til, automatiseret.http://karma-runner.github.io

Ellers så har James Shore et rigtig godt projekt kørende på www.letscodejavascript.com, hvor han laver en række screencasts om professionel javascript udvikling bla. kørt test-drevent. Projektet benytter node.js på server-siden og Karma til browser test. Det koster godt nok et abonnement, men der er meget at lære.

3
4. juni 2013 kl. 12:41

Man kan med fordel smide en .jshintrc i roden af site frontend projekt, som så kan læses af diverse værktøjer. Her er min .jshintrc på mit nuværende projekt: https://gist.github.com/Munter/5705018Filen versionsstyres naturligvis.

Mit team benytte sublime text til tekstredigering. Her findes der er plugin 'Sublimelinter', som kan forstå at benytter denne .jshintrc til konfiguration, løbende linte og highlighte fejl osv. På denne måde kan du sikre løbende fejlindikationer så folk ikke begår dem i første omgang. Dette sikrer generel kodekvalitet og bedre disciplin på tværs af teamet som helhed. https://github.com/SublimeLinter/SublimeLinter

Derudover kan du bruge nodes 'jslint' moduls binary til at linte al din javascript kode i alle subdirectories med dine definerede settings således: 'jshint --config .jshintrc http-pub'. Jeg har dette i et make target, som også kører inden jeg laver et produktionsbuild af koden.

Det ovenstående target kan også tilføjes i forskellige hooks i versionsstyring. Jeg har et lokalt git precommit hook der sikrer at jeg aldrig får lov at tjekke kode ind som fejler linting. Eller du kan køre det på en CI server i stedet. Nøglen er at konfiguration er nem og identisk på tværs af miljøer.

Derudover kunne man også med fordel på samme måde integrere https://npmjs.org/package/complexity-report i sit workflow.

4
4. juni 2013 kl. 13:40

Vi bruger også IntelliJ, som er rimeligt god til at advare om problemer, men det er meget rart at have den ekstra sikkerhed på CI-serveren.

Desuden er noget at vores JavaScript embedded i Velocity-templates, så den unit test, jeg har lavet, sørger for at instantiere Velocity-templaten og dermed får genereret det rigtige JavaScript, inkl. de dependencies, som det kommer til at have, når det kører i produktion.