James Sherry PRO
Web Development Tutor and Co-Founder of { The Jump } Digital School
Brief: Show the customers broadband packages
// JSON response from the server
[{
"id": 827349,
"name": {
"first": "John",
"last": "Smith"
},
"packages": ["sports", "nature", "travel"]
}, {
...
}]
<div>
<h1>My Broadband Packages</h1>
<ul>
<li>Nature</li>
<li>Travel</li>
<li>Sports</li>
</ul>
</div>
A few weeks later and the team want to build a new page showing a customer's packages; the prices of those packages, and; upgrade options
// JSON response from the server
[{
"id": 827349,
"name": {
"first": "John",
"last": "Smith"
},
"packages": [{
"name": "sports",
"cost": 50,
"upgradeOptions": ["sportsPlus"]
}, {
...
}]
}, {
...
}]
<div>
<h1>My Broadband Packages</h1>
<ul>
<li>Sports
<span>Cost: £50</span>
<a href="/upgrade?options="sportsplus">
See upgrade options</a>
</li>
etc...
</ul>
</div>
<div>
<h1>My Broadband Packages</h1>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
Uncaught TypeError: package.toLowerCase
is not a function(…)
In our case, the API was upgraded to meet the needs of another page. This changed the nature of the data we received and hence broke our program.
They can't be expected to check every page manually - some sites can have hundreds of pages potentially.
How do we solve this problem??
Let's say we're building a game of tictactoe: What would I need?
This page has your working product on. It has your styles, your vendor scripts and your main script file.
It outputs your finished product.
This page has the same, but in addition it has the jasmine unit testing framework and your specs.
It outputs the results of your unit tests.
(function(){
"use strict";
//Application code goes here
}());
(function() {
"use strict";
describe("TicTacToe", function() {
//test code goes here
});
}());
(function() {
"use strict";
describe("TicTacToe", function() {
it("It should be loaded into the browser and be accessible", function() {
expect(window.TicTacToe).toBeDefined();
});
});
}());
(function() {
window.TicTacToe = function(sideLength, playerNames, options){
};
}());
(function() {
"use strict";
describe("TicTacToe", function() {
var game, board, squares, sideLength, playerNames;
beforeEach(function() {
sideLength = 3;
});
afterEach(function() {
sideLength = null;
});
it("It should be loaded into the browser and be accessible", function() {
expect(window.TicTacToe).toBeDefined();
});
describe('The Board', function() {
it("It should create a board", function() {
expect(board).not.toBeUndefined();
});
});
});
}());
(function() {
describe("TicTacToe", function() {
var game, board;
beforeEach(function() {
game = new TicTacToe();
game.init();
board = document.getElementsByClassName('board')[0];
});
it("It should be loaded into the browser and be accessible", function() {
expect(window.TicTacToe).toBeDefined();
});
describe("The Board", function() {
it("It should create a board", function() {
expect(board).not.toBeUndefined();
});
});
});
}());
(again the test must fail first)
(function() {
"use strict";
window.TicTacToe = window.TicTacToe ||
function(sideLength, playerNames, options){
//THE BOARD
var boardSize, players = [];
sideLength = sideLength || 3;
boardSize = sideLength * sideLength;
function createBoard(){
//Create the board
var board, squares;
board = document.createElement("DIV");
board.className = "board row";
//etc.
};
//etc.
}());
(function() {
"use strict";
window.TicTacToe = window.TicTacToe ||
function(sideLength, playerNames, options){
function createBoard(){
//Create the board
var board, squares;
board = document.createElement("DIV");
board.className = "board row";
document.body.appendChild(board);
(function mySpecialContractorFunction(){
window.TicTacToe = "I\'m well good, me!!!";
}());
};
}());
Full documentation is available at:
http://jasmine.github.io/edge/introduction.html
describe("TicTacToe", function() {
it("It should be loaded into the browser and be accessible", function() {
expect(window.TicTacToe).toBeDefined();
expect(window.hamster).not.toBe(7);
expect(message).toMatch(/bar/);
expect(foo).toBeTruthy();
});
});
(function() {
"use strict";
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("tracks that the spy was called", function() {
expect(foo.setBar).toHaveBeenCalled();
});
it("tracks all the arguments of its calls", function() {
expect(foo.setBar).toHaveBeenCalledWith(123);
expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
});
});
}());
Jest, Mocha, Sinon, Chai, QUnit, JUnit, Buster.js, etc. etc.
I personally use the first 4, but Buster is good and QUnit is an old favourite.
Most CI services will run your tests for you:
Example services include:
By James Sherry