Permalink
Browse files

Update default test runner. Change output behavior some

  • Loading branch information...
1 parent a804673 commit c1c0ac594fbdf2712e05962d497cef5039a4c50c Benjamin Thomas committed Aug 10, 2010
Showing with 159 additions and 50 deletions.
  1. +9 −10 README.md
  2. +3 −4 examples/readme.js
  3. +146 −35 lib/runners.js
  4. +1 −1 package.json
View
@@ -88,14 +88,13 @@ tests. A test suite is just an object with tests:
If you want to be explicit about the number of assertions run in a given test,
you can set `numAssertions` on the test. This can be very helpful in
-asynchronous tests where you want to be sure all callbacks get fired.
+asynchronous tests where you want to be sure all callbacks get fired:
- suite['test assertions expected (fails)'] = function(test) {
- test.numAssertions = 3;
+ suite['test assertions expected'] = function(test) {
+ test.numAssertions = 1;
test.ok(true);
test.finish();
- // this test will fail!
}
If you need to make assertions about what kind of errors are thrown, you can
@@ -122,7 +121,7 @@ simple as writing a wrapper function which takes a test and returns a new test:
function setup(testFunc) {
return function newTestFunc(test) {
- var extra1 = 1;
+ var extra1 = 1
var extra2 = 2;
testFunc(test, extra1, extra2);
}
@@ -139,7 +138,7 @@ in a suite:
require('async_testing').wrapTests(suite, setup);
-See `test/test-wrap_tests` for more details.
+See `test/test-wrap_tests.js` for more details examples.
Additionally, the you can look at any of the files in the `test` directory for
examples.
@@ -149,9 +148,9 @@ Running test suites
The easiest way to run a suite is with the `run` method:
- require('async-testing').run(suite);
+ require('async_testing').run(suite);
-The `run` command can take a test suite, a file name, a directory name (it
+The `run` method can take a test suite, a file name, a directory name (it
recursively searches the directory for javascript files that start with `test-`)
or an array of any of those three options.
@@ -174,7 +173,7 @@ were in a file called `mySuite.js`):
node mySuite.js
-Additionally, the `run` command can be passed an array of command line arguments
+Additionally, the `run` method can be passed an array of command line arguments
that alter how it works:
exports['first test'] = function(test) { ... };
@@ -189,7 +188,7 @@ Now, you can tell the runner to run the tests in parallel:
node mySuite.js --parallel
-Or only run a specific test:
+Or to only run a specific test:
node mySuite.js --test-name "first test"
View
@@ -7,20 +7,19 @@ exports['asynchronousTest'] = function(test) {
test.ok(true);
// finish the test
test.finish();
- },50);
+ },500);
};
exports['synchronousTest'] = function(test) {
test.ok(true);
test.finish();
};
-exports['test assertions expected (fails)'] = function(test) {
- test.numAssertions = 3;
+exports['test assertions expected'] = function(test) {
+ test.numAssertions = 1;
test.ok(true);
test.finish();
- // this test will fail!
}
exports['test catch sync error'] = function(test) {
View
@@ -21,7 +21,7 @@ exports.def = function(list, options, args, callback) {
, bold = function(str){return "\033[1m" + str + "\033[22m"}
;
- // make sure options exist
+ // make sure options exists
if (typeof options == 'undefined' || options == null) {
options = {};
}
@@ -37,6 +37,11 @@ exports.def = function(list, options, args, callback) {
}
}
+ // create help message. It uses the supplied options object to load the
+ // defaults, so we have to make the help message here before we modify the
+ // options object
+ var helpMessage = createHelpMessage(options);
+
// list needs to be an array
if (!list) {
list = [];
@@ -48,7 +53,7 @@ exports.def = function(list, options, args, callback) {
for(var i = 2; i < args.length; i++) {
switch(args[i]) {
- case "--log":
+ case "--log-level":
case "-l":
options.verbosity = args[i+1];
i++;
@@ -58,7 +63,7 @@ exports.def = function(list, options, args, callback) {
options.parallel = true;
break;
case "--consecutive":
- case "-c":
+ case "-P":
options.parallel = false;
break;
case "--test-name":
@@ -67,14 +72,30 @@ exports.def = function(list, options, args, callback) {
i++;
break;
case "--suite-name":
- case "-n":
+ case "-s":
options.suiteName = args[i+1];
i++;
break;
case "--help":
case "-h":
options.help = true;
break;
+ case "--no-color":
+ case "-w":
+ options.noColor = true;
+ break;
+ case "--color":
+ case "-W":
+ options.noColor = false;
+ break;
+ case "--successes":
+ case "-x":
+ options.printSuccesses = true;
+ break;
+ case "--no-successes":
+ case "-X":
+ options.printSuccesses = false;
+ break;
default:
list.push(args[i]);
}
@@ -95,14 +116,8 @@ exports.def = function(list, options, args, callback) {
}
if (options.help) {
- sys.puts('Flags:');
- sys.puts(' --log, -l: the log level: 0 => succinct, 1 => default, 2 => full stack traces');
- sys.puts(' --test-name, -t: to search for a specific test');
- sys.puts(' --suite-name, -s: to search for a specific suite ');
- sys.puts(' --parallel, -p: run the suites in parallel mode');
- sys.puts(' --consecutive, -c: don\'t run the suites in parallel mode');
- sys.puts(' --help, -h: this help message');
- process.exit();
+ sys.puts(helpMessage);
+ return;
}
if (typeof options.verbosity == 'undefined') {
@@ -112,25 +127,26 @@ exports.def = function(list, options, args, callback) {
options.parallel = false;
}
- /* Available options (aside from those available to runSuites in async_testing.js
- *
- * verbosity: 0, 1, or 2
- * 0 Not much
- * 2 All
- * 1 Somewhere in the middle
- */
+ if (options.noColor) {
+ red = green = yellow = function(str) { return str; };
+ }
+
+ // some state
+ var currentSuite = null
+ , printedCurrentSuite = null
+ , numSuites = null
+ ;
opts =
{ parallel: options.parallel
, testName: options.testName
, suiteName: options.suiteName
+ , onStart: function(num) {
+ numSuites = num;
+ }
, onSuiteStart: function(name) {
- if (name) {
- sys.puts(bold(name));
- }
- else {
- sys.puts('');
- }
+ currentSuite = name;
+ printedCurrentSuite = false;
}
, onSuiteDone: function(suiteResults) {
var tests = suiteResults.tests;
@@ -139,8 +155,15 @@ exports.def = function(list, options, args, callback) {
return;
}
- sys.puts('');
if(options.verbosity > 0) {
+ if (numSuites > 1 || suiteResults.numErrors > 0 || suiteResults.numFailures > 0) {
+ if (!printedCurrentSuite) {
+ sys.puts(bold(currentSuite));
+ }
+ if (options.printSuccesses || suiteResults.numErrors > 0 || suiteResults.numFailures > 0) {
+ sys.puts('');
+ }
+ }
for(var i = 0; i < tests.length; i++) {
var r = tests[i];
if (r.status == 'failure') {
@@ -219,21 +242,50 @@ exports.def = function(list, options, args, callback) {
if (suiteResults.numFailures > 0) {
sys.print(' FAILURES: '+suiteResults.numFailures+'/'+total+' tests failed.');
}
+ if (suiteResults.numFailures > 0 && suiteResults.numErrors > 0) {
+ sys.puts('');
+ sys.print(' ');
+ }
if (suiteResults.numErrors > 0) {
sys.print(' ERRORS: '+suiteResults.numErrors+'/'+total+' tests errored.');
}
}
else {
- sys.print(' '+green('OK: ')+total+' test'+(total == 1 ? '' : 's')+'.');
+ if (options.verbosity > 0 && numSuites > 1) {
+ sys.print(' '+green('OK: ')+total+' test'+(total == 1 ? '' : 's')+'.');
+ }
}
+ if (suiteResults.numFailures > 0 && suiteResults.numErrors > 0) {
+ sys.puts('');
+ sys.print(' ');
+ }
+ }
+
+ if (options.verbosity == 0) {
+ if (options.printSuccesses || suiteResults.numErrors > 0 || suiteResults.numFailures >0) {
+ sys.puts('');
+ }
+ }
+ else if(numSuites > 1) {
sys.puts(' '+(suiteResults.duration/1000)+' seconds.');
sys.puts('');
}
}
, onTestDone: function(result) {
+ if (!printedCurrentSuite) {
+ if (options.printSuccesses || result.status != 'success') {
+ if (currentSuite) {
+ sys.puts(bold(currentSuite));
+ }
+ printedCurrentSuite = true;
+ }
+ }
+
if (result.status == 'success') {
- sys.puts('' + result.name);
+ if (options.printSuccesses) {
+ sys.puts('' + result.name);
+ }
}
else if (result.status == 'failure') {
sys.puts(red('' + result.name));
@@ -266,15 +318,16 @@ exports.def = function(list, options, args, callback) {
}
}
- if (total > 1) {
- if(successes != total) {
- sys.print(bold(red('PROBLEMS: ')+(total-successes)+'/'+total+' suites had problems.'));
- }
- else {
- sys.print(bold(green('SUCCESS: ')+total+'/'+total+' suites passed successfully.'));
+ if (successes != total) {
+ sys.print(bold(red('PROBLEMS: ')+(total-successes)+'/'+total+' suites had problems.'));
+ }
+ else {
+ sys.print(bold(green('SUCCESS:')));
+ if (total > 1) {
+ sys.print(bold(' '+total+'/'+total+' suites passed successfully.'));
}
- sys.puts(bold(' ' + tests+(tests == 1 ? ' test' : ' total tests')+'. '+(duration/1000)+' seconds.'));
}
+ sys.puts(bold(' ' + tests+(tests == 1 ? ' test' : ' total tests')+'. '+(duration/1000)+' seconds.'));
if (callback) {
callback(allResults, duration);
@@ -296,3 +349,61 @@ exports.def = function(list, options, args, callback) {
testing.runSuites(list, opts);
}
+
+function createHelpMessage(options) {
+ var helpMessage =
+ 'Async-testing'
+ + '\n-------------'
+ + '\n'
+ + '\nOptions:'
+ + '\n --test-name, -t <name>: only run tests with the specified name'
+ + '\n'
+ + '\n --suite-name, -s <name>: only run suites with the specified name'
+ + '\n'
+ + '\n --consecutive, -R: don\'t run the suites in parallel mode'
+ ;
+ if (!options.parallel) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage += '\n --parallel, -r: run the suites in parallel mode';
+ if (options.parallel) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage +=
+ '\n'
+ + '\nOutput:'
+ + '\n --log-level, -l <level>: 0 => succinct, 1 => default, 2 => full stack traces'
+ + '\n'
+ + '\n --no-successes, -X: supress output information about successes'
+ ;
+ if (!options.printSuccesses) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage += '\n --successes, -x: output information about successes as they happen';
+ if (options.printSuccesses) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage += '\n\n --color, -W: use colored output';
+ if (!options.noColor) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage += '\n --no-color, -w: don\'t use colored output';
+ if (options.parallel) {
+ helpMessage += ' (default)';
+ }
+
+ helpMessage +=
+ '\n'
+ + '\nHelp:'
+ + '\n --help, -h: output this help message'
+ + '\n'
+ + '\nAny additional arguments are file names containing test suites that should be ran'
+ ;
+
+ return helpMessage;
+}
View
@@ -1,6 +1,6 @@
{ "name": "async_testing"
, "description": "A simple Node testing library."
-, "version": "0.2.0"
+, "version": "0.2.1"
, "author": "Benjamin Thomas"
, "main": "./index"
, "directories": {"lib":"./lib"}

0 comments on commit c1c0ac5

Please sign in to comment.