|
||||||||
PREV NEXT | FRAMES NO FRAMES |
Core elements of a test group containing individual test cases
Class Summary | |
TestGroup | Abstract base class implementing a group of test cases. Actual test group objects are derived from this base class. Each test case is created as a method of this object. |
/** * --------- * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) * |# #| * |# #| Copyright (c) 1999-2006 CardContact Software & System Consulting * |'##> <##'| Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de) * --------- * * This file is part of OpenSCDP. * * OpenSCDP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * OpenSCDP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenSCDP; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @fileoverview Core elements of a test group containing individual test cases */ /** * Create a test group object containing test cases. * * @class * <p>Abstract base class implementing a group of test cases.</p> * <p>Actual test group objects are derived from this base class.</p> * <p>Each test case is created as a method of this object.</p> * @constructor * @param {String} name the name of the test group * @param {Object} parameter the parameter object for this group of tests */ function TestGroup(name, parameter) { this.name = name; this.parameter = parameter; // this.logfile = new String("--- TestGroup " + name + "\n"); this.marker = null; // print("TestGroup constructor called"); } /** * Log a text message. * * @param {String} message the message to add to the log */ TestGroup.prototype.log = function(message) { GPSystem.trace(message); // this.logfile += message + "\n"; // print(message); } /** * Setup method called before invoking each individual test case. */ TestGroup.prototype.setUp = function() { // this.log("TestGroup.setUp() called"); } /** * Teardown method called after invocation of a test case. */ TestGroup.prototype.tearDown = function() { // this.log("TestGroup.tearDown() called"); } /** * Verify that the given assertion evaluates to true. Throw an exception if result is false. * * @param {Boolean} result true if assertion is valid * @param {String} message the message to log in case result is false */ TestGroup.prototype.assertTrue = function(result, message) { if (!result) { if (this.marker) { throw new Error("Assertion failed for [" + this.marker + "]: " + message); } else { throw new Error("Assertion failed: " + message); } } } /** * Verify that the given values are equal. Throw an exception if not. * * @param {Any} first the first argument * @param {Any} second the second argument * @param {String} message the message to log in case result is false */ TestGroup.prototype.assertEquals = function(first, second, message) { if (first != second) { if (this.marker) { throw new Error("Assertion failed for [" + this.marker + "]: " + message); } else { throw new Error("Assertion failed: " + message); } } } /** * Sets a marker used to identify a context in which an assertion failed. * * <p>A context can be a certain iteration * or group of assertions. A marker allows to further identify the area of a problem.</p> * * @param {String} marker the marker to set */ TestGroup.prototype.setMarker = function(marker) { this.marker = marker; } /** * Returns the name of test group. * * @type String * @return the name of the test group */ TestGroup.prototype.getName = function() { return this.name; } /** * Returns a list of tests as sorted array of test case names. * * @type String[] * @return the sorted array of test case names */ TestGroup.prototype.getTestCaseNames = function() { var tests = new Array(); for (f in this) { if (f.substr(0, 4) == "case") { if (this[f] instanceof Function) { tests.push(f.substr(4)); } } } tests.sort(); return tests; } /** * Returns a specific test case function. * * @param {String} name the test case name * @type Function * @return the test case method */ TestGroup.prototype.getTestCase = function(name) { return this["case" + name]; } /** * Returns a list of test procedure names referenced by a test case. * * @param {String} test case name * @type String[] * @return a list of test procedure names or undefined */ TestGroup.prototype.getUsedTestProceduresForTestCase = function(name) { if (this.constructor.prototype.usedProcedures) { return this.constructor.prototype.usedProcedures[name]; } else { return undefined; } } /** * Run a named test procedure. * * <p>This method is called by code in a test case to run a test procedure.</p> * <p>This method uses the test runner to create a new instance of the test procedure object. * All test steps in the procedure are executed and the test procedure object is returned to * the caller for further processing of test results.</p> * * @param {String} name the test procedure name * @param {Object} param the parameter object to pass to the execution of the test procedure * @type TestProcedure * @return the test procedure object */ TestGroup.prototype.runTestProcedure = function(name, param) { if (!this.testRunner) { throw new GPError("TestGroup", GPError.INVALID_USAGE, 0, "No test runner defined"); } var proc = this.testRunner.getTestProcedure(name); var test = new proc(name, this, param); test.run(); return test; } /** * Report progress of passed steps in a test procedure to the test runner. This method is used internally. * * @private * @param {String} procedure the procedure name * @param {String} step the step name */ TestGroup.prototype.reportProgress = function(procedure, step) { if (this.testRunner) { var runner = this.testRunner; var uniqueName = this.currentTestCase + "/" + procedure + "/" + step; runner.hasPassed(uniqueName, null); } } /** * Initialize a test run. This method is used internally. * @private */ TestGroup.prototype.initTestRun = function() { this.marker = null; } /** * Run a single test case. This method is called internally. Use {@link #runTestCase} for running a single test case. * * @private * @type boolean * @return true if test passed */ TestGroup.prototype.runTestCaseInternal = function(casename, runner) { var result = false; this.currentTestCase = this.name + "/" + casename; this.testRunner = runner; // this.logfile = ""; var starttime = new Date(); GPSystem.markTrace(); logentry = "+ TestCase " + this.currentTestCase + " started " + starttime; print(logentry); this.log(logentry); try { this.setUp(); var func = this.getTestCase(casename); func.call(this); this.tearDown(); var endtime = new Date(); logentry = "+ TestCase " + this.currentTestCase + " completed on " + endtime + " after " + (endtime.valueOf() - starttime.valueOf()) + " ms"; print(logentry); this.log(logentry); if (runner) { var logfile = GPSystem.copyTrace(); runner.hasPassed(this.currentTestCase, logfile); } result = true; } catch(e) { var endtime = new Date(); logentry = "+ TestCase " + this.currentTestCase + " failed on " + endtime + " after " + (endtime.valueOf() - starttime.valueOf()) + " ms"; print(logentry); this.log(logentry); logentry = " ### - " + e; print(logentry); this.log(logentry); for (j in e) { logentry = " ### " + j + " = " + e[j]; print(logentry); this.log(logentry); } if (runner) { var logfile = GPSystem.copyTrace(); runner.hasFailed(this.currentTestCase, logfile); } } return result; } /** * Runs all tests in a test group. * * <p>This method can be used to run a test group without a test runner. In that case leave the runner * argument empty or null.</p> * * @param {TestRunner} runner the test runner to report progress or undefined or null */ TestGroup.prototype.run = function(runner) { this.initTestRun(); var tests = this.getTestCaseNames(); var startgroup = new Date(); var logentry = "TestGroup " + this.name + " started " + startgroup; var failures = 0; print(logentry); this.log(logentry); for (var i = 0; i < tests.length; i++) { var uniqueName = this.name + "/" + tests[i]; if (runner) { if (!runner.isEnabled(uniqueName)) continue; } if (!this.runTestCaseInternal(tests[i], runner)) { failures++; } } var endgroup = new Date(); logentry = "TestGroup " + this.name + " completed on " + endgroup + " with " + failures + " failed tests"; print(logentry); this.log(logentry); } /** * Run a single test in a test group, optionally using a test runner. * * @param {String} casename the name of the test case * @param {TestRunner} the test runner object or undefined or null */ TestGroup.prototype.runTestCase = function(casename, runner) { this.initTestRun(); this.runTestCaseInternal(casename, runner); }
|
||||||||
PREV NEXT | FRAMES NO FRAMES |