Skip to content
This repository has been archived by the owner on Jan 9, 2019. It is now read-only.

Commit

Permalink
Merge branch 'feature/cucumber-integration'
Browse files Browse the repository at this point in the history
* 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 71d6ae2
Show file tree
Hide file tree
Showing 11 changed files with 454 additions and 0 deletions.
1 change: 1 addition & 0 deletions Rakefile
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions acceptance/cucumber/cucumber_example.feature
@@ -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
30 changes: 30 additions & 0 deletions acceptance/cucumber/step_definitions/development_steps.rb
@@ -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
48 changes: 48 additions & 0 deletions acceptance/verification_spec.rb
Expand Up @@ -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
99 changes: 99 additions & 0 deletions lib/ci/reporter/cucumber.rb
@@ -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
17 changes: 17 additions & 0 deletions lib/ci/reporter/rake/cucumber.rb
@@ -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
6 changes: 6 additions & 0 deletions lib/ci/reporter/rake/cucumber_loader.rb
@@ -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'

0 comments on commit 71d6ae2

Please sign in to comment.