В поисках качества
JavaScript:
модульное тестирование
Анна Хабибуллина
DA-14 / da-14.com
anna.khabibullina@da-14.com
akhab...
ZE QUALITYS?
“Any feature without a test doesn’t exist”
Steve Loughran HP Laboratories
AGENDA
 Unit Testing Concept
 Pros & Cons
 Basic Terms & Structure
 TDD &/vs. BDD
 Tools & Libraries
 Unit Testing S...
UNIT TESTING CONCEPT
Unit testing is a method by which individual
units of source code are tested to determine
if they are...
WHY UNIT TESTING?
Unit tests find problems early in the
development cycle (TDD & BDD)
Refactoring
Integration
Documentatio...
IS UNIT TESTING A GOOD INVESTMENT?
 slow down the development process
 share the same blind spots with the code
 doesn’...
BASIC TERMS
In simple words, the goal of assertion is to
forcefully define if the test fails or passes.
STATEMENT PASSES FAILS
x = 1 a...
function initialize() {
// The initialization was successful.
return true;
}
Given the function initialize():
ASSERTION: E...
ASSERTION: EXAMPLE
var isInitialized = initialize();
TDD assert.isTrue(isInitialized)
BDD expect(isInitialized).to.be.true...
FIXTURE
A test fixture is a fixed state of the software
under test used as a baseline for running
tests.
In JavaScript for...
FIXTURE: EXAMPLE
Require the piece of markup stored in
myfixturemarkup.html file before each test:
beforeEach(function() {...
STUB
Method stubs
are functions
with pre-
programmed
behavior.
STUB: EXAMPLE
Forcing a method to throw an error in order
to test error handling.
var fn = foo.stub().throws(Error);
expec...
SPY
A test spy is a
function that
records
arguments,
return value, the
value of this and
exception thrown
(if any) for all...
SPY: EXAMPLE
Test that a function cursor.hide() has been
only called once, and only once.
sinon.spy(cursor, "hide");
TDD s...
MOCK
Mocks are fake objects with pre-
programmed behavior (like stubs) and
pre-programmed expectations.
They are like both...
MOCK: EXAMPLE
Create an expectation that jQuery.each is
called once, and only once, and also
instructs the mock to behave ...
MOCK: EXAMPLE
#1 – which method?
#2 – how many times it is called?
#3 – what are the arguments when the
method called?
#4 ...
TEST DRIVEN DEVELOPMENT(TDD)
TDD is a software
development
process that…
I’ll tell you the rest 
WHAT ARE THESE BDD?
ALRIGHT, WHAT IS BDD YOU ASK?
Terminology:
TDD BDD
Test Example
Assertion Expectation
Unit Behavior
BASIC STRUCTURE
#1. Setup/BeforeEach/Before
#2. Prepare an input
#3. Call a method
#4. Check an output
#5. Tear down/After...
#1. Setup / Before
before(function(done) {
// Create a basic document.
document = jsdom.jsdom();
window = document.parentW...
Before / BeforeEach
before(function() { console.log(‘before test’); });
test(‘first test’, function() { console.log(‘first...
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom
level.',
#2. Prepare an input and pr...
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom
level.',
#2. Prepare an input and pr...
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom
level.',
#2. Prepare an input and pr...
BASIC STRUCTURE: EXPLAINED
it('should initialize cursor if zoom level >= minimum zoom
level.',
#2. Prepare an input and pr...
#5. TearDown / After
after(function(done) {
// Remove global objects document.
document = null;
window = null;
done();
});...
OUTPUT
<testsuite name="Macchiato Tests" tests="13"
failures="0" errors="0" skipped="0"
timestamp="Mon, 02 Dec 2013 11:08:09 GMT"...
<failure classname="cursor #init()"
name="should initialize cursor if zoom level
&gt; minimum zoom level." time="0"
messag...
TOOLS
TOOLS
> 40 frameworks & libraries
qUnit(TDD) light-weight TDD framework
Jasmine(BDD) flexible BDD framework
Mocha / Karma ...
ENTIRE SPACE OF FRAMEWORKS…
HOW DO I UNIT TEST
Known Frameworks / Libraries?
What to test? What to use?
Angular, React, Flight Karma + Jasmine
Backbon...
TOOLS: WHAT WE USE
 Run UT: Mocha
 Run UT in parallel: Macchiato
 Assert/Expect: Chai
 W3C DOM in JavaScript: Jsdom
 ...
TOOLS: WHAT WE USE
TOOLS: WHAT WE USE
Project unit tested like a dream ♥
UNIT TESTING SPECIFICS IN JAVASCRIPT
UI
Load fake data via “fixtures”
Jsdom(W3C JavaScript implementation)
UNIT TESTING SPECIFICS IN JAVASCRIPT
AJAX
Stub jQuery.ajax
Fake XMLHttpRequest
(XMLHTTP ActiveXObject)
Fake server
UNIT TESTING SPECIFICS IN JAVASCRIPT
3rd-party scripts
Stubbing jQuery plugin functions
(mock jQuery.fn)
UNIT TESTING SPECIFICS IN JAVASCRIPT
Dependency Injection
Mocking deps in RequireJs sucks hard!
Squire.js lib / testr.js
UNIT TESTING SPECIFICS IN JAVASCRIPT
NodeJs
Server-side specifics
rewire: node.js dependency injection
BEST PRACTISES
Fast
Isolated
Consistent
Responsibility
Self-descriptive
No exception Handling
Use assertions when needed
WRAPPING UP
 Each test verifies a small chunk of code
 Unit tests work best in isolation
 Mocks, stubs and spies help t...
SHWEEET
ありがとう
Upcoming SlideShare
Loading in …5
×

Js fwdays unit tesing javascript(by Anna Khabibullina)

1,799 views

Published on

See video from JS Frameworks Day, April 2014
https://www.youtube.com/watch?v=edOIMiQFZ2w&list=UU3NDbeN0Jq_InNAhiJtvHcQ

Published in: Engineering, Technology, Education
1 Comment
0 Likes
Statistics
Notes
  • Be the first to like this

No Downloads
Views
Total views
1,799
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide

Js fwdays unit tesing javascript(by Anna Khabibullina)

  1. 1. В поисках качества JavaScript: модульное тестирование Анна Хабибуллина DA-14 / da-14.com anna.khabibullina@da-14.com akhabibullina _khabibullina
  2. 2. ZE QUALITYS? “Any feature without a test doesn’t exist” Steve Loughran HP Laboratories
  3. 3. AGENDA  Unit Testing Concept  Pros & Cons  Basic Terms & Structure  TDD &/vs. BDD  Tools & Libraries  Unit Testing Specifics in JavaScript  Best Practices
  4. 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.
  5. 5. WHY UNIT TESTING? Unit tests find problems early in the development cycle (TDD & BDD) Refactoring Integration Documentation Better design
  6. 6. 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
  7. 7. BASIC TERMS
  8. 8. In simple words, the goal of assertion is to forcefully define if the test fails or passes. STATEMENT PASSES FAILS x = 1 assert(x > 0) assert(x < 0) expect(4+5).to.equal(9); ASSERTION
  9. 9. function initialize() { // The initialization was successful. return true; } Given the function initialize(): ASSERTION: EXAMPLE
  10. 10. ASSERTION: EXAMPLE var isInitialized = initialize(); TDD assert.isTrue(isInitialized) BDD expect(isInitialized).to.be.true Check that function initialize() returns true when called.
  11. 11. 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.
  12. 12. FIXTURE: EXAMPLE Require the piece of markup stored in myfixturemarkup.html file before each test: beforeEach(function() { loadFixtures('myfixturemarkup.html'); });
  13. 13. STUB Method stubs are functions with pre- programmed behavior.
  14. 14. 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);
  15. 15. 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.
  16. 16. 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
  17. 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.
  18. 18. 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);
  19. 19. 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?
  20. 20. TEST DRIVEN DEVELOPMENT(TDD) TDD is a software development process that… I’ll tell you the rest 
  21. 21. WHAT ARE THESE BDD?
  22. 22. ALRIGHT, WHAT IS BDD YOU ASK? Terminology: TDD BDD Test Example Assertion Expectation Unit Behavior
  23. 23. BASIC STRUCTURE #1. Setup/BeforeEach/Before #2. Prepare an input #3. Call a method #4. Check an output #5. Tear down/AfterEach/After
  24. 24. #1. Setup / Before before(function(done) { // Create a basic document. document = jsdom.jsdom(); window = document.parentWindow; done(); }); BASIC STRUCTURE: EXPLAINED
  25. 25. Before / BeforeEach 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 BASIC STRUCTURE: EXPLAINED
  26. 26. 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) {
  27. 27. 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) {
  28. 28. 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) {
  29. 29. 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) {
  30. 30. #5. TearDown / After after(function(done) { // Remove global objects document. document = null; window = null; done(); }); BASIC STRUCTURE: EXPLAINED
  31. 31. OUTPUT
  32. 32. <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 &gt; minimum zoom level." time="0.004"/> </testsuite> OUTPUT: SUCCESS
  33. 33. <failure classname="cursor #init()" name="should initialize cursor if zoom level &gt; 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
  34. 34. TOOLS
  35. 35. 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
  36. 36. ENTIRE SPACE OF FRAMEWORKS…
  37. 37. HOW DO I UNIT TEST Known Frameworks / Libraries? What to test? What to use? Angular, React, Flight Karma + Jasmine Backbone qUnit Ember Karma + qUnit (ember-app-kit) ExtJs Jasmine, Siesta (UI) TypeScript tsUnit CoffeeScript qUnit Dart Unittest, Hop and Drone.io NodeJs expresso and vows, Nodeunit
  38. 38. 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
  39. 39. TOOLS: WHAT WE USE
  40. 40. TOOLS: WHAT WE USE Project unit tested like a dream ♥
  41. 41. UNIT TESTING SPECIFICS IN JAVASCRIPT UI Load fake data via “fixtures” Jsdom(W3C JavaScript implementation)
  42. 42. UNIT TESTING SPECIFICS IN JAVASCRIPT AJAX Stub jQuery.ajax Fake XMLHttpRequest (XMLHTTP ActiveXObject) Fake server
  43. 43. UNIT TESTING SPECIFICS IN JAVASCRIPT 3rd-party scripts Stubbing jQuery plugin functions (mock jQuery.fn)
  44. 44. UNIT TESTING SPECIFICS IN JAVASCRIPT Dependency Injection Mocking deps in RequireJs sucks hard! Squire.js lib / testr.js
  45. 45. UNIT TESTING SPECIFICS IN JAVASCRIPT NodeJs Server-side specifics rewire: node.js dependency injection
  46. 46. BEST PRACTISES Fast Isolated Consistent Responsibility Self-descriptive No exception Handling Use assertions when needed
  47. 47. 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!
  48. 48. SHWEEET
  49. 49. ありがとう

×