Skip to content

Instantly share code, notes, and snippets.

@mardambey
Created April 14, 2011 03:56
Show Gist options
  • Save mardambey/918862 to your computer and use it in GitHub Desktop.
Save mardambey/918862 to your computer and use it in GitHub Desktop.
Simple test runner in JS.
<html>
<head>
<title>Mate1 Test Runner</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript">
// A test is the base class for all tests
// that will be run by the test runner.
Test = function() {
// Abstract function that needs to be
// implemented by the child to run
// test.
this.run = function() {}
// The state of a test is any of:
// NOT_STARTED - test has not started running
// RUNNING - test is currently running
// FINISHED - test has finished running
this.NOT_STARTED = 0;
this.RUNNING = 1;
this.FINISHED = 2;
// This holds the current state of the test
// and defaults to NOT_STARTED
this.state = this.NOT_STARTED;
// Holds random data that can be passed to
// the test at startup and can be handed off
// to another test if ran as part of a series
// of tests.
this.data = {};
// When a test is finished it can have one
// of the following results:
// PASS - everything passed
// FAIL - something failed
this.PASS = 1;
this.FAIL = 0;
// Can be either PASS or FAIL, must be
// set to FAIL before run() ends or the
// state is set to FINISHED if the test
// failed.
this.result = this.PASS;
// A message that the test can relay back
// to the test runner which can be displayed
// to the user.
this.message = "";
}
// Holds a series of tests and runs them
// serially optionally passing a piece of
// data from one test to the other.
ChainedTestRunner = function(tests, data) {
// List of tests to run
this.tests = tests;
// Data object to pass around tests, optional
this.data = data;
// Callback that can be implemented so that the
// user of the test runner can run their own code
// on test completion
this.onFinished = function(test) {}
// Check if tests are complete
this.checkTestCompletion = function() {
var finished = [];
for (var test in this.tests) {
if (this.tests[test].state === this.tests[test].FINISHED) {
this.data = this.tests[test].data;
finished.push(test);
}
}
// announce and delete the finished tests
for (var pos in finished) {
this.finished(this.tests[pos]);
this.tests.splice(finished[pos], 1);
}
var self = this;
if (this.tests.length > 0) {
for (var test in this.tests) {
if(this.tests[test].STATE === this.RUNNING) break;
else {
this.tests[test].data = this.data;
this.tests[test].run();
break;
}
}
setTimeout(function() { self.checkTestCompletion(); }, 100);
}
}
// Finishes a test and calls the user
// specified onFinished callback.
this.finished = function(test) {
this.onFinished(test);
}
// run tests and check for completion
this.runTests = function() {
for (var test in this.tests) {
this.tests[test].run();
break;
}
this.checkTestCompletion();
}
}
// The test runner runs a series of tests and
// reports the results back to the user.
// Accepts an array of Test objects.
ParallelTestRunner = function(tests) {
// List of tests to run
this.tests = tests;
// Callback that can be implemented so that the
// user of the test runner can run their own code
// on test completion
this.onFinished = function(test) {}
// Check if tests are complete
this.checkTestCompletion = function() {
var finished = [];
for (var test in this.tests) {
if (this.tests[test].state === this.tests[test].FINISHED) {
finished.push(test);
}
}
// announce and delete the finished tests
for (var pos in finished) {
this.finished(this.tests[pos]);
this.tests.splice(finished[pos], 1);
}
self = this;
if (this.tests.length > 0) {
setTimeout(function() { self.checkTestCompletion(); }, 100);
}
}
// Finishes a test and calls the user
// specified onFinished callback.
this.finished = function(test) {
this.onFinished(test);
}
// run tests and check for completion
this.runTests = function() {
for (var test in this.tests) {
this.tests[test].run();
}
this.checkTestCompletion();
}
}
// Sample test, instantiate
var LoginTest = new Test();
// Define the test. This is a fake
// test that does an ajax request
// then sleeps for a bit before completing.
LoginTest.run = function() {
$.ajax({
url: "login.html",
success: function(data) {
LoginTest.data.sessionId = "RE34R534TG3Y77N";
LoginTest.message = "LoginTest done";
LoginTest.result = LoginTest.PASS;
LoginTest.state = LoginTest.FINISHED;
}
});
}
// Sample test, instantiate
var AnotherTest = new Test();
// Define the test. This is a fake
// test that does an ajax request
// then sleeps for a bit before completing.
AnotherTest.run = function() {
$.ajax({
url: "login.html?sessionId=" + AnotherTest.data.sessionId,
success: function(data) {
AnotherTest.message = "AnotherTest done";
AnotherTest.result = AnotherTest.PASS;
AnotherTest.state = AnotherTest.FINISHED;
}
});
}
var tests = [LoginTest, AnotherTest];
var testRunner = new ChainedTestRunner(tests, {});
testRunner.onFinished = function(test) {
$("#results").append("<li>" + test.message + ": <strong>" + (test.result === test.PASS ? "PASS" : "FAIL") + "</strong></li>");
}
testRunner.runTests();
</script>
</head>
<body>
<ul id="results"></ul>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment