Download - JS Frameworks Day April,26 of 2014
![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)
ありがとう