0
Introduction toJavaScript TestingRan Mizrahi (@ranm8)Open Source Dpt. Leader @ CodeOasisSaturday, April 27, 13
About CodeOasis• CodeOasis specializes in cutting-edge web solutions.• Large variety of customers (from startups to enterp...
Why Do Software Projects Fail?!• Deliver late or over budget.• Deliver the wrong thing.• Unstable in production.Production...
Why Do Software Projects Fail?!Saturday, April 27, 13
Untestable code...function createUser(properties) {var user = {firstName: properties.firstName,lastName: properties.lastNa...
Why Test Your Code???The problems with untestable code:• Tightly coupled.• No separation of concerns.• Not readable.• Not ...
Why Test Your Code???The problems with untestable code:• Tightly coupled.• No separation of concerns.• Not readable.• Not ...
Test-Driven Development To The Recuse!Methodology for using automated unittests to drive software design, qualityand stabi...
Test-Driven Development To The Recuse!How it’s done :• First the developer writesa failing test case thatdefines a desiredf...
Seems Great But How Much Longer Does TDD Takes???My experience:• Initial progress will be slower.• Greater consistency.• L...
The Three Rules of TDDRule #1Your code should always fail before you implement the codeRule #2Implement the simplest code ...
BDD (Behavior-Driven Development)Test-Driven DevelopmentSaturday, April 27, 13
BDD (Behavior-Driven Development)Test-Driven DevelopmentWhat exactly are we testing?!Saturday, April 27, 13
BDD (Behavior-Driven Development)• Originally started in 2003 by Dan North, author of JBehave, thefirst BDD tool.• Based on...
BDD (Behavior-Driven Development)Feature: lsIn order to see the directory structureAs a UNIX userI need to be able to list...
Main Test Types• Unit Testing• Integration Testing• Functional TestingSaturday, April 27, 13
Challenges Testing JavaScript• Async tests:• Testing async methods can be tricky.• Define tests timeout.• Indicate when tes...
TDD/BDD using Mocha and Expect.jsMocha is a feature-rich JavaScript test frameworks running onnode and the browser, making...
TDD/BDD using Mocha and Expect.jsExpect.js is a minimalistic assertion library based on should.jsExpect.jsMain features:• ...
TDD/BDD using Mocha and Expect.jsInstalling Mocha and Expect.js$ npm install mocha -g$ npm install expect.js -gInstall moc...
TDD/BDD using Mocha and Expect.jsvar expect = require(expect.js);describe(Array, function() {describe(#indexOf(), function...
TDD/BDD using Mocha and Expect.js“Async” test:var expect = require(expect.js);function asyncCall(val ,callback) {var prefi...
Back to our codeSaturday, April 27, 13
First, Let’s Write The Tests!function createUser(properties) {var user = {firstName: properties.firstName,lastName: proper...
First, Let’s Write The Tests!What to test in our case:• Validations.• Full name getter.• User save callbackWhat not to tes...
First, Let’s Write The Tests!describe(User, function() {var user;beforeEach(function() {// Create the user objuser = new U...
Run those testsSaturday, April 27, 13
Now, Let’s Write The Codevar User = (function() {use strict;var User = function(properties) {// Set some datathis.firstNam...
Run those tests,again!Saturday, April 27, 13
Running The Testsmocha tests can run in different environments and formats:• Browser - using mocha.js (see example)• For CI...
Benefits of Testing Your Code• Short feedback/testing cycle.• High code coverage of tests that can be at run any time topro...
Questions?Thank you!Saturday, April 27, 13
Upcoming SlideShare
Loading in...5
×

Intro to JavaScript Testing

2,866

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,866
On Slideshare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
9
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Intro to JavaScript Testing"

  1. 1. Introduction toJavaScript TestingRan Mizrahi (@ranm8)Open Source Dpt. Leader @ CodeOasisSaturday, April 27, 13
  2. 2. About CodeOasis• CodeOasis specializes in cutting-edge web solutions.• Large variety of customers (from startups to enterprises).• Technologies we love:• PHP - Symfony2 and Drupal• node.js• HTML5• CSS3• AngularJS• Our Microsoft department works with C#, WPF, etc.Saturday, April 27, 13
  3. 3. Why Do Software Projects Fail?!• Deliver late or over budget.• Deliver the wrong thing.• Unstable in production.Production Maintenance• Expensive maintenance.• Long adjustment to marketneeds.• Long development cycles.Saturday, April 27, 13
  4. 4. Why Do Software Projects Fail?!Saturday, April 27, 13
  5. 5. Untestable code...function createUser(properties) {var user = {firstName: properties.firstName,lastName: properties.lastName,username: properties.username,mail: properties.mail};var fullName = User.firstName + + User.lastName;// Make sure user is validif (!user.firstName || !user.lastName) {throw new Error(First or last name are not valid!);} else if(typeof user.mail === string && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/)) === null) {throw new Error(Mail is not valid);} else if (!user.username) {throw new Error(Username is not valid);}$.post(/user, {fullName: fullName,userName: user.username,mail: user.mail}, function(data) {var message;if (data.code === 200) {message = User saved successfully!;} else {message = Operation was failed!;}$(#some-div).animate({margin-left: $(window).width()}, 1000, function() {$(this).html(message);});});}Saturday, April 27, 13
  6. 6. Why Test Your Code???The problems with untestable code:• Tightly coupled.• No separation of concerns.• Not readable.• Not predictable.• Global states.• Long methods.• Large classes/objects.Saturday, April 27, 13
  7. 7. Why Test Your Code???The problems with untestable code:• Tightly coupled.• No separation of concerns.• Not readable.• Not predictable.• Global states.• Long methods.• Large classes/objects.>• Hard to maintain.• High learning curve.• Stability issues.• You can never expectproblems before theyoccurSaturday, April 27, 13
  8. 8. Test-Driven Development To The Recuse!Methodology for using automated unittests to drive software design, qualityand stability.Saturday, April 27, 13
  9. 9. Test-Driven Development To The Recuse!How it’s done :• First the developer writesa failing test case thatdefines a desiredfunctionality to thesoftware.• Makes the code passthose tests.• Refactor the code to meetstandards.Saturday, April 27, 13
  10. 10. Seems Great But How Much Longer Does TDD Takes???My experience:• Initial progress will be slower.• Greater consistency.• Long tern cost is drasticallylower• After getting used to it, youcan write TDD faster (-:Studies:• Takes 15-30% longer.• 45-80% less bugs.• Fixing bugs later on isdramatically faster.Saturday, April 27, 13
  11. 11. The Three Rules of TDDRule #1Your code should always fail before you implement the codeRule #2Implement the simplest code possible to pass your tests.Rule #3Refactor, refactor and refractor - There is no shame in refactoring.Saturday, April 27, 13
  12. 12. BDD (Behavior-Driven Development)Test-Driven DevelopmentSaturday, April 27, 13
  13. 13. BDD (Behavior-Driven Development)Test-Driven DevelopmentWhat exactly are we testing?!Saturday, April 27, 13
  14. 14. BDD (Behavior-Driven Development)• Originally started in 2003 by Dan North, author of JBehave, thefirst BDD tool.• Based on the TDD methodology.• Aims to provide tools for both developers and business (e.g.product manager, etc.) to share development process together.• The steps of BDD :• Developers and business personas write specification together.• Developer writes tests based on specs and make them fail.• Write code to pass those tests.• Refactor, refactor, refactor...Saturday, April 27, 13
  15. 15. BDD (Behavior-Driven Development)Feature: lsIn order to see the directory structureAs a UNIX userI need to be able to list the current directorys contentsScenario: List 2 files in a directoryGiven I am in a directory "test"And I have a file named "foo"And I have a file named "bar"When I run "ls"Then I should get:"""barfoo"""Saturday, April 27, 13
  16. 16. Main Test Types• Unit Testing• Integration Testing• Functional TestingSaturday, April 27, 13
  17. 17. Challenges Testing JavaScript• Async tests:• Testing async methods can be tricky.• Define tests timeout.• Indicate when test is completed in callback.• Assert on callback.• DOM:• Testing DOM is a difficult task.• The key is to separate your controller and model logic fromDOM and test those only.• Testing DOM is done using functional testing (e.g. WebDriver,etc.)Saturday, April 27, 13
  18. 18. TDD/BDD using Mocha and Expect.jsMocha is a feature-rich JavaScript test frameworks running onnode and the browser, making asynchronies tests easy.MochaMain features:• Supports both TDD and BDD styles.• Both browser and node support.• Proper exit status for CI support.• node.js debugger support.• Highly flexible, choose and join the pieces yourself (spy library,assertion library, etc.).Saturday, April 27, 13
  19. 19. TDD/BDD using Mocha and Expect.jsExpect.js is a minimalistic assertion library based on should.jsExpect.jsMain features:• BDD style.• Compatible with all test frameworks.• Both node.js and browser compatible.• Standalone assertion library.Saturday, April 27, 13
  20. 20. TDD/BDD using Mocha and Expect.jsInstalling Mocha and Expect.js$ npm install mocha -g$ npm install expect.js -gInstall mocha globally using npm:Install Expect.js:Saturday, April 27, 13
  21. 21. TDD/BDD using Mocha and Expect.jsvar expect = require(expect.js);describe(Array, function() {describe(#indexOf(), function() {it(Expect -1 when the value is not present, function() {var array = [1, 2, 3];expect(array.indexOf(4)).to.be(-1);});});});“Normal” test:Run it..$ mocha --reporter specArray#indexOf()✓ Expect -1 when the value is not present1 test complete (5 ms)Saturday, April 27, 13
  22. 22. TDD/BDD using Mocha and Expect.js“Async” test:var expect = require(expect.js);function asyncCall(val ,callback) {var prefix = - ;setTimeout(function() {var newString = val + prefix + OK;callback(newString);}, 500);}describe(asyncCall, function() {it(Add suffix that prefixed with - to the given string, function(done) {var testVal = Foo;asyncCall(testVal, function(response) {expect(response).to.contain(testVal + - OK);done();});});});Let’s run it...Saturday, April 27, 13
  23. 23. Back to our codeSaturday, April 27, 13
  24. 24. First, Let’s Write The Tests!function createUser(properties) {var user = {firstName: properties.firstName,lastName: properties.lastName,username: properties.username,mail: properties.mail};var fullName = User.firstName + + User.lastName;// Make sure user is validif (!user.firstName || !user.lastName) {throw new Error(First or last name are not valid!);} else if(typeof user.mail === string && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/)) === null) {throw new Error(Mail is not valid);} else if (!user.username) {throw new Error(Username is not valid);}$.post(/user, {fullName: fullName,userName: user.username,mail: user.mail}, function(data) {var message;if (data.code === 200) {message = User saved successfully!;} else {message = Operation was failed!;}$(#some-div).animate({margin-left: $(window).width()}, 1000, function() {$(this).html(message);});});}Saturday, April 27, 13
  25. 25. First, Let’s Write The Tests!What to test in our case:• Validations.• Full name getter.• User save callbackWhat not to test :• DOM manipulations - for that, we should use functional testing forthat cause (e.g. WebDriver)• AJAX requests - Leaving integration testing aside.Saturday, April 27, 13
  26. 26. First, Let’s Write The Tests!describe(User, function() {var user;beforeEach(function() {// Create the user objuser = new User({firstName: Ran,lastName: Mizrahi,mail: ranm@codeoasis.com,username: ranm});});afterEach(function() {// clean-upuser = {};});describe(#fullName(), function() {it(Should return firstName and lastName separated by space, function() {expect(user.fullName).to.be(Ran Mizrahi);});});describe(#save(), function() {it(Should save user without any errors, function(done) {user.save(function(error) {if (error) {throw error;} else {done();}});});});describe(#mail(), function() {it(Should set mail correctly after mail validation, function() {expect(user.mail).to.be(ranm@codeoasis.com);});});});Saturday, April 27, 13
  27. 27. Run those testsSaturday, April 27, 13
  28. 28. Now, Let’s Write The Codevar User = (function() {use strict;var User = function(properties) {// Set some datathis.firstName = properties.firstName || ;this.lastName = properties.lastName || ;this.username = properties.username || ;this.mail = properties.mail || ;};User.__defineGetter__(fullName, function() {return this.firstName + + this.lastName;});User.__defineSetter__(mail, function(mail) {var matcher = new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/);if (mail.match(matcher) === null) {throw Mail is not valid;}this._mail = mail;});User.prototype.save = function(callback) {setTimeout(function() {callback();}, 1000);return this;};return User;}());Saturday, April 27, 13
  29. 29. Run those tests,again!Saturday, April 27, 13
  30. 30. Running The Testsmocha tests can run in different environments and formats:• Browser - using mocha.js (see example)• For CI automation use JSTestDriver.• CLI - as demonstrated before using the “mocha” command.• CI (e.g. xunit) - $ mocha test/asyncTest.js --reporter xunit.• Many other formats (JSON, HTML, list, Spec, etc.)Saturday, April 27, 13
  31. 31. Benefits of Testing Your Code• Short feedback/testing cycle.• High code coverage of tests that can be at run any time toprovide feedback that the software is functioning.• Provides detailed spec/docs of the application.• Less time spent on debugging and refactoring.• Know what breaks early on.• Enforces code quality (decoupled) and simplicity.• Help you focus on writing one job code units.Saturday, April 27, 13
  32. 32. Questions?Thank you!Saturday, April 27, 13
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×