Your SlideShare is downloading. ×
0
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Testing in JavaScript
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Testing in JavaScript

514

Published on

Here at Digital Natives we are devoted to support the automated testing of our applications. Lately we write more and more complex business logics on front-end side therefore we need to test front-end …

Here at Digital Natives we are devoted to support the automated testing of our applications. Lately we write more and more complex business logics on front-end side therefore we need to test front-end side codes more accurately. I put together a presentation for our weekly developer meeting concerning this topic, where I reviewed the current possibilities, but I think that it might be interesting for other front-end programmers too.

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

  • Be the first to like this

No Downloads
Views
Total Views
514
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. JS Unit Testing For both Backend and Frontend
  • 2. Why is unit testing good for js? ● you can develop without a browser ● you can test your code automatically ● you don’t have to test manually ● you don’t have to test via E2E test ● you can develop without a browser ○ of course for view development you have to use ● you can test you BE code
  • 3. Prerequisite (conditions) ● well separated code ○ like mvc (no spaghetti code) ○ small, testable parts (classes) ● zero or minimal dom dependency ○ dom is slow ○ very slow and you don’t want to mock it out
  • 4. How to test JS? ● you need a library ○ mocha ○ jasmine ○ Qunit ○ etc ● you have to run your tests ○ browser ○ node ○ karma (odd one out) ○ etc
  • 5. What I’m using ● Mocha ○ works with node ○ works with browser(s) (karma) ● Chai-TDD ○ closest to ruby expect
  • 6. Example JS code - User Model var User; User = (function() { function User(plainObject) { this.parse(plainObject); } User.prototype.parse = function(plainObject) { this.id = plainObject.id; this.first_name = plainObject.first_name; this.last_name = plainObject.last_name; this.status = plainObject.status; }; return User; })();
  • 7. How can we test Our Model? describe('User/Model', function() { var dummyUserData = { id: 1, first_name: 'First', last_name: 'Last', status: 'locked' }; describe('#initialize', function() { it('should set the provided fields', function() { var user = new User(dummyUserData); expect(user.first_name).to.eq('First'); expect(user.last_name).to.eq('Last'); expect(user.status).to.eq('locked'); }); }); });
  • 8. Test with a browser ● Create a test.html ● Include ○ mocha.js ○ chai.js ○ user_model.js ○ user_model_test.js ● open test.html
  • 9. open test.html
  • 10. How to use xhr in your model? User.prototype.get = function(cbSuccess, cbError) { var self = this; $.get("/users/" + this.id, function(data) { self.parse(data); cbSuccess(); }).fail(function(error, m) { cbError(); }); };
  • 11. In the browser you should ● include sinon.js ○ spy/stub/mock library ● include sinon server ○ xhr mocking server
  • 12. How to test async call? describe('with success xhr', function() { beforeEach(function() { var response = '{ "id": 1, "first_name": "Second First", "last_name": "Second Last", "status": "active" }'; server = sinon.fakeServer.create(); server.respondWith("GET", "/users/1", [200, { "Content-Type": "application/json" }, response ]); }); afterEach(function() { server.restore(); }); it('should set the newly provided data', function(done) { user.get(function() { expect(user.first_name).to.eq('Second First'); .... done(); }); server.respond(); }); });
  • 13. open test.html
  • 14. Test with multiple browsers (karma) ● open the browsers (silently) ● run your tests ● close the browsers (optional) ● rerun your tests on file changes (optional) ● outputs results to your console karma.conf.js { frameworks: ['mocha', 'chai'], files: [ 'vendor/**/*.js', 'user_model.js', 'user_model_tests.js' ], autoWatch: false, browsers: ['Chrome', 'Firefox'], singleRun: true };
  • 15. karma start
  • 16. Test with node ● basically the same as in browsers ○ only difference is the module system require (‘module’) ● faster than browsers ● you can test your BE and FE with the same test runner ○ if you doesn’t use browser specific stuff (like xhr, window, dom etc)
  • 17. Test with node var request = require("superagent"); var User; User = (function() { ... User.prototype.get = function(cbSuccess) { var url = "/users/" + this.id; request.get(url, function(res) { this.parse(res); cbSuccess(); }.bind(this)); }; return User; })(); module.exports = User; var chai = require('chai'); var expect = chai.expect; var sinon = require('sinon'); var User = require('../src/user'); var request = require("superagent"); describe('User/Model', function() { beforeEach(function() { var response = var response = '{ "id": 1, "first_name": "Second First", "last_name": "Second Last", "status": "active" }'; sinon.stub(request, "get").yields(response); }); }); ....
  • 18. mocha
  • 19. ● While I develop I want to to test my code via node ○ a lot faster ○ easier to test partials ● When I build I want to test my code via karma ○ we have to know if something is wrong in IE Same tests with node and karma
  • 20. Browserify ● you can use nodejs module syntax on the frontend ○ var UserModel = require(“Modules/User/Model”); ○ var userModel = new UserModel(); ● generate one js file with all the dependencies ● you can use same libraries on the FE and on the BE part ○ moment.js ○ schemata (js validation library) ○ your custom lib
  • 21. Schemate schema def. var schemata = require('schemata'); var UserSchema = schemata({ first_name: { name: 'First Name', type: String, validators: { all: [req] } }, last_name: { name: 'Last Name', type: String, validators: { all: [req] } }, status: { type: String, default: 'locked', validators: { all: [req] } } }); module.exports = UserSchema; REQUIRE VALIDATOR var req = function(key, keyDisplayName, object, callback) { var value = object[key]; if (typeof value !== “undefined” && value !== null){ return callback(null, undefined); } else { return callback(null, ' is required' ); } }; FE buttonClick = function(){ var json = this.toJson(); UserSchema.validate(json, function(errors){ if (Object.keys(errors).length === 0) return sendAjaxToTheServer(json); showErrors(errors); }); }
  • 22. Use browserify with mocha ● everything is the same as in the node tests ● you have to use karma preprocessor { frameworks: ['mocha', 'browserify'], preprocessors: { 'test/*': ['browserify'] } .... };
  • 23. Test with node / karma var request = require("superagent"); var User; User = (function() { ... User.prototype.get = function(cbSuccess) { var url = "/users/" + this.id; request.get(url, function(res) { this.parse(res); cbSuccess(); }.bind(this)); }; return User; })(); module.exports = User; var chai = require('chai'); var expect = chai.expect; var sinon = require('sinon'); var User = require('../src/user'); var request = require("superagent"); describe('User/Model', function() { beforeEach(function() { var response = var response = '{ "id": 1, "first_name": "Second First", "last_name": "Second Last", "status": "active" }'; sinon.stub(request, "get").yields(response); }); }); ....
  • 24. karma start | mocha
  • 25. Grunt - Config based Task runner ● There are a lot of contributed tasks ○ mochaTest, karma, browserify, concatenate, copy, ftp, sass, less, etc ● you can define complex tasks ○ build (jshint, concatenate, test:unit, test:e2e) ○ test (jshint, test:unit) ○ deploy (build, ftp)
  • 26. Grunt example You can create complex tasks test: - 'karma' - 'mochaTest' build: - 'jshint' - 'test' - 'browserify' - 'concatenate' - 'minify' - 'sass' - 'copy' Simple task, using grunt-contrib-mocha configuration file: mochaTest: feTest: options: clearRequireCache: true reporter: 'spec' src: ['test/fe/**/*.js'] beTest: options: clearRequireCache: true reporter: 'dots' src: ['test/be/**/*.js']
  • 27. grunt test
  • 28. Grunt watch ● watches for file changes ● runs tasks if one of the specified files have changed watch: scripts: files: ['test/unit/**/*.js', 'src/js/**/*.js'] tasks: ['jshint', 'mocha'] interrupt: true options: spawn: false jade: files: ['src/view/**/*.jade'] tasks: ['jade', ‘livereload:html’] interrupt: true options: spawn: false stylus: files: ['src/style/**/*.styl'] tasks: ['stylus', ‘livereload:css’] interrupt: false options: spawn: false
  • 29. grunt watch
  • 30. https://github.com/Valetudox/js_unit_testing we are hiring :)

×