In search of JavaScript code quality: unit testing
1.
2. AGENDA
Unit Testing Concept
Why Unit Testing?
Test Driven Development (a.k.a. TDD)
Basic Terms & Structure
Tools & Libraries
Unit Testing Specifics in JavaScript
Best Practices
3.
4. 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.
Unit is the smallest testable piece of
code.
Unit tests are created by programmers.
5.
6. COMMON SENSE OR WHY UNIT TESTING?
Unit tests find problems early in the development cycle (TDD
& BDD)
Refactoring
Documentation
design
Integration
Better
7. IS UNIT TESTING A GOOD INVESTMENT?
Might slow down the development
process.
The tests may share the same blind
spots with the code.
Proving that components X and Y both
work independently doesn’t prove
that they’re compatible with one
another or configured correctly.
8.
9. TEST DRIVEN DEVELOPMENT(TDD)
Test-driven development is
related to the test-first
programming concepts of
extreme programming (XP).
TDD is a software development
process that relies on the
repetition of short development
cycle shown on the screen to the
left.
Behavior-driven
development(BDD) based on
TDD…
10. ALRIGHT, SO WHAT IS BDD YOU ASK?
Behavior-driven development (BDD) isn't anything new or
revolutionary. It's just TDD with any test-related
terminology replaced by examples-of-behavior-related
terminology:
TDD term
BDD term
Test
Example
Assertion
Expectation
assert
should, expect
Unit
Behavior
Verification
Specification
11.
12. ASSERTION
In simple words, the goal of assertion is to forcefully define
if the test fails or passes.
Example #1:
Statement
Passes(True)
Fails(False)
x = 1;
assert (x > 0)
assert (x < 0)
x++;
assert (x > 1)
assert (x < 1)
13. ASSERTION: EXAMPLE
Example(Chai) #2:
Given the function initialize():
function initialize() {
//… Some code goes here …
// The initialization went successfully.
return true;
}
Check that function initialize() returns true when called.
var isInitialized = initialize();
TDD syntax
BDD syntax
assert.isTrue(isInitialized)
expect(isInitialized).to.be.true
14. FIXTURE
A test fixture is a fixed state of the software under test used as a
baseline for running tests.
In JavaScript: simulate AJAX responses; loading known set of
data, such as html objects.
Example(Jasmine):
Require the piece of markup stored in myfixturemarkup.html file before each
test:
beforeEach(function() {
loadFixtures('myfixturemarkup.html');
});
15. STUB
Method stubs are functions with pre-programmed behavior.
Example (Sinon):
Forcing a method to throw an error in order to test error handling.
var fn = foo.stub().throws(Error);
expect(fn).to.throw(Error);
16. 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.
Example(Sinon):
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
17. MOCK
Mocks are fake objects with pre-programmed behavior (like
stubs) and pre-programmed expectations. They are like both
stubs and spies – in one.
Mocks isolate the imitate the dependency and thus isolate the
unit test.
18. MOCK: EXAMPLE
Example(Sinon):
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);
#1 – which method?(“jQuery.each”)
#2 – how many times it is called?(only once)
#3 – what are the arguments when the method called? (1, {})
#4 – what the method returns? (empty object)
22. BASIC STRUCTURE EXPLAINED
before(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 test
first test
after each test
second test
after each test
23. BASIC STRUCTURE EXPLAINED
it('should not initialize cursor if zoom level <= minimum zoom level.',
function(done) {
#2. Prepare an input and predicted result.
var zoomLevel = 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();
});
‘32px’, etc…};
30. 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
31.
32. UNIT TESTING SPECIFICS IN JAVASCRIPT
Stubbing jQuery plugin functions(mock jQuery.fn)
Testing Ajax requests
Stub jQuery.ajax
Fake XMLHttpRequest(XMLHTTP ActiveXObject)
Fake server
Mocking DOM elements
Load fake data via “fixtures”
Use W3C Javascript implementation Jsdom
35. Senior Frontend Developer at GlobalLogic
Co-founder of IT company DA-14
Contributor of HoganJs,
Backbone.Validations
http://da-14.com/
akhabibullina
_khabibullina
ua.linkedin.com/pub/anna-khabibullina/38/566/463/