KEMBAR78
Client side unit tests - using jasmine & karma | PDF
Client side testingClient side testing
Before we startBefore we start
Hebrew or English?
Don't wait for the "Questions?" slide
I'm skipping the "why test?" intro
YouYou
Adam Klein
CTO of 500Tech
meetup.com/AngularJS-IL
angular.co.il
hackademy.co.il
Among our clients:
- Wix
- Cellebrite
- eToro
- Autodesk
- ...
MeMe
JasmineJasmine
The most popular testing
framework
var Person = function(first, last) {
this.fullname = function() {
return first + ' ' + last;
}
}
describe ('Person', function() {
it('should return fullname correctly', function() {
var p = new Person('Adam', 'Klein');
expect(p.fullname()).toEqual('Adam Klein');
});
});
ExampleExample
It runs in the browserIt runs in the browser
+1 on credibility+1 on credibility
Let's see it in action
Debugging the testDebugging the test
chrome dev toolschrome dev tools
JasmineJasmine
What it is not:
It's not a framework for running tests
But karma is....
Is a test running framework
Makes the browser interaction seamless
Works with various testing frameworks, not just
jasmine
KarmaKarma
formerly testacular
renamed because it resembles....
Let's see it live
Run in severalRun in several
browsers at oncebrowsers at once
karma-firefox-launcher
karma-chrome-launcher
karma-phantomjs-launcher
Other cool stuffOther cool stuff
OSX reporter
Coverage
...
You might ask yourself, how the hell do IYou might ask yourself, how the hell do I
unit test this code:unit test this code:
<button onclick="addOne()">
Add one
</button>
<h1>0</h1>
function addOne() {
var count = $('h1');
var number = parseInt(count.text());
count.text(number + 1);
}
html
Javascript
Karma html2JS toKarma html2JS to
the rescuethe rescue
Load an html file in the current DOM
Test the javascript that interacts with it
Preparation
document.body.innerHTML = __html__['views/index.html'];
var button = $('button');
var h1 = $('h1');
it('should start with 0', function() {
expect(h1.text()).toEqual('0');
});
it('should add one', function() {
button.click();
expect(h1.text()).toEqual('1');
});
Test
AngularJSAngularJS
<div ng-controller="myController">
<button ng-click="addOne()">
Add one
</button>
<h1>{{count}}</h1>
</div>
function MyController($scope) {
$scope.count = 0;
$scope.addOne = function() {
$scope.count++;
}
}
AngularJSAngularJS
Controller
Handles view state
Makes data and functions accessible via $scope
Doesn't know DOM
View (template)
Data binding
Glue events
How the test will look likeHow the test will look like
it('should bind h1 to count', function() {
$scope.count = 10;
$scope.$apply();
expect(h1.text()).toEqual('10');
});
it('should call add one on button click', function() {
button.click();
expect($scope.addOne).toHaveBeenCalled();
});
What about system testsWhat about system tests
with Selenium you ask?with Selenium you ask?
Good question!!
Follow our twitter for my
coming presentation on how to
make maintainable, readable,
and fast system tests.....
Our mediaOur media
Our presentations
Cool libraries & services
Interesting blog posts
Courses & workshops
@500TechIL
500Tech on facebook
external serverexternal server
productsService = {
products: [],
create: function(product) {
var response = $.ajax(...);
if(response.success) {
this.products.push(product);
}
}
}
Easy to mockEasy to mock
serverApi
productsService
actual server
HTTP
Something like thisSomething like this
productsService = {
products: [],
create: function(product) {
var response = serverApi.createProduct(product);
if(response.success) {
this.products.push(product);
}
}
}
serverApi = {
createProduct: function(product) {
$.ajax(...);
}
}
Spy / Mock / Stub / FakeSpy / Mock / Stub / Fake
spyOnspyOn
var product = {name: 'product'};
spyOn(serverApi, 'createProduct').andReturn({success: true});
productsService.create(product);
expect(productsService.products).toEqual([product]);
Test the side effectTest the side effect
expect(serverApi.createProduct).
toHaveBeenCalledWith(product);
Credibility alert!Credibility alert!
Test might pass but code will fail
The spies are the contract with the server
Keep in TouchKeep in Touch
@500TechIL
blog.500tech.com
meetup.com/angularjs-il
meetup.com/hackademy
hackademy.co.il

Client side unit tests - using jasmine & karma

  • 1.
  • 2.
    Before we startBeforewe start Hebrew or English? Don't wait for the "Questions?" slide I'm skipping the "why test?" intro
  • 3.
  • 4.
    Adam Klein CTO of500Tech meetup.com/AngularJS-IL angular.co.il hackademy.co.il Among our clients: - Wix - Cellebrite - eToro - Autodesk - ... MeMe
  • 5.
  • 6.
    var Person =function(first, last) { this.fullname = function() { return first + ' ' + last; } } describe ('Person', function() { it('should return fullname correctly', function() { var p = new Person('Adam', 'Klein'); expect(p.fullname()).toEqual('Adam Klein'); }); }); ExampleExample
  • 7.
    It runs inthe browserIt runs in the browser +1 on credibility+1 on credibility Let's see it in action
  • 8.
    Debugging the testDebuggingthe test chrome dev toolschrome dev tools
  • 9.
    JasmineJasmine What it isnot: It's not a framework for running tests But karma is....
  • 10.
    Is a testrunning framework Makes the browser interaction seamless Works with various testing frameworks, not just jasmine KarmaKarma formerly testacular renamed because it resembles.... Let's see it live
  • 11.
    Run in severalRunin several browsers at oncebrowsers at once karma-firefox-launcher karma-chrome-launcher karma-phantomjs-launcher
  • 12.
    Other cool stuffOthercool stuff OSX reporter Coverage ...
  • 13.
    You might askyourself, how the hell do IYou might ask yourself, how the hell do I unit test this code:unit test this code: <button onclick="addOne()"> Add one </button> <h1>0</h1> function addOne() { var count = $('h1'); var number = parseInt(count.text()); count.text(number + 1); } html Javascript
  • 14.
    Karma html2JS toKarmahtml2JS to the rescuethe rescue Load an html file in the current DOM Test the javascript that interacts with it
  • 15.
    Preparation document.body.innerHTML = __html__['views/index.html']; varbutton = $('button'); var h1 = $('h1'); it('should start with 0', function() { expect(h1.text()).toEqual('0'); }); it('should add one', function() { button.click(); expect(h1.text()).toEqual('1'); }); Test
  • 16.
    AngularJSAngularJS <div ng-controller="myController"> <button ng-click="addOne()"> Addone </button> <h1>{{count}}</h1> </div> function MyController($scope) { $scope.count = 0; $scope.addOne = function() { $scope.count++; } }
  • 17.
    AngularJSAngularJS Controller Handles view state Makesdata and functions accessible via $scope Doesn't know DOM View (template) Data binding Glue events
  • 18.
    How the testwill look likeHow the test will look like it('should bind h1 to count', function() { $scope.count = 10; $scope.$apply(); expect(h1.text()).toEqual('10'); }); it('should call add one on button click', function() { button.click(); expect($scope.addOne).toHaveBeenCalled(); });
  • 19.
    What about systemtestsWhat about system tests with Selenium you ask?with Selenium you ask? Good question!! Follow our twitter for my coming presentation on how to make maintainable, readable, and fast system tests.....
  • 20.
    Our mediaOur media Ourpresentations Cool libraries & services Interesting blog posts Courses & workshops @500TechIL 500Tech on facebook
  • 21.
    external serverexternal server productsService= { products: [], create: function(product) { var response = $.ajax(...); if(response.success) { this.products.push(product); } } }
  • 22.
    Easy to mockEasyto mock serverApi productsService actual server HTTP
  • 23.
    Something like thisSomethinglike this productsService = { products: [], create: function(product) { var response = serverApi.createProduct(product); if(response.success) { this.products.push(product); } } } serverApi = { createProduct: function(product) { $.ajax(...); } }
  • 24.
    Spy / Mock/ Stub / FakeSpy / Mock / Stub / Fake spyOnspyOn var product = {name: 'product'}; spyOn(serverApi, 'createProduct').andReturn({success: true}); productsService.create(product); expect(productsService.products).toEqual([product]);
  • 25.
    Test the sideeffectTest the side effect expect(serverApi.createProduct). toHaveBeenCalledWith(product);
  • 26.
    Credibility alert!Credibility alert! Testmight pass but code will fail The spies are the contract with the server
  • 27.
    Keep in TouchKeepin Touch @500TechIL blog.500tech.com meetup.com/angularjs-il meetup.com/hackademy hackademy.co.il