Given-when-then testing
Proof of concept. Async sequential running of actions will allow for tests that interact with page loading, form submissions and maybe even ajax.
by andrewdavey
HTML
<input type="text" id="name"/><button id="go">Test</button>
<p id="message"></p>
JavaScript
// ******** CODE UNDER TEST ***********
$("#go").click(function() {
$("#message").text("Hello, " + $("#name").val());
});
// ******** TEST CODE *************
initTestRunner();
// A passing test
given(
loadPage("/")
).
when(
type("#name", "Andrew"),
click("#go")
).
then(
$("#message").textShouldBe("Hello, Andrew")
);
// A failing test
given(
loadPage("/")
).
when(
type("#name", ""),
click("#go")
).
then(
$("#message").textShouldBe("Please enter your name.")
);
function initTestRunner() {
$.fn.textShouldBe = function(value) {
return function() {
if (this.text() !== value) {
throw new Error("Text should be '" + value + "' but was '" + this.text() + "'");
}
}.bind(this);
};
var actions = buildActions({
click: function(id) {
$(id).click();
},
type: function(id, text) {
$(id).val(text);
},
loadPage: async(function(url) {
var done = this.done;
// FAKE CODE!
// Real code will set and iframe's src to trigger page load
// and call done once the window load event fires.
setTimeout(function() {
done();
}, 100);
}),
pause: async(function(ms) {
setTimeout(this.done, ms);
}),
message: function(text) {
$("#message").text(text);
}
});
$.extend(window, actions);
window.given = (function() {
return function () {
var actions = copy(arguments);
return {
when: function() {
return when.apply({
actions: actions
}, arguments);
}
};
}
function when() {
var actions = this.actions.concat(copy(arguments));
return {
then: function() {
...