JavaScript Static Analysis Tools and Techniques - STP Online Session 2013


Published on

An overview of JavaScript static analysis tools and an anecdotal case for the utility of static analysis in automated testing of JavaScript projects.

Many errors in JavaScript projects --- think misplaced semicolons and mis-scoped variables --- are trivially preventable with habitual use of community-maintained tools like JSHint, JSLint, JSONLint or the Google Closure Compiler Linter. Many other errors are preventable through the judicious use of find, grep and simple regular expressions. In test automation, the simplest approach often proves surprisingly robust. I will conclude the session by discussing in detail how I am using static analysis on my own projects today.

Published in: Technology

JavaScript Static Analysis Tools and Techniques - STP Online Session 2013

  1. 1.
  2. 2. “Lint”
  3. 3. “StaticAnalysis”means“AutomatedReading”
  4. 4.
  5. 5. Thegoalofstaticanalysisistoautomateyourselfreadingcode.—SebastianBergmann
  6. 6. TheCaseForStaticAnalysisStatic analysis can reveal interesting places to startreading in an unfamiliar code base.It can also be used to locate areas of the code basethat may benefit from refactoring.Additionally static analysis may highlight potentialsources of latent bugs.
  7. 7. “Errors”aren’tnecessarilybad.Edsger Dijkstra famously said that tests can show thepresence of bugs, but never their absence.Static analysis can tell you where to start reading, butit can’t tell you where and when to stop reading andtake action.The feedback from any of these tools is ultimately justanother data point. How to respond to that data is aproblem static analysis can’t solve ;-)
  8. 8. Goodhart’sLawAnymetricthatisusedtogaugeperformance,willbegamedsuchthatitisnolongeranaccuratemeasureofperformance.
  9. 9. —GerardHolzmann(NASA/JPL)"reliabilityisasystemproperty,notacomponentproperty""sincesmalldefectscanlineupandleadtoabiganomaly…beingmeticulousaboutevensmalldefectscanreallypayoff.Everysmalldefectthatyoueliminate,eliminatesonelinkinthechainthatcouldbuildtowardalargerproblem.Acodingstandardcouldhelp.Almosteveryorganizationhasacodingstandardandinmostcasesthedevelopersarecompletelyunawareofit--theydontreadit...Ifyoucomeupwithacodingstandardyoubetterhaverulesthatmatter,thatcorrelatewithriskandyoubettermakesurethatyoucancheckcompliancemechanically."
  10. 10. UniformityandComprehensibility
  11. 11. ChecksfordetectableerrorsFind places where semicolon insertion mightproduce unintended resultsDetect unintentional declaration of global variablesDetect undeclared variablesWarn about potential unintended behavior from ==Flag usages of eval()
  12. 12. Firstweneedanexistingcodebase.wget jquery-1.10.1.js jquery.js
  13. 13. JSLintnpm -g install jslintjslint jquery.jsJSLint is Douglas Crockfords personal linting tool.It ships with a great default ruleset -- Crockfords own,constantly updated as he continues to learn aboutJavaScript and its pitfalls.JSLint is highly opinionated. While this is generallyseen as a good thing, theres a limited amount offlexibility when it comes to disabling individual rules.It’s hard to apply JSLint to legacy code.
  14. 14. JSHintnpm -g install jshintjshint jquery.jsJSHint is very similar to JSLint (in fact it began life asJSLint fork) but all of JSHint’s warnings and errors canbe configured or disabled via command line options orwith a .jshintrc configuration file.
  15. 15. JSONLintnpm -g install jsonlintjsonlint myFile.jsonJSONLint is a validator for the JSON data-interchangeformat. JSON is used by almost all modern Web APIs.JSONLint automates the process of testing whetherthere are parsiing errors in a block of JSON.
  16. 16. GoogleClosureCompilercurl -sO -qo compiler-latest.zipjava -jar compiler.jar jquery.jsClosure compilation is the closest thing that JavaScripthas to an "interpreter" syntax check like php  -­‐l orruby  -­‐c  Closure also warns you about potential issues suchas missing parameters and undeclared or redefinedvariables.If code wont compile with the Closure Compiler, thenyou can be certain said code is deeply hosed in somefundamental way.
  17. 17. TheGoogleJavaScriptLinter(gjslint)fixjsstyleyardstickProjectMessDetector(PMD)Copy-PasteDetector(CPD)CSSLintTidyforHTML5PHPCodeSniffer
  18. 18. JSONLintGoogleClosureCompilerJSHintUseandConfiguration
  19. 19. jsonlint myFile.jsonJSONLintinaction
  20. 20. GoogleClosureCompilerinaction
  21. 21. jslint jquery.jsJSLintinaction
  22. 22. jshint jquery.jsJSHintinaction
  23. 23. ConfigureJSHintandClosureCompiler
  24. 24. .jshintrcfile
  25. 25. Usea.jshintrcfile
  26. 26. OutputTuning
  27. 27. In-the-wildexamplesofoutputtuning
  28. 28. RegularExpressionsjslint jquery.js | egrep -v is OK.$ | egrep -v ^ *$This relatively simple regex suppresses statusmessages from JSLint. The only lines that will beprinted are lines containing errors and warnings.
  29. 29. RegularExpressionstidy_ignore_regex=(DOCTYPE|title|notapproved|proprietary attribute|implicit <body>|trimming empty|missing <li>)|"tabindex" has invalidvalue "-1"|missing </template> before<li>|inserting implicit <ul>|missing</ul> before </template>|missingquote mark for attribute value
  30. 30. TunetheToolsToMatchTheCodejslint --predef Meteor --predef Template --predef $ --predef _ --predef Session --predef setTitle --predef Conf --predef google --predef Npm --predef makeInfoWindowEvent --predef IS_DEV --predef IS_PRODUCTION --plusplus --devel --vars --nomen --sloppy --white --terse --browser jquery.js | egrep -v is OK.$ | egrep -v ^ *$
  31. 31. TunetheToolsToMatchTheCodejava compiler.jar jquery.js --warning_level DEFAULT --jscomp_off missingProperties --compilation_level ADVANCED_OPTIMIZATIONS --externs ../../tests/conf/externs.js | > /dev/null
  32. 32. Don’tFeartheFilteryardstick_runner () {reasonable_upper_bound_for_CCN=10result=$(echo $* | xargs yardstick | grep -v @ | egrep -v ^ | perl -lnwe s{^(S+)(s+)(d+).*}{$3$2$1} and print | sort -rn | head -n1 | xargs -I @ echo @: high cyclomatic complexity.)count=`echo $result | cut -d -f1`if [ $count -gt $reasonable_upper_bound_for_CCN ]thenecho WARNING: $result >&2fi}
  33. 33. Don’tFeartheFilter
  34. 34. ThewholetimeI’mwritingcode,I’mconstantlytestingmyassumptions.—RasmusLerdorf
  35. 35. Questions?