unit test in javascript
TRANSCRIPT
Unit testing
Rich UI brownbagswww.slideshare.net/bmarchal/unit-test-in-javascript
2
US Software Population
1950 1965 1980 1995 20100
10
20
30
40
50
60
70
80
90
100
Development personnel Maintenance personnel
The economics of software maintenance in the XXI century, Capers Jones, 2006
3
Benoît Marchal
http://marchal.com
4
Unit testsProven, well-known technique to delay legacy comesto JavaScript
5
Share RoMa frontend experienceWith unit tests
6
Unit tests in JavaScript
Jasmine helps us write formal, executable specifications. It integrates transparently with our development methodologies while supporting us with a set of tools.
7
Find them early, fix them cheaply
Re-quire-ments
Design & coding
Integration Testing Support0
10
20
30
40
50
60
70
80
90
Introduction of defects
Cost to fix
FORMAL SPECIFICATIONS
Delay legacy
9
How/when/why to use these?
• function union(gsA, gsB, geography) { // …}
• this.detach = function() { // …}
• function plantATree(inputNodes) { // …}
• { assume: function(uri, id, type) { // … }}
10
Show me an example
• it("fused municipalities", function() { var seeds = [ item("/antwerpen"), item("/arlon"), item("/brugge"), item("/gent"), item("/hasselt"), item("/leuven"), item("/liege"), item("/mons"), item("/namur"), item("/wavre") ], harvest = { "/antwerpen": { include: true, children: {} }, "/arlon": { include: true, children: {} }, "/brugge": { include: true, children: {} }, "/gent": { include: true, children: {} }, "/hasselt": { include: true, children: {} }, "/leuven": { include: true, children: {} }, "/liege": { include: true, children: {} }, "/mons": { include: true, children: {} }, "/namur": { include: true, children: {} }, "/wavre": { include: true, children: {} } }; expect(plantATree(seeds)).toEqual(harvest);});
11
Formal Specifications
• Formal component specifications– What is the component supposed to do?– Executable so always up-to-date– Specifications “by example”
• Testing is a tool, not a goal
– Alternatives• Design by contract• Assertions
• Legacy code: code without tests– Michael Feathers “Working effectively with legacy code”– Premature legacy
• Oftentimes easier to rewrite than to understand• Unit tests protect components
12
Written when…
• Understanding the problem or solution– Describe what you expect, include edge cases– Test that you implemented your understanding… for free– Akin to rubber duck debugging – By nature, UI work is iterative
• Teamwork– Encourage reuse: code samples for now or later– Ease maintenance: pinpoint source of problems– Team growth or change
• Refactoring– Enforce the existing API– Or highlight where it’s broken
13
Formal specifications
• Find problems early• Facilitates change• Simplifies integration• Documentation• Design
TRANSPARENT
Write it in plain JavaScript
15
Magically self-healing codeSadly it’s a myth
16
Documentation exposes equally
The good• Brilliant solution• Efficient component• Stable API• Beautiful design
• You see it,– You have confidence
And the not so good• Defect• Slow component• Difficult API• Odd design
• You see it,– You can improve it
17
Generic development cycle
Design/refactor
CodeTest
18
Test cycle
Design/refactor
Write tests
Code
Run (write) tests
19
SOLID is easier to specify/test*
• Single responsible principle– A component has a single responsibility
• Open/closed principle– Open for extension, closed for modification
• Liskov substitution principle– Objects replaceable with instances of their subtypes
• Interface segregation principle– Client-specific interfaces over general-purpose ones
• Dependency inversion principle– Depend upon abstractions, not concretions
• * = see separation of concerns
20
Transparent
• No silver bullet• Highlights equally strengths and flaws
– So you can see them
• Testable code is more likely to be SOLID• Fit it in your coding habits/methodologies
TOOLS
Making it fit
22
Jasmine and Karma
23
WebStorm or Grunt/PhantomJS
24
: separation of concerns
Factory
Service
Controller
Filter
Template
Directive
model
interaction
view
integration
25
templates
• it("responds to a click (direct compilation)", function() { $rootScope.$digest(); spyOn(scope, "tickle"); browserTrigger(element.children(), "click"); expect(scope.tickle).toHaveBeenCalled();});
26
jargon
• describe() : specification• it()• beforeEach() & afterEach()• xit() & xdescribe()• iit() & ddescribe()• createSpy() & createSpyObj()• expect()• jasmine.any()• matchers• dependency injection
27
Demo
28
Tools
templates
UNIT TESTS IN JAVASCRIPT
Share RoMa experience
30
Unit tests in JavaScript
Jasmine helps us write formal, executable specifications. It integrates transparently with our development methodologies while supporting us with a set of tools.
31
Check these out
• Guidelines and JavaScript Templates– http://wiki.netpost/display/ROMA/JS+unit+testing+and+specifications– http://svn.netpost:10080/svn/rom/branches/DEV_V0003.10.00/
• components/2020/ui/rom-ui-app/test/examples
• Writing testable code– http://wiki.netpost/display/ROMA/Testing+the+Domain+Model
• Angular guidelines– https://docs.angularjs.org/guide/unit-testing
• Tools– http://jasmine.github.io/– http://karma-runner.github.io/– http://www.jetbrains.com/webstorm/– http://gruntjs.com/– http://phantomjs.org/
32
Delay legacySpecifications in plain JavaScript