fixed #215 - added a `--fail-fast` option to `casper test`
In order to terminate a test suite execution as soon as any failure is encountered.
Showing
5 changed files
with
23 additions
and
8 deletions
... | @@ -5,6 +5,7 @@ XXXX-XX-XX, v1.0.0 | ... | @@ -5,6 +5,7 @@ XXXX-XX-XX, v1.0.0 |
5 | ------------------ | 5 | ------------------ |
6 | 6 | ||
7 | - fixed [#266](https://github.com/n1k0/casperjs/issues/266) - Fix `tester` module and its self tests | 7 | - fixed [#266](https://github.com/n1k0/casperjs/issues/266) - Fix `tester` module and its self tests |
8 | - fixed [#215](https://github.com/n1k0/casperjs/issues/215) - added a `--fail-fast` option to the `casper test` command, in order to terminate a test suite execution as soon as any failure is encountered | ||
8 | - added `Tester.assertFalse()` as an alias of `Tester.assertNot()` | 9 | - added `Tester.assertFalse()` as an alias of `Tester.assertNot()` |
9 | 10 | ||
10 | 2012-10-31, v1.0.0-RC4 | 11 | 2012-10-31, v1.0.0-RC4 | ... | ... |
... | @@ -154,6 +154,9 @@ var Casper = function Casper(options) { | ... | @@ -154,6 +154,9 @@ var Casper = function Casper(options) { |
154 | this.initErrorHandler(); | 154 | this.initErrorHandler(); |
155 | 155 | ||
156 | this.on('error', function(msg, backtrace) { | 156 | this.on('error', function(msg, backtrace) { |
157 | if (msg === this.test.SKIP_MESSAGE) { | ||
158 | return this.warn(f('--fail-fast: aborted remaining tests in "%s"', this.test.currentTestFile)); | ||
159 | } | ||
157 | var c = this.getColorizer(); | 160 | var c = this.getColorizer(); |
158 | var match = /^(.*): __mod_error(.*):: (.*)/.exec(msg); | 161 | var match = /^(.*): __mod_error(.*):: (.*)/.exec(msg); |
159 | var notices = []; | 162 | var notices = []; | ... | ... |
... | @@ -55,6 +55,8 @@ var Tester = function Tester(casper, options) { | ... | @@ -55,6 +55,8 @@ var Tester = function Tester(casper, options) { |
55 | 55 | ||
56 | this.casper = casper; | 56 | this.casper = casper; |
57 | 57 | ||
58 | this.SKIP_MESSAGE = '__termination__'; | ||
59 | |||
58 | this.currentTestFile = null; | 60 | this.currentTestFile = null; |
59 | this.currentSuiteNum = 0; | 61 | this.currentSuiteNum = 0; |
60 | this.exporter = require('xunit').create(); | 62 | this.exporter = require('xunit').create(); |
... | @@ -66,6 +68,7 @@ var Tester = function Tester(casper, options) { | ... | @@ -66,6 +68,7 @@ var Tester = function Tester(casper, options) { |
66 | this.running = false; | 68 | this.running = false; |
67 | this.suites = []; | 69 | this.suites = []; |
68 | this.options = utils.mergeObjects({ | 70 | this.options = utils.mergeObjects({ |
71 | failFast: false, // terminates a suite as soon as a test fails? | ||
69 | failText: "FAIL", // text to use for a successful test | 72 | failText: "FAIL", // text to use for a successful test |
70 | passText: "PASS", // text to use for a failed test | 73 | passText: "PASS", // text to use for a failed test |
71 | pad: 80 // maximum number of chars for a result line | 74 | pad: 80 // maximum number of chars for a result line |
... | @@ -648,11 +651,13 @@ Tester.prototype.configure = function configure() { | ... | @@ -648,11 +651,13 @@ Tester.prototype.configure = function configure() { |
648 | 651 | ||
649 | // events | 652 | // events |
650 | this.casper.on('error', function(msg, backtrace) { | 653 | this.casper.on('error', function(msg, backtrace) { |
654 | if (!utils.isString(msg) && msg.indexOf(this.SKIP_MESSAGE) === -1) { | ||
651 | var line = 0; | 655 | var line = 0; |
652 | try { | 656 | try { |
653 | line = backtrace[0].line; | 657 | line = backtrace[0].line; |
654 | } catch (e) {} | 658 | } catch (e) {} |
655 | tester.uncaughtError(msg, tester.currentTestFile, line); | 659 | tester.uncaughtError(msg, tester.currentTestFile, line); |
660 | } | ||
656 | tester.done(); | 661 | tester.done(); |
657 | }); | 662 | }); |
658 | 663 | ||
... | @@ -816,21 +821,23 @@ Tester.prototype.pass = function pass(message) { | ... | @@ -816,21 +821,23 @@ Tester.prototype.pass = function pass(message) { |
816 | */ | 821 | */ |
817 | Tester.prototype.processAssertionResult = function processAssertionResult(result) { | 822 | Tester.prototype.processAssertionResult = function processAssertionResult(result) { |
818 | "use strict"; | 823 | "use strict"; |
819 | var eventName, style, status; | 824 | var eventName= 'success', |
820 | if (result.success === true) { | 825 | message = result.message || result.standard, |
821 | eventName = 'success'; | 826 | style = 'INFO', |
822 | style = 'INFO'; | ||
823 | status = this.options.passText; | 827 | status = this.options.passText; |
824 | this.testResults.passed++; | 828 | if (!result.success) { |
825 | } else { | ||
826 | eventName = 'fail'; | 829 | eventName = 'fail'; |
827 | style = 'RED_BAR'; | 830 | style = 'RED_BAR'; |
828 | status = this.options.failText; | 831 | status = this.options.failText; |
829 | this.testResults.failed++; | 832 | this.testResults.failed++; |
833 | } else { | ||
834 | this.testResults.passed++; | ||
830 | } | 835 | } |
831 | var message = result.message || result.standard; | ||
832 | this.casper.echo([this.colorize(status, style), this.formatMessage(message)].join(' ')); | 836 | this.casper.echo([this.colorize(status, style), this.formatMessage(message)].join(' ')); |
833 | this.emit(eventName, result); | 837 | this.emit(eventName, result); |
838 | if (this.options.failFast && !result.success) { | ||
839 | throw this.SKIP_MESSAGE; | ||
840 | } | ||
834 | return result; | 841 | return result; |
835 | }; | 842 | }; |
836 | 843 | ... | ... |
... | @@ -60,6 +60,7 @@ if (casper.cli.get('no-colors') === true) { | ... | @@ -60,6 +60,7 @@ if (casper.cli.get('no-colors') === true) { |
60 | casper.options.colorizerType = cls; | 60 | casper.options.colorizerType = cls; |
61 | casper.colorizer = colorizer.create(cls); | 61 | casper.colorizer = colorizer.create(cls); |
62 | } | 62 | } |
63 | casper.test.options.failFast = casper.cli.get('fail-fast') || false; | ||
63 | 64 | ||
64 | // test paths are passed as args | 65 | // test paths are passed as args |
65 | if (casper.cli.args.length) { | 66 | if (casper.cli.args.length) { |
... | @@ -97,6 +98,9 @@ this.loadIncludes.forEach(function(include){ | ... | @@ -97,6 +98,9 @@ this.loadIncludes.forEach(function(include){ |
97 | casper.test.on('tests.complete', function() { | 98 | casper.test.on('tests.complete', function() { |
98 | "use strict"; | 99 | "use strict"; |
99 | this.renderResults(true, undefined, casper.cli.get('xunit') || undefined); | 100 | this.renderResults(true, undefined, casper.cli.get('xunit') || undefined); |
101 | if (this.options.failFast && this.testResults.failures.length > 0) { | ||
102 | casper.warn('Test suite failed fast, all tests may not have been executed.'); | ||
103 | } | ||
100 | }); | 104 | }); |
101 | 105 | ||
102 | // run all the suites | 106 | // run all the suites | ... | ... |
... | @@ -27,7 +27,7 @@ var codes = [100, 101, 102, 118, 200, 201, 202, 203, 204, 205, 206, 207, 210, | ... | @@ -27,7 +27,7 @@ var codes = [100, 101, 102, 118, 200, 201, 202, 203, 204, 205, 206, 207, 210, |
27 | 414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450, | 27 | 414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450, |
28 | 500, 501, 502, 503, 504, 505, 507, 509]; | 28 | 500, 501, 502, 503, 504, 505, 507, 509]; |
29 | 29 | ||
30 | casper.thenOpen('http://google.com').each(codes, function(self, code) { | 30 | casper.each(codes, function(self, code) { |
31 | if (code === 100) { | 31 | if (code === 100) { |
32 | // HTTP 100 is CONTINUE, so don't expect a terminated response | 32 | // HTTP 100 is CONTINUE, so don't expect a terminated response |
33 | return; | 33 | return; | ... | ... |
-
Please register or sign in to post a comment