js frameworks day april,26 of 2014
DESCRIPTION
Unit Testing in Javascript The way to quality product isn't easy or simple but it is reachable. One of the key things to do is unit testing. What, when and how to do it --> read in the presentation. See more details here: http://www.slideshare.net/AnnaKhabibullina/jsfwdays-2014unittesingjavascriptv4-33966202 Read about this and other techtalks @ DA-14 in our blog: http://da-14.com/our-blog/TRANSCRIPT
![Page 1: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/1.jpg)
В поисках качества JavaScript:модульное тестированиеАнна ХабибуллинаDA-14 / da-14.com
akhabibullina
_khabibullina
![Page 2: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/2.jpg)
ZE QUALITYS?
“Any feature without a test doesn’t exist”
Steve Loughran HP Laboratories
![Page 3: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/3.jpg)
AGENDA
Unit Testing Concept Pros & Cons Basic Terms & Structure TDD &/vs. BDD Tools & Libraries Unit Testing Specifics in JavaScript Best Practices
![Page 4: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/4.jpg)
UNIT TESTING CONCEPT
Unit testing is a method by which individual units of source code are tested to determine
if they are fit for use.
![Page 5: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/5.jpg)
WHY UNIT TESTING?
Unit tests find problems early in the development cycle (TDD & BDD)
Refactoring
Integration
Documentation
Better design
![Page 6: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/6.jpg)
IS UNIT TESTING A GOOD INVESTMENT?
slow down the development process
share the same blind spots with the code
doesn’t prove that they’re compatible with one another or configured correctly
![Page 7: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/7.jpg)
BASIC TERMS
![Page 8: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/8.jpg)
In simple words, the goal of assertion is to forcefully define if the test fails or passes.
STATEMENT PASSES FAILSx = 1 assert(x > 0) assert(x < 0)
expect(4+5).to.equal(9);
ASSERTION
![Page 9: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/9.jpg)
function initialize() {
// The initialization was successful. return true;}
Given the function initialize():
ASSERTION: EXAMPLE
![Page 10: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/10.jpg)
ASSERTION: EXAMPLE
var isInitialized = initialize();
TDD assert.isTrue(isInitialized)BDD expect(isInitialized).to.be.true
Check that function initialize() returns true when called.
![Page 11: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/11.jpg)
FIXTURE
A test fixture is a fixed state of the software under test used as a baseline for running tests. In JavaScript for client side:
simulate AJAX responses;loading known set of data such as html objects.
![Page 12: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/12.jpg)
FIXTURE: EXAMPLE
Require the piece of markup stored in myfixturemarkup.html file before each test:
beforeEach(function() {
loadFixtures('myfixturemarkup.html');
});
![Page 13: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/13.jpg)
STUB
Method stubs are functions
with pre-programmed
behavior.
![Page 14: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/14.jpg)
STUB: EXAMPLE
Forcing a method to throw an error in order to test error handling.
var fn = foo.stub().throws(Error);
expect(fn).to.throw(Error);
![Page 15: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/15.jpg)
SPY
A test spy is a function that
records arguments,
return value, the value of this and exception thrown (if any) for all its
calls.
![Page 16: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/16.jpg)
SPY: EXAMPLE
Test that a function cursor.hide() has been only called once, and only once.
sinon.spy(cursor, "hide");
TDD sinon.assert.calledOnce(cursor.hide) BDD expect(cursor.hide.calledOnce).to.be.true
![Page 17: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/17.jpg)
MOCK
Mocks are fake objects with pre-programmed behavior (like stubs) and
pre-programmed expectations.They are like both stubs and spies – in
one.
![Page 18: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/18.jpg)
MOCK: EXAMPLE
Create an expectation that jQuery.each is called once, and only once, and also instructs the mock to behave as we pre-define.
var mock = sinon.mock(jQuery);
![Page 19: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/19.jpg)
MOCK: EXAMPLE
#1 – which method?#2 – how many times it is called?#3 – what are the arguments when the method called?#4 – what the method returns?
![Page 20: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/20.jpg)
TEST DRIVEN DEVELOPMENT(TDD)
TDD is a software development process that…I’ll tell you the rest
![Page 21: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/21.jpg)
WHAT ARE THESE BDD?
![Page 22: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/22.jpg)
ALRIGHT, WHAT IS BDD YOU ASK?
Terminology:
TDD BDDTest ExampleAssertion ExpectationUnit Behavior
![Page 23: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/23.jpg)
BASIC STRUCTURE
#1. Setup/BeforeEach/Before
#2. Prepare an input
#3. Call a method
#4. Check an output
#5. Tear down/AfterEach/After
![Page 24: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/24.jpg)
#1. Setup / Before
before(function(done) { // Create a basic document. document = jsdom.jsdom(); window = document.parentWindow; done(); });
BASIC STRUCTURE: EXPLAINED
![Page 25: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/25.jpg)
Before / BeforeEachbefore(function() { console.log(‘before test’); });
test(‘first test’, function() { console.log(‘first test’); });
test(‘second test’, function() { console.log(‘second test’);});
afterEach(function() { console.log(‘after each test’); });
Result
before testfirst testafter each testsecond testafter each test
BASIC STRUCTURE: EXPLAINED
![Page 26: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/26.jpg)
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom level.',
#2. Prepare an input and predicted result. var minZoomLevel = 1; var zoomLevel = minZoomLevel + 0.1; var expectedCursor = {‘color’: ‘white’, ‘height’: … };
#3. Call a method. var actualCursor = cursor.init(zoomLevel);
#4. Check an output. expect(actualCursor).to.deep.equal(expectedCursor); done();
});
function(done) {
![Page 27: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/27.jpg)
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom level.',
#2. Prepare an input and predicted result. var minZoomLevel = 1; var zoomLevel = minZoomLevel + 0.1; var expectedCursor = {‘color’: ‘white’, ‘height’: … };
#3. Call a method. var actualCursor = cursor.init(zoomLevel);
#4. Check an output. expect(actualCursor).to.deep.equal(expectedCursor); done();
});
function(done) {
![Page 28: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/28.jpg)
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom level.',
#2. Prepare an input and predicted result. var minZoomLevel = 1; var zoomLevel = minZoomLevel + 0.1; var expectedCursor = {‘color’: ‘white’, ‘height’: … };
#3. Call a method. var actualCursor = cursor.init(zoomLevel);
#4. Check an output. expect(actualCursor).to.deep.equal(expectedCursor); done();
});
function(done) {
![Page 29: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/29.jpg)
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom level.',
#2. Prepare an input and predicted result. var minZoomLevel = 1; var zoomLevel = minZoomLevel + 0.1; var expectedCursor = {‘color’: ‘white’, ‘height’: … };
#3. Call a method. var actualCursor = cursor.init(zoomLevel);
#4. Check an output. expect(actualCursor).to.deep.equal(expectedCursor); done();
});
function(done) {
![Page 30: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/30.jpg)
#5. TearDown / After
after(function(done) {// Remove global objects document. document = null; window = null;done();
});
BASIC STRUCTURE: EXPLAINED
![Page 31: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/31.jpg)
OUTPUT
![Page 32: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/32.jpg)
<testsuite name="Macchiato Tests" tests="13" failures="0" errors="0" skipped="0" timestamp="Mon, 02 Dec 2013 11:08:09 GMT" time="0.114">
<testcase classname = "cursor #init ()" name = "should initialize cursor if zoom level > minimum zoom level." time="0.004"/>
</testsuite>
OUTPUT: SUCCESS
![Page 33: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/33.jpg)
<failure classname="cursor #init()" name="should initialize cursor if zoom level > minimum zoom level." time="0" message="Cannot read property 'show' of undefined"><![CDATA[TypeError: Cannot read property 'show' of undefined
// ..... Exception Stack Trace .....
</failure>
OUTPUT: FAILURE
![Page 34: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/34.jpg)
TOOLS
![Page 35: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/35.jpg)
TOOLS
> 40 frameworks & libraries
qUnit(TDD) light-weight TDD framework
Jasmine(BDD) flexible BDD framework
Mocha / Karma test runner for async code
+ Chai TDD / BDD assertion library
+ Sinon test spies, stubs & mocks
![Page 36: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/36.jpg)
ENTIRE SPACE OF FRAMEWORKS…
![Page 37: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/37.jpg)
HOW DO I UNIT TEST Known Frameworks / Libraries?
What to test? What to use?Angular, React, Flight Karma + JasmineBackbone qUnitEmber Karma + qUnit (ember-app-kit)ExtJs Jasmine, Siesta (UI)TypeScript tsUnitCoffeeScript qUnitDart Unittest, Hop and Drone.io
NodeJs expresso and vows, Nodeunit
![Page 38: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/38.jpg)
TOOLS: WHAT WE USE
Run UT: Mocha Run UT in parallel: Macchiato Assert/Expect: Chai W3C DOM in JavaScript: Jsdom Mock, spy, stub: Sinon Code coverage tool: None Routine automation: make/Grunt
![Page 39: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/39.jpg)
TOOLS: WHAT WE USE
![Page 40: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/40.jpg)
TOOLS: WHAT WE USE
Project unit tested like a dream ♥
![Page 41: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/41.jpg)
UNIT TESTING SPECIFICS IN JAVASCRIPT
UI
Load fake data via “fixtures”Jsdom(W3C JavaScript implementation)
![Page 42: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/42.jpg)
UNIT TESTING SPECIFICS IN JAVASCRIPT
AJAX
Stub jQuery.ajaxFake XMLHttpRequest
(XMLHTTP ActiveXObject)Fake server
![Page 43: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/43.jpg)
UNIT TESTING SPECIFICS IN JAVASCRIPT
3rd-party scripts
Stubbing jQuery plugin functions(mock jQuery.fn)
![Page 44: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/44.jpg)
UNIT TESTING SPECIFICS IN JAVASCRIPT
Dependency Injection
Mocking deps in RequireJs sucks hard! Squire.js lib / testr.js
![Page 45: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/45.jpg)
UNIT TESTING SPECIFICS IN JAVASCRIPT
NodeJs
Server-side specificsrewire: node.js dependency injection
![Page 46: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/46.jpg)
BEST PRACTISES
FastIsolatedConsistentResponsibilitySelf-descriptiveNo exception HandlingUse assertions when needed
![Page 47: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/47.jpg)
WRAPPING UP
Each test verifies a small chunk of code
Unit tests work best in isolation Mocks, stubs and spies help to
isolate test Don’t test everything but write
many tests > 40 tools are available to ease
unit testing experience, so CHOOSE YOUR OWN!
![Page 48: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/48.jpg)
SHWEEET
![Page 49: JS Frameworks Day April,26 of 2014](https://reader034.vdocuments.pub/reader034/viewer/2022042713/53f505938d7f7246588b4598/html5/thumbnails/49.jpg)
ありがとう