Skip to content

Commit

Permalink
Add failure reporting (close #20)
Browse files Browse the repository at this point in the history
- Exception messages and stack traces are now reported by the progress formatter
- Failed scenario names and line numbers are also printed out
  • Loading branch information
jbpros committed Aug 1, 2011
1 parent 172dd29 commit 6e55cdc
Show file tree
Hide file tree
Showing 23 changed files with 435 additions and 252 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
source :rubygems
gem "aruba", "0.4.3"
gem "aruba", "0.4.5"
16 changes: 8 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
GEM
remote: http://rubygems.org/
specs:
aruba (0.4.3)
aruba (0.4.5)
bcat (>= 0.6.1)
childprocess (>= 0.1.9)
cucumber (>= 0.10.7)
Expand All @@ -10,20 +10,20 @@ GEM
bcat (0.6.1)
rack (~> 1.0)
builder (3.0.0)
childprocess (0.1.9)
childprocess (0.2.0)
ffi (~> 1.0.6)
cucumber (1.0.0)
cucumber (1.0.2)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.4.1)
gherkin (~> 2.4.5)
json (>= 1.4.6)
term-ansicolor (>= 1.0.5)
diff-lcs (1.1.2)
ffi (1.0.9)
gherkin (2.4.1)
gherkin (2.4.5)
json (>= 1.4.6)
json (1.5.3)
rack (1.3.0)
rack (1.3.2)
rdiscount (1.6.8)
rspec (2.6.0)
rspec-core (~> 2.6.0)
Expand All @@ -33,10 +33,10 @@ GEM
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
term-ansicolor (1.0.5)
term-ansicolor (1.0.6)

PLATFORMS
ruby

DEPENDENCIES
aruba (= 0.4.3)
aruba (= 0.4.5)
2 changes: 1 addition & 1 deletion cucumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var featurePath = process.ARGV[2];
var supportCodePath = process.ARGV[3] ? process.cwd() + '/' + process.ARGV[3] : './features/step_definitions/cucumber_steps';

if (typeof(featurePath) == 'undefined') {
throw("Please give me a feature, try something like `" + process.ARGV[1] + " features/cucumber-features/core.feature`.");
throw(new Error("Please give me a feature, try something like `" + process.ARGV[1] + " features/cucumber-features/core.feature`."));
}

var supportCode = require(supportCodePath);
Expand Down
2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ <h2>Step definitions</h2>

Then(/^the variable should contain (\d+)$/, function(number, callback) {
if (variable != parseInt(number))
throw('Variable should contain '+number+' but it contains '+variable+'.');
throw(new Error('Variable should contain '+number+' but it contains '+variable+'.'));
callback();
});</textarea>

Expand Down
2 changes: 1 addition & 1 deletion features/cucumber-features
133 changes: 0 additions & 133 deletions features/legacy/progress_formatter.feature

This file was deleted.

6 changes: 3 additions & 3 deletions features/step_definitions/calculator_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,21 @@ var calculatorSteps = function(Calculator) {
Then(/^the calculator returns PI$/, function(callback) {
var value = calc.value();
if (!isNumberWithinRangeOfValue(value, 0.00001, Math.PI))
throw("Expected " + Math.PI + " (PI), got " + value);
throw(new Error("Expected " + Math.PI + " (PI), got " + value));
callback();
});

Then(/^the calculator returns "([^"]*)"$/, function(expected_number, callback) {
var value = calc.value();
if (!isNumberWithinRangeOfValue(value, 0.00001, parseFloat(expected_number)))
throw("Expected calculator to return a value within 0.00001 of " + expected_number + ", got " + value);
throw(new Error("Expected calculator to return a value within 0.00001 of " + expected_number + ", got " + value));
callback();
});

Then(/^the calculator does not return ([\d\.]+)$/, function(unexpected_number, callback) {
var value = calc.value();
if (isNumberWithinRangeOfValue(value, 0.00001, parseFloat(unexpected_number)))
throw("Expected calculator to not return a value within 0.00001 of " + unexpected_number + ", got " + value);
throw(new Error("Expected calculator to not return a value within 0.00001 of " + unexpected_number + ", got " + value));
callback();
});
};
Expand Down
18 changes: 15 additions & 3 deletions features/step_definitions/cucumber_js_mappings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,19 @@ def cucumber_bin
end

def write_passing_mapping(step_name)
append_step_definition(step_name, "// no-op, pass gently")
append_step_definition(step_name, "// no-op, pass gently\ncallback();")
end

def write_pending_mapping(step_name)
append_step_definition(step_name, "callback.pending();")
end

def write_failing_mapping(step_name)
append_step_definition(step_name, "throw('Boom!');")
write_failing_mapping_with_message(step_name, "I was supposed to fail.")
end

def write_failing_mapping_with_message(step_name, message)
append_step_definition(step_name, "throw(new Error('#{message}'));")
end

def write_calculator_code
Expand Down Expand Up @@ -72,6 +76,15 @@ def assert_undefined_scenario
assert_success true
end

def assert_scenario_reported_as_failing(scenario_name)
assert_partial_output("# Scenario: #{scenario_name}", all_output)
assert_success false
end

def assert_scenario_not_reported_as_failing(scenario_name)
assert_no_partial_output("# Scenario: #{scenario_name}", all_output)
end

def failed_output
"failed"
end
Expand All @@ -84,7 +97,6 @@ def append_step_definition(step_name, code)
Given(/#{step_name}/, function(callback) {
fs.writeFileSync("#{step_file(step_name)}", "");
#{indented_code}
callback();
});
EOF
end
Expand Down
52 changes: 45 additions & 7 deletions features/step_definitions/cucumber_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@ var cucumberSteps = function() {
prepare();
stepDefinitions += "Given(/^" + stepName + "$/, function(callback) {\
touchStep(\"" + stepName + "\");\
throw('I was supposed to fail.');\
throw(new Error('I was supposed to fail.'));\
});\n";
callback();
});

Given(/^the step "([^"]*)" has a mapping failing with the message "([^"]*)"$/, function(stepName, message, callback) {
prepare();
stepDefinitions += "Given(/^" + stepName + "$/, function(callback) {\
touchStep(\"" + stepName + "\");\
throw(new Error('" + message + "'));\
});\n";
callback();
});
Expand Down Expand Up @@ -63,7 +72,7 @@ var cucumberSteps = function() {

Then(/^the scenario passes$/, function(callback) {
if (!lastRunSucceeded)
throw("Expected the scenario to pass but it failed");
throw(new Error("Expected the scenario to pass but it failed"));
callback();
});

Expand All @@ -82,6 +91,16 @@ var cucumberSteps = function() {
callback();
});

Then(/^the scenario called "([^"]*)" is reported as failing$/, function(scenarioName, callback) {
assertScenarioReportedAsFailing(scenarioName);
callback();
});

Then(/^the scenario called "([^"]*)" is not reported as failing$/, function(scenarioName, callback) {
assertScenarioNotReportedAsFailing(scenarioName);
callback();
});

Then(/^the step "([^"]*)" is skipped$/, function(stepName, callback) {
assertSkippedStep(stepName);
callback();
Expand All @@ -92,6 +111,11 @@ var cucumberSteps = function() {
callback();
});

Then(/^the failure message "([^"]*)" is output$/, function(message, callback) {
assertFailureMessage(message);
callback();
});

function prepare() {
if (shouldPrepare) {
shouldPrepare = false;
Expand Down Expand Up @@ -150,29 +174,43 @@ var cucumberSteps = function() {
assertSuccess();
}

function assertScenarioReportedAsFailing(scenarioName) {
assertPartialOutput("# Scenario: " + scenarioName, lastRunOutput);
assertFailure();
}

function assertScenarioNotReportedAsFailing(scenarioName) {
assertNoPartialOutput("# Scenario: " + scenarioName, lastRunOutput);
}

function assertSkippedStep(stepName) {
if (isStepTouched(stepName))
throw("Expected step \"" + stepName + "\" to have been skipped.");
throw(new Error("Expected step \"" + stepName + "\" to have been skipped."));
}

function assertSuccess() {
if (!lastRunSucceeded)
throw("Expected Cucumber to succeed but it failed.");
throw(new Error("Expected Cucumber to succeed but it failed."));
}

function assertFailure() {
if (lastRunSucceeded)
throw("Expected Cucumber to fail but it succeeded.");
throw(new Error("Expected Cucumber to fail but it succeeded."));
}

function assertFailureMessage(message) {
assertPartialOutput(message, lastRunOutput);
assertFailure();
}

function assertPartialOutput(expected, actual) {
if (actual.indexOf(expected) < 0)
throw("Expected:\n\"" + actual + "\"\nto match:\n\"" + expected + "\"");
throw(new Error("Expected:\n\"" + actual + "\"\nto match:\n\"" + expected + "\""));
}

function assertNoPartialOutput(expected, actual) {
if (actual.indexOf(expected) >= 0)
throw("Expected:\n\"" + actual + "\"\nnot to match:\n\"" + expected + "\"");
throw(new Error("Expected:\n\"" + actual + "\"\nnot to match:\n\"" + expected + "\""));
}
};
module.exports = cucumberSteps;
Loading

0 comments on commit 6e55cdc

Please sign in to comment.