Permalink
Browse files

Merge branch 'feature/cucumber-integration'

* feature/cucumber-integration:
  The remainder of the specs, I think.  Not test-driving is painful...
  Big pile o' passing specs. I suppose it's testing that it interacts correctly with the underlying API...
  Spec out the CucumberFailure.
  Nuke the CucumberDoc version for now.
  Inherit directly from Ast::Visitor.
  Accept (and demonstrate) that Cucumber doesn't differentiate between failures and errors.
  Implement catching and reporting of errors.
  If there are 0 errors, don't check for errors elements.
  Reimplement the visitor.  I must have been smoking something on Friday.
  Pending steps should not be reported as errors.
  Start of an implementation of the visitor.
  Expect a slightly different filename.
  We have to require the cucumber loader slightly differently otherwise it doesn't autoload step definitions.
  Acceptance tests for cucumber integration.
  Add in a place to stick specs for the Cucumber integration.
  Add in some tests for the Cucumber setup rake task.
  Infrastructure for Cucumber integration.
  • Loading branch information...
mathie committed May 4, 2009
2 parents 509a989 + c5b9fdc commit 71d6ae240cf18eeb6fd9dcbbaf248d337de49665
View
@@ -63,6 +63,7 @@ task :generate_output do
begin
`ruby -Ilib acceptance/test_unit_example_test.rb` rescue nil
`ruby -Ilib -S spec --require ci/reporter/rake/rspec_loader --format CI::Reporter::RSpec acceptance/rspec_example_spec.rb` rescue nil
+ `ruby -Ilib -rci/reporter/rake/cucumber_loader -S cucumber --format CI::Reporter::Cucumber acceptance/cucumber` rescue nil
ensure
ENV.delete 'CI_REPORTS'
end
@@ -0,0 +1,19 @@
+Feature: Example feature
+ As a conscientious developer who writes features
+ I want to be able to see my features passing on the CI Server
+ So that I can bask in the glow of a green bar
+
+ Scenario: Conscientious developer
+ Given that I am a conscientious developer
+ And I write cucumber features
+ Then I should see a green bar
+
+ Scenario: Lazy hacker
+ Given that I am a lazy hacker
+ And I don't bother writing cucumber features
+ Then I should be fired
+
+ Scenario: Bad coder
+ Given that I can't code for peanuts
+ And I write step definitions that throw exceptions
+ Then I shouldn't be allowed out in public
@@ -0,0 +1,30 @@
+require 'spec/expectations'
+
+Given /^that I am a conscientious developer$/ do
+end
+
+Given /^I write cucumber features$/ do
+end
+
+Then /^I should see a green bar$/ do
+end
+
+Given /^that I am a lazy hacker$/ do
+end
+
+Given /^I don't bother writing cucumber features$/ do
+ false.should be_true
+end
+
+Then /^I should be fired$/ do
+end
+
+Given /^that I can't code for peanuts$/ do
+end
+
+Given /^I write step definitions that throw exceptions$/ do
+ raise RuntimeError, "User error!"
+end
+
+Then /^I shouldn't be allowed out in public$/ do
+end
@@ -62,3 +62,51 @@
doc.root.elements.to_a("/testsuite/testcase").size.should == 1
end
end
+
+describe "Cucumber acceptance" do
+ it "should generate three XML files" do
+ File.exist?(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Conscientious-developer.xml')).should == true
+ File.exist?(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Lazy-hacker.xml')).should == true
+ File.exist?(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Bad-coder.xml')).should == true
+
+ Dir["#{REPORTS_DIR}/CUCUMBER-*.xml"].length.should == 3
+ end
+
+ it "should have three tests and no failures for the conscientious developer" do
+ doc = File.open(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Conscientious-developer.xml')) do |f|
+ REXML::Document.new(f)
+ end
+ doc.root.attributes["errors"].should == "0"
+ doc.root.attributes["failures"].should == "0"
+ doc.root.attributes["tests"].should == "3"
+ doc.root.elements.to_a("/testsuite/testcase").size.should == 3
+ end
+
+ it "should have three tests and one failure for the lazy hacker" do
+ doc = File.open(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Lazy-hacker.xml')) do |f|
+ REXML::Document.new(f)
+ end
+ doc.root.attributes["errors"].should == "0"
+ doc.root.attributes["failures"].should == "1"
+ doc.root.attributes["tests"].should == "3"
+ doc.root.elements.to_a("/testsuite/testcase").size.should == 3
+
+ failures = doc.root.elements.to_a("/testsuite/testcase/failure")
+ failures.size.should == 1
+ failures.first.attributes["type"].should == "Spec::Expectations::ExpectationNotMetError"
+ end
+
+ it "should have three tests and one failure for the bad coder" do
+ doc = File.open(File.join(REPORTS_DIR, 'CUCUMBER-Feature-Example-feature-Bad-coder.xml')) do |f|
+ REXML::Document.new(f)
+ end
+ doc.root.attributes["errors"].should == "0"
+ doc.root.attributes["failures"].should == "1"
+ doc.root.attributes["tests"].should == "3"
+ doc.root.elements.to_a("/testsuite/testcase").size.should == 3
+
+ failures = doc.root.elements.to_a("/testsuite/testcase/failure")
+ failures.size.should == 1
+ failures.first.attributes["type"].should == "RuntimeError"
+ end
+end
@@ -0,0 +1,99 @@
+# (c) Copyright 2006-2009 Nick Sieger <nicksieger@gmail.com>
+# See the file LICENSE.txt included with the distribution for
+# software license details.
+
+require 'ci/reporter/core'
+tried_gem = false
+begin
+ require 'cucumber'
+ require 'cucumber/ast/visitor'
+rescue LoadError
+ unless tried_gem
+ tried_gem = true
+ require 'rubygems'
+ gem 'cucumber'
+ retry
+ end
+end
+
+module CI
+ module Reporter
+ class CucumberFailure
+ attr_reader :step
+
+ def initialize(step)
+ @step = step
+ end
+
+ def failure?
+ true
+ end
+
+ def error?
+ !failure?
+ end
+
+ def name
+ step.exception.class.name
+ end
+
+ def message
+ step.exception.message
+ end
+
+ def location
+ step.exception.backtrace.join("\n")
+ end
+ end
+
+ class Cucumber < ::Cucumber::Ast::Visitor
+
+ attr_accessor :test_suite, :report_manager, :feature_name
+
+ def initialize(step_mother, io, options)
+ self.report_manager = ReportManager.new("cucumber")
+ super(step_mother)
+ end
+
+ def visit_feature_name(name)
+ self.feature_name = name.split("\n").first
+ super
+ end
+
+ def visit_feature_element(feature_element)
+ self.test_suite = TestSuite.new("#{feature_name} #{feature_element.instance_variable_get("@name")}")
+ test_suite.start
+
+ return_value = super
+
+ test_suite.finish
+ report_manager.write_report(test_suite)
+ self.test_suite = nil
+
+ return_value
+ end
+
+ def visit_step(step)
+ test_case = TestCase.new(step.name)
+ test_case.start
+
+ return_value = super
+
+ test_case.finish
+
+ case step.status
+ when :pending, :undefined
+ test_case.name = "#{test_case.name} (PENDING)"
+ when :skipped
+ test_case.name = "#{test_case.name} (SKIPPED)"
+ when :failed
+ test_case.failures << CucumberFailure.new(step)
+ end
+
+ test_suite.testcases << test_case
+
+ return_value
+ end
+ end
+ end
+end
@@ -0,0 +1,17 @@
+# (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
+# See the file LICENSE.txt included with the distribution for
+# software license details.
+
+namespace :ci do
+ namespace :setup do
+ task :cucumber_report_cleanup do
+ rm_rf ENV["CI_REPORTS"] || "features/reports"
+ end
+
+ task :cucumber => :cucumber_report_cleanup do
+ spec_opts = ["--require", "#{File.dirname(__FILE__)}/cucumber_loader.rb",
+ "--format", "CI::Reporter::Cucumber"].join(" ")
+ ENV["CUCUMBER_OPTS"] = "#{ENV['CUCUMBER_OPTS']} #{spec_opts}"
+ end
+ end
+end
@@ -0,0 +1,6 @@
+# (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
+# See the file LICENSE.txt included with the distribution for
+# software license details.
+
+$: << File.dirname(__FILE__) + "/../../.."
+require 'ci/reporter/cucumber'
Oops, something went wrong.

0 comments on commit 71d6ae2

Please sign in to comment.