You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by as...@apache.org on 2008/01/12 01:48:15 UTC
svn commit: r611339 - in /incubator/buildr/trunk: doc/pages/ lib/core/
lib/java/ spec/
Author: assaf
Date: Fri Jan 11 16:48:12 2008
New Revision: 611339
URL: http://svn.apache.org/viewvc?rev=611339&view=rev
Log:
JUnit and TestNG now working with new test framework
Modified:
incubator/buildr/trunk/doc/pages/testing.textile
incubator/buildr/trunk/lib/core/compile.rb
incubator/buildr/trunk/lib/core/test.rb
incubator/buildr/trunk/lib/java/compilers.rb
incubator/buildr/trunk/lib/java/test_frameworks.rb
incubator/buildr/trunk/spec/compile_spec.rb
incubator/buildr/trunk/spec/java_compilers.rb
incubator/buildr/trunk/spec/java_test_frameworks.rb
incubator/buildr/trunk/spec/sandbox.rb
incubator/buildr/trunk/spec/spec_helpers.rb
incubator/buildr/trunk/spec/test_spec.rb
Modified: incubator/buildr/trunk/doc/pages/testing.textile
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/doc/pages/testing.textile?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/doc/pages/testing.textile (original)
+++ incubator/buildr/trunk/doc/pages/testing.textile Fri Jan 11 16:48:12 2008
@@ -15,7 +15,7 @@
The first two tasks to execute are @test.compile@ and @test.resources@. They
work similar to @compile@ and @resources@, but uses a different set of
-directories. For example, Java test cases compile from the @src/test/java@
+directories. For example, Java tests compile from the @src/test/java@
directory into the @target/test/classes@ directory, while resources are copied
from @src/test/resources@ into @target/test/resources@.
@@ -30,7 +30,7 @@
dependency lists separately, but using @test.with@ is good enough in more
cases.
-Once compiled, the @test@ task runs the test cases.
+Once compiled, the @test@ task runs all the tests.
h2. Using JUnit
@@ -97,9 +97,9 @@
h2. Excluding Tests and Ignoring Failures
-If you have a lot of test cases that are failing or just hanging there
-collecting dusts, you can tell Buildr to ignore them. You can either tell
-Buildr to only run specific tests, for example:
+If you have a lot of tests that are failing or just hanging there collecting
+dusts, you can tell Buildr to ignore them. You can either tell Buildr to only
+run specific tests, for example:
{{{!ruby
test.include 'com.acme.tests.passing.*'
@@ -143,7 +143,7 @@
It's a good idea to run tests every time you change the source code, so we
wired the @build@ task to run the @test@ task at the end of the build. And
conveniently enough, the @build@ task is the default task, so another way to
-build changes in your code and run your test cases:
+build changes in your code and run your tests:
{{{!sh
$ buildr
@@ -154,7 +154,7 @@
@build@ task that does not invoke the @test@ task, so @buildr build@ will run
the tests cases, but @buildr foo:build@ will not.
-While it's a good idea to always run your test cases, it's not always possible.
+While it's a good idea to always run your tests, it's not always possible.
There are two ways you can get @build@ to not run the @test@ task. You can set
the environment variable @test@ to @no@ (but @skip@ and @off@ will also work).
You can do that when running Buildr:
@@ -174,21 +174,20 @@
Buildfile or @buildr.rb@ file, by setting @options.test = false@. We didn't say
it's a good idea, we're just giving you the option.
-The @test@ task is just smart enough to run all the test cases it finds, but
-will accept include/exclude patterns. Often enough you're only working on one
-broken test case and you only want to run that one test case. Better than
-changing your Buildfile, you can run the @test@ task with a pattern. For
-example:
+The @test@ task is just smart enough to run all the tests it finds, but will
+accept include/exclude patterns. Often enough you're only working on one
+broken test and you only want to run that one test. Better than changing your
+Buildfile, you can run the @test@ task with a pattern. For example:
{{{!sh
$ buildr test:KillerAppTest
}}}
-Buildr will then only run tests that contain the value @KillerAppTest@. It
+Buildr will then run only tests that match the pattern @KillerAppTest@. It
uses pattern matching, so @test:Foo@ will run @com.acme.FooTest@ and
-@com.acme.FooBarTest@. You can use a class name, or a package name to run all
-tests in that package, or any such combination. In fact, you can specify
-several patterns separated with commas. For example:
+@com.acme.FooBarTest@. With Java, you can use this to pick a class name, or a
+package name to run all tests in that package, or any such combination. In
+fact, you can specify several patterns separated with commas. For example:
{{{!sh
$ buildr test:FooTest,BarTest
@@ -214,8 +213,8 @@
So far we talked about unit tests. Unit tests are run in isolation on the
specific project they test, in an isolated environment, generally with minimal
-setup and teardown. You get a sense of that when we told you test cases run
-after the @build@ task, and include JMock in the dependency list.
+setup and teardown. You get a sense of that when we told you tests run after
+the @build@ task, and include JMock in the dependency list.
In contrast, integration tests are run with a number of components, in an
environment that resembles production, often with more complicates setup and
@@ -224,8 +223,8 @@
You write integration tests much the same way as you write unit tests, using
@test.compile@ and @test.resources@. However, you need to tell Buildr that
-your test cases will execute during integration test. To do so, add the
-following line in your project definition:
+your tests will execute during integration test. To do so, add the following
+line in your project definition:
{{{!ruby
test.using :integration
Modified: incubator/buildr/trunk/lib/core/compile.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/compile.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/compile.rb (original)
+++ incubator/buildr/trunk/lib/core/compile.rb Fri Jan 11 16:48:12 2008
@@ -22,7 +22,7 @@
# Adds a compiler to the list of supported compiler.
#
# For example:
- # Buildr::Compiler.add Buildr::Javac
+ # Buildr::Compiler << Buildr::Javac
def add(compiler)
@compilers ||= []
@compilers |= [compiler]
@@ -44,7 +44,7 @@
# The compiler's identifier (e.g. :javac). Inferred from the class name.
def to_sym
- @symbol
+ @symbol ||= name.split('::').last.downcase.to_sym
end
# The compiled language (e.g. :java).
@@ -59,8 +59,6 @@
attr_reader :target_ext
# The default packaging type (e.g. :jar).
attr_reader :packaging
- # Options to inherit from parent task. Defaults to value of OPTIONS constant.
- attr_reader :inherit_options
# Returns true if this compiler applies to any source code found in the listed source
# directories. For example, Javac returns true if any of the source directories contains
@@ -74,17 +72,15 @@
# For example:
# specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
def specify(attrs)
- attrs[:symbol] ||= name.split('::').last.downcase.to_sym
attrs[:sources] ||= attrs[:language].to_s
attrs[:source_ext] ||= attrs[:language].to_s
- attrs[:inherit_options] ||= const_get('OPTIONS').clone rescue []
attrs.each { |name, value| instance_variable_set("@#{name}", value) }
end
end
# Construct a new compiler with the specified options. Note that options may
- # changed before the compiler is run.
+ # change before the compiler is run.
def initialize(options)
@options = options
end
@@ -183,8 +179,9 @@
def initialize(*args) #:nodoc:
super
- @parent_task = Project.parent_task(name)
- @options = OpenObject.new
+ parent_task = Project.parent_task(name)
+ inherit = lambda { |hash, key| parent_task.options[key] } if parent_task.respond_to?(:options)
+ @options = OpenObject.new &inherit
@sources = FileList[]
@dependencies = FileList[]
@@ -317,8 +314,6 @@
def compiler=(name) #:nodoc:
raise "#{compiler} compiler already selected for this project" if @compiler
cls = Compiler.select(name) or raise ArgumentError, "No #{name} compiler available. Did you install it?"
- cls.inherit_options.reject { |name| options.has_key?(name) }.
- each { |name| options[name] = @parent_task.options[name] } if @parent_task.respond_to?(:options)
@compiler = cls.new(options)
from Array(cls.sources).map { |path| @project.path_to(:source, @usage, path) }.
select { |path| File.exist?(path) } if sources.empty?
Modified: incubator/buildr/trunk/lib/core/test.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/test.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/test.rb (original)
+++ incubator/buildr/trunk/lib/core/test.rb Fri Jan 11 16:48:12 2008
@@ -7,37 +7,36 @@
# The underlying test framework used by TestTask.
# To add a new test framework, extend TestFramework::Base and add your framework using:
- # Buildr::TestFramework.add MyFramework
+ # Buildr::TestFramework << MyFramework
class TestFramework
class << self
# Returns true if the specified test framework exists.
def has?(name)
- frameworks.any? { |framework| framework.name == name }
+ frameworks.any? { |framework| framework.to_sym == name.to_sym }
end
# Select a test framework by its name.
def select(name)
- frameworks.detect { |framework| framework.name == name }
+ frameworks.detect { |framework| framework.to_sym == name.to_sym }
end
# Identify which test framework applies for this project.
- def identify_from(project)
+ def select_from(project)
# Look for a suitable test framework based on the compiled language,
# which may return multiple candidates, e.g. JUnit and TestNG for Java.
# Pick the one used in the parent project, if not, whichever comes first.
- candidates = frameworks.select { |framework| framework.supports?(project) }
- parent = project.parent.test.framework if project.parent
- candidates.detect { |framework| framework.name == parent } || candidates.first
+ candidates = frameworks.select { |framework| framework.applies_to?(project) }
+ parent = project.parent
+ parent && candidates.detect { |framework| framework.to_sym == parent.test.framework } || candidates.first
end
# Adds a test framework to the list of supported frameworks.
#
# For example:
- # Buildr::TestFramework.add Buildr::JUnit
+ # Buildr::TestFramework << Buildr::JUnit
def add(framework)
- framework = framework.new if Class === framework
@frameworks ||= []
@frameworks |= [framework]
end
@@ -54,21 +53,57 @@
# (see JUnit as an example).
class Base
- def initialize(args = {})
- args[:name] ||= self.class.name.split('::').last.downcase.to_sym
- args[:requires] ||= []
- args.each { |name, value| instance_variable_set "@#{name}", value }
+ class << self
+
+ # The framework's identifier (e.g. :junit). Inferred from the class name.
+ def to_sym
+ @symbol ||= name.split('::').last.downcase.to_sym
+ end
+
+ # Returns true if this framework applies to the current project. For example, JUnit returns
+ # true if the tests are written in Java.
+ def applies_to?(paths)
+ raise 'Not implemented'
+ end
+
+ # Returns a list of dependencies for this framework. Defaults to obtaining a list of
+ # artifact specifications from the REQUIRES constant.
+ def dependencies
+ @dependencies ||= FileList[*(const_get('REQUIRES') rescue [])]
+ end
+
+ end
+
+ # Construct a new test framework with the specified options. Note that options may
+ # change before the framework is run.
+ def initialize(options)
+ @options = options
end
- attr_accessor :name
- attr_accessor :requires
+ # Options for this test framework.
+ attr_reader :options
- def tests(path)
- Dir["#{path}/**/*"]
+ # Returns a list of dependenices for this framework. Defaults to calling the #dependencies
+ # method on the class.
+ def dependencies
+ self.class.dependencies
end
- def supports?(project)
- false
+ # TestTask calls this method to return a list of test names that can be run in this project.
+ # It then applies the include/exclude patterns to arrive at the list of tests that will be
+ # run, and call the #run method with that list.
+ #
+ # This method should return a list suitable for using with the #run method, but also suitable
+ # for the user to manage. For example, JUnit locates all the tests in the test.compile.target
+ # directory, and returns the class names, which are easier to work with than file names.
+ def tests(project)
+ raise 'Not implemented'
+ end
+
+ # TestTask calls this method to run the named (and only those) tests. This method returns
+ # the list of tests that ran successfully.
+ def run(tests, task, dependencies)
+ raise 'Not implemented'
end
end
@@ -81,16 +116,16 @@
# You can use the test task in three ways. You can access and configure specific test tasks,
# e.g. enhance the #compile task, or run code during #setup/#teardown.
#
- # You can use convenient methods that handle the most common settings. For example, add
- # dependencies using #with, or include only specific test cases using #include.
+ # You can use convenient methods that handle the most common settings. For example,
+ # add dependencies using #with, or include only specific tests using #include.
#
# You can also enhance this task directly. This task will first execute the #compile task, followed
# by the #setup task, run the unit tests, any other enhancements, and end by executing #teardown.
#
- # Unit tests are fun from classed compiled by the test.compile class that match the TEST_FILE_PATTERN
- # (i.e. MyClassTest, MyClassTestSuite, etc). The test framework is determined by setting one of the
- # test framework options to true, for example:
- # test.unsing :testng
+ # The test framework is determined based on the available test files, for example, if the test
+ # cases are written in Java, then JUnit is selected as the test framework. You can also select
+ # a specific test framework, for example, to use TestNG instead of JUnit:
+ # test.using :testng
class TestTask < Rake::Task
class << self
@@ -118,7 +153,7 @@
# Used by the test/integration rule to only run tests that match the specified names.
def only_run(tests) #:nodoc:
tests = tests.map { |name| name =~ /\*/ ? name : "*#{name}*" }
- # Since the test case may reside in a sub-project, we need to set the include/exclude pattern on
+ # Since the tests may reside in a sub-project, we need to set the include/exclude pattern on
# all sub-projects, but only invoke test on the local project.
Project.projects.each { |project| project.test.instance_eval { @include = tests ; @exclude.clear } }
end
@@ -132,13 +167,15 @@
@dependencies = FileList[]
@include = []
@exclude = []
- @options = OpenObject.new
parent_task = Project.parent_task(name)
if parent_task.respond_to?(:options)
- parent_task.options.each { |name, value| @options[name] = value unless @options.has_key?(name) }
+ @options = OpenObject.new { |hash, key| parent_task.options[key] }
+ else
+ @options = OpenObject.new(DEFAULT_OPTIONS)
+ end
+ enhance do
+ run_tests if framework
end
- DEFAULT_OPTIONS.each { |name, value| @options[name] = value unless @options.has_key?(name) }
- enhance { run_tests }
end
# The dependencies used for running the tests. Includes the compiled files (compile.target)
@@ -175,11 +212,11 @@
#
# The compile task is similar to the Project's compile task. However, it compiles all
# files found in the src/test/{source} directory into the target/test/{code} directory.
- # This task is executed by the test task before running any test cases.
+ # This task is executed by the test task before running any tests.
#
# Once the project definition is complete, all dependencies from the regular
# compile task are copied over, so you only need to specify dependencies
- # specific to your test cases. You can do so by calling #with on the test task.
+ # specific to your tests. You can do so by calling #with on the test task.
# The dependencies used here are also copied over to the junit task.
def compile(*sources, &block)
@project.task('test:compile').from(sources).enhance &block
@@ -217,7 +254,7 @@
# with(*specs) => self
#
# Specify artifacts (specs, tasks, files, etc) to include in the depdenenciest list
- # when compiling and running test cases.
+ # when compiling and running tests.
def with(*artifacts)
@dependencies |= Buildr.artifacts(artifacts.flatten).uniq
compile.with artifacts
@@ -230,26 +267,34 @@
# :call-seq:
# using(options) => self
#
- # Sets various test options from a hash and returns self. Can also be used to select
- # the test framework. For example:
- # test.using :testng, :fork=>:each, :properties=>{ 'url'=>'http://localhost:8080' }
- #
- # Currently supports the following options:
- # * :fail_on_failure -- True to fail on test failure (default is true).
- # * :fork -- Fork test cases (JUnit only).
- # * :properties -- System properties.
- # * :environment -- Environment variables.
- #
- # The :fork option takes the following values:
- # * :once -- Fork one JVM for each project (default).
- # * :each -- Fork one JVM for each test case.
- # * false -- Do not fork, running all test cases in the same JVM.
+ # Sets various test options from a hash and returns self. For example:
+ # test.using :fork=>:each, :properties=>{ 'url'=>'http://localhost:8080' }
+ #
+ # Can also be used to select the test framework, or to run these tests as
+ # integration tests. For example:
+ # test.using :testng
+ # test.using :integration
+ #
+ # The :fail_on_failure option specifies whether the task should fail if
+ # any of the tests fail (default), or should report the failures but continue
+ # running the build (when set to false).
+ #
+ # All other options depend on the capability of the test framework. These options
+ # should be used the same way across all frameworks that support them:
+ # * :fork -- Fork once for each project (:once, default), for each test in each
+ # project (:each), or don't fork at all (false).
+ # * :properties -- Properties pass to the test, e.g. in Java as system properties.
+ # * :environment -- Environment variables. This hash is made available in the
+ # form of environment variables.
def using(*args)
args.pop.each { |key, value| options[key.to_sym] = value } if Hash === args.last
args.each do |name|
if TestFramework.has?(name)
- select name
+ self.framework = name
+ elsif name == :integration
+ options[:integration] = true
else
+ warn_deprecated "Please replace with using(:#{name}=>true)"
options[name.to_sym] = true
end
end
@@ -259,19 +304,16 @@
# :call-seq:
# include(*names) => self
#
- # Include only the specified test cases. Unless specified, the default is to include
- # all test cases. This method accepts multiple arguments and returns self.
- #
- # Test cases are specified using the fully qualified class name. You can also use file-like
- # patterns (glob) to specify collection of files, classes, packages, etc. For example:
- # test.include 'com.example.FirstTest'
- # test.include 'com.example.*'
- # test.include 'com.example.Module*'
- # test.include '*.{First,Second}Test'
- #
- # By default, all classes that have a name ending with Test or Suite are included.
- # Use these suffixes for your test and test suite classes respectively, to distinguish them
- # from stubs, helper classes, etc.
+ # Include only the specified tests. Unless specified, the default is to include
+ # all tests identified by the test framework. This method accepts multiple arguments
+ # and returns self.
+ #
+ # Tests are specified by their full name, but you can use glob patterns to select
+ # multiple tests, for example:
+ # test.include 'com.example.FirstTest' # FirstTest only
+ # test.include 'com.example.*' # All tests under com/example
+ # test.include 'com.example.Module*' # All tests starting with Module
+ # test.include '*.{First,Second}Test' # FirstTest, SecondTest
def include(*names)
@include += names
self
@@ -280,7 +322,7 @@
# :call-seq:
# exclude(*names) => self
#
- # Exclude the specified test cases. This method accepts multiple arguments and returns self.
+ # Exclude the specified tests. This method accepts multiple arguments and returns self.
# See #include for the type of arguments you can use.
def exclude(*names)
@exclude += names
@@ -288,60 +330,42 @@
end
# :call-seq:
- # tests() => strings
+ # tests => strings
#
- # List of test files to run. Determined by finding all the test failes in the target directory,
- # and reducing based on the include/exclude patterns.
+ # List the tests that this task will run.
def tests
- return [] unless compile.target
- fail "No test framework selected" unless @framework
- @files ||= begin
- base = Pathname.new(compile.target.to_s)
- @framework.tests(compile.target.to_s).select { |test| include?(test) }.sort
- end
+ fail "No test framework selected" unless framework
+ @tests ||= @framework.tests(@project).select { |test| include?(test) }.sort
end
# *Deprecated*: Use tests instead.
def classes
- warn_deprecated 'Use tests instead'
+ warn_deprecated 'Call tests instead of classes'
tests
end
- # List of failed tests. Set after running the tests.
+ # After running the task, returns all the tests that failed, empty array if all tests passed.
attr_reader :failed_tests
- # List of passed tests. Set after running the tests.
+ # After running the task, returns all the tests that passed, empty array if no tests passed.
attr_reader :passed_tests
# :call-seq:
- # include?(name) => boolean
- #
- # Returns true if the specified class name matches the inclusion/exclusion pattern. Used to determine
- # which tests to execute.
- def include?(name)
- (@include.empty? || @include.any? { |pattern| File.fnmatch(pattern, name) }) &&
- !@exclude.any? { |pattern| File.fnmatch(pattern, name) }
- end
-
- # :call-seq:
- # requires() => specs
- #
- # Returns the dependencies for the selected test frameworks. Necessary for compiling and running test cases.
- def requires
- framework ? Array(@framework.requires) : []
- end
-
- # :call-seq:
- # framework() => symbol
+ # framework => symbol
#
# Returns the test framework, e.g. :junit, :testng.
def framework
- @framework ||= TestFramework.identify_from(@project)
- @framework && @framework.name
+ unless @framework
+ frameworks = TestFramework.frameworks.select { |cls| cls.applies_to?(@project) }
+ candidate = @project.parent && frameworks.detect { |framework| framework.to_sym == @project.parent.test.framework } ||
+ frameworks.first
+ self.framework = candidate if candidate
+ end
+ @framework && @framework.class.to_sym
end
# :call-seq:
- # report_to() => file
+ # report_to => file
#
# Test frameworks that can produce reports, will write them to this directory.
#
@@ -359,23 +383,34 @@
@project = project
end
- def select(name)
- @framework = TestFramework.select(name)
+ def framework=(name)
+ cls = TestFramework.select(name) or raise ArgumentError, "No #{name} test framework available. Did you install it?"
+ #cls.inherit_options.reject { |name| options.has_key?(name) }.
+ # each { |name| options[name] = @parent_task.options[name] } if @parent_task.respond_to?(:options)
+ @framework = cls.new(options)
+ # Test framework dependency.
+ with @framework.class.dependencies
end
# :call-seq:
- # run_tests()
+ # include?(name) => boolean
#
- # Runs the test cases using the selected test framework. Executes as part of the task.
+ # Returns true if the specified test name matches the inclusion/exclusion pattern. Used to determine
+ # which tests to execute.
+ def include?(name)
+ (@include.empty? || @include.any? { |pattern| File.fnmatch(pattern, name) }) &&
+ !@exclude.any? { |pattern| File.fnmatch(pattern, name) }
+ end
+
+ # Runs the tests using the selected test framework.
def run_tests
rm_rf report_to.to_s
- tests = self.tests
if tests.empty?
@passed_tests, @failed_tests = [], []
else
puts "Running tests in #{@project.name}" if verbose
- @failed_tests = @framework.run(tests, self, @dependencies.compact.map(&:to_s))
- @passed_tests = tests - @failed_tests
+ @passed_tests = @framework.run(tests, self, @dependencies.compact.map(&:to_s))
+ @failed_tests = tests - @passed_tests
unless @failed_tests.empty?
warn "The following tests failed:\n#{@failed_tests.join('\n')}" if verbose
fail 'Tests failed!'
@@ -431,22 +466,21 @@
end
- # Methods added to Project to support compilation and running of test cases.
+ # Methods added to Project to support compilation and running of tests.
module Test
include Extension
first_time do
- desc 'Run all test cases'
+ desc 'Run all tests'
task('test') { TestTask.run_local_tests false }
- # This rule takes a suffix and runs that test case in the current project. For example;
+ # This rule takes a suffix and runs that tests in the current project. For example;
# buildr test:MyTest
- # will run the test case class com.example.MyTest, if found in the current project.
+ # will run the test com.example.MyTest, if such a test exists for this project.
#
- # If you want to run multiple test cases, separate tham with a comma. You can also use glob
- # (* and ?) patterns to match multiple tests, e.g. com.example.* to run all test cases in
- # a given package. If you don't specify a glob pattern, asterisks are added for you.
+ # If you want to run multiple test, separate tham with a comma. You can also use glob
+ # (* and ?) patterns to match multiple tests, see the TestTask#include method.
rule /^test:.*$/ do |task|
TestTask.only_run task.name.scan(/test:(.*)/)[0][0].split(',')
task('test').invoke
@@ -454,7 +488,7 @@
task 'build' do |task|
# Make sure this happens as the last action on the build, so all other enhancements
- # are made to run before starting the test cases.
+ # are made to run before starting the tests.
task.enhance do
task('test').invoke unless Buildr.options.test == false
end
@@ -496,11 +530,11 @@
# Dependency on compiled code, its dependencies and resources.
test.with project.compile.dependencies, Array(project.compile.target) if project.compile.target
test.with Array(project.resources.target)
- # Dependency on compiled test cases and resources. Dependencies added using with.
+ # Dependency on compiled tests and resources. Dependencies added using with.
test.dependencies.concat Array(test.compile.target) if test.compile.target
test.dependencies.concat Array(test.resources.target)
- # Test framework dependency.
- test.with test.requires
+ # Picking up the test frameworks adds further dependencies.
+ test.framework
project.clean do
verbose(false) do
@@ -519,26 +553,25 @@
#
# You can use the test task in three ways. You can access and configure specific
# test tasks, e.g. enhance the compile task by calling test.compile, setup for
- # the test cases by enhancing test.setup and so forth.
+ # the tests by enhancing test.setup and so forth.
#
# You can use convenient methods that handle the most common settings. For example,
- # add dependencies using test.with, or include only specific test cases
- # using test.include.
+ # add dependencies using test.with, or include only specific tests using test.include.
#
# You can also enhance this task directly. This method accepts a list of arguments
# that are used as prerequisites and an optional block that will be executed by the
# test task.
#
- # This task compiles the project and the test cases (in that order) before running any tests.
- # It execute the setup task, runs all the test cases, any enhancements, and ends with the
+ # This task compiles the project and the tests (in that order) before running any tests.
+ # It execute the setup task, runs all the tests, any enhancements, and ends with the
# teardown tasks.
def test(*prereqs, &block)
task('test').enhance prereqs, &block
end
# :call-seq:
- # integration() { |task| .... }
- # integration() => IntegrationTestTask
+ # integration { |task| .... }
+ # integration => IntegrationTestTask
#
# Use this method to return the integration tests task, or enhance it with a block to execute.
#
@@ -547,7 +580,7 @@
# :integration=>true, all other tests are considered unit tests and run by the test task before packaging.
# So essentially: build=>test=>packaging=>integration=>install/deploy.
#
- # You add new test cases from projects that define integration tests using the regular test task,
+ # You add new tests from projects that define integration tests using the regular test task,
# but with the following addition:
# test.using :integration
#
@@ -561,8 +594,8 @@
# :call-seq:
- # integration() { |task| .... }
- # integration() => IntegrationTestTask
+ # integration { |task| .... }
+ # integration => IntegrationTestTask
#
# Use this method to return the integration tests task.
def integration(*deps, &block)
@@ -571,17 +604,17 @@
class Options
- # Runs test cases after the build when true (default). This forces test cases to execute
+ # Runs tests after the build when true (default). This forces tests to execute
# after the build, including when running build related tasks like install, deploy and release.
#
- # Set to false to not run any test cases. Set to :all to run all test cases, ignoring failures.
+ # Set to false to not run any tests. Set to :all to run all tests, ignoring failures.
#
# This option is set from the environment variable 'test', so you can also do:
# Returns the test option (environment variable TEST). Possible values are:
- # * :false -- Do not run any test cases (also accepts 'no' and 'skip').
- # * :true -- Run all test cases, stop on failure (default if not set).
- # * :all -- Run all test cases, ignore failures.
+ # * :false -- Do not run any tests (also accepts 'no' and 'skip').
+ # * :true -- Run all tests, stop on failure (default if not set).
+ # * :all -- Run all tests, ignore failures.
def test
case value = ENV['TEST'] || ENV['test']
when /^(no|off|false|skip)$/i
@@ -591,7 +624,7 @@
when /^(yes|on|true)$/i, nil
true
else
- warn "Expecting the environment variable test to be 'no' or 'all', not sure what to do with #{value}, so I'm just going to run all the test cases and stop at failure."
+ warn "Expecting the environment variable test to be 'no' or 'all', not sure what to do with #{value}, so I'm just going to run all the tests and stop at failure."
true
end
end
@@ -615,9 +648,9 @@
task('help') do
puts <<-HELP
-To run a full build without running any test cases:
+To run a full build without running any tests:
buildr test=no
-To run specific test case:
+To run specific test:
buildr test:MyTest
To run integration tests:
buildr integration
Modified: incubator/buildr/trunk/lib/java/compilers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/compilers.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/compilers.rb (original)
+++ incubator/buildr/trunk/lib/java/compilers.rb Fri Jan 11 16:48:12 2008
@@ -29,8 +29,10 @@
def initialize(options) #:nodoc:
super
- { :warnings=>verbose, :deprecation=>false, :lint=>false, :debug=>Buildr.options.debug }.
- each { |name, value| options[name] = value unless options.has_key?(name) }
+ options[:debug] = Buildr.options.debug if options[:debug].nil?
+ options[:warnings] = verbose if options[:warnings].nil?
+ options[:deprecation] ||= false
+ options[:lint] ||= false
end
def compile(sources, target, dependencies) #:nodoc:
Modified: incubator/buildr/trunk/lib/java/test_frameworks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/test_frameworks.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/test_frameworks.rb (original)
+++ incubator/buildr/trunk/lib/java/test_frameworks.rb Fri Jan 11 16:48:12 2008
@@ -8,15 +8,14 @@
# JMock is available when using JUnit and TestNG.
module JMock
- # JMock version..
+ # JMock version.
VERSION = '1.2.0' unless const_defined?('VERSION')
# JMock specification.
REQUIRES = ["jmock:jmock:jar:#{VERSION}"]
end
- # JUnit test framework, the default test framework for Java.
- # test.using :junit
+ # JUnit test framework, the default test framework for Java tests.
#
# Support the following options:
# * :fork -- If true/:once (default), fork for each test class. If :each, fork for each individual
@@ -92,7 +91,7 @@
end
- # Ant-JUnit requires for JUnit and JUnit reports tasks.
+ # Ant-JUnit requires for JUnit and JUnit reports tasks. Also requires JUnitTestFilter.
Java.classpath << "org.apache.ant:ant-junit:jar:#{Ant::VERSION}" << File.join(File.dirname(__FILE__))
# JUnit version number.
@@ -100,27 +99,28 @@
# JUnit specification.
REQUIRES = ["junit:junit:jar:#{VERSION}"] + JMock::REQUIRES
- def initialize #:nodoc:
- super :requires=>REQUIRES
+ class << self
+
+ def applies_to?(project) #:nodoc:
+ project.test.compile.language == :java
+ end
+
end
- def tests(path) #:nodoc:
- # Ignore anonymous classes.
- base = Pathname.new(path)
- candidates = super(path).map { |file| Pathname.new(file).relative_path_from(base).to_s.ext('').gsub(File::SEPARATOR, ',') }.
+ def tests(project) #:nodoc:
+ return [] unless project.test.compile.target
+ target = Pathname.new(project.test.compile.target.to_s)
+ candidates = Dir["#{target}/**/*.class"].
+ map { |file| Pathname.new(file).relative_path_from(target).to_s.ext('').gsub(File::SEPARATOR, '.') }.
reject { |name| name =~ /\$/ }
- classpath = [path + '/'] + Buildr.artifacts(REQUIRES).map(&:to_s)
+ classpath = [target.to_s + '/'] + Buildr.artifacts(dependencies).map(&:to_s)
Java.org.apache.buildr.JUnitTestFilter.new(classpath).filter(candidates)
end
- def supports?(project) #:nodoc:
- project.test.compile.language == :java
- end
-
def run(tests, task, dependencies) #:nodoc:
# Use Ant to execute the Junit tasks, gives us performance and reporting.
Buildr.ant('junit') do |ant|
- case task.options[:fork]
+ case options[:fork]
when false
forking = {}
when :each
@@ -131,11 +131,11 @@
fail 'Option fork must be :once, :each or false.'
end
mkpath task.report_to.to_s
- ant.junit forking.merge(:clonevm=>task.options[:clonevm] || false, :dir=>task.send(:project).path_to) do
+ ant.junit forking.merge(:clonevm=>options[:clonevm] || false, :dir=>task.send(:project).path_to) do
ant.classpath :path=>dependencies.each { |path| file(path).invoke }.join(File::PATH_SEPARATOR)
- (task.options[:properties] || []).each { |key, value| ant.sysproperty :key=>key, :value=>value }
- (task.options[:environment] || []).each { |key, value| ant.env :key=>key, :value=>value }
- java_args = task.options[:java_args] || Buildr.options.java_args
+ (options[:properties] || []).each { |key, value| ant.sysproperty :key=>key, :value=>value }
+ (options[:environment] || []).each { |key, value| ant.env :key=>key, :value=>value }
+ java_args = options[:java_args] || Buildr.options.java_args
java_args = java_args.split(/\s+/) if String === java_args
java_args.each { |value| ant.jvmarg :value=>value } if java_args
ant.formatter :type=>'plain'
@@ -147,19 +147,19 @@
end
end
end
- return [] unless ant.project.getProperty('failed')
+ return tests unless ant.project.getProperty('failed')
end
# But Ant doesn't tell us what went kaput, so we'll have to parse the test files.
- tests.inject([]) do |failed, test|
+ tests.inject([]) do |passed, test|
report_file = File.join(task.report_to.to_s, "TEST-#{test}.txt")
if File.exist?(report_file)
report = File.read(report_file)
# The second line (if exists) is the status line and we scan it for its values.
status = (report.split("\n")[1] || '').scan(/(run|failures|errors):\s*(\d+)/i).
inject(Hash.new(0)) { |hash, pair| hash[pair[0].downcase.to_sym] = pair[1].to_i ; hash }
- failed << test if status[:failures] > 0 || status[:errors] > 0
+ passed << test if status[:failures] == 0 && status[:errors] == 0
end
- failed
+ passed
end
end
@@ -176,7 +176,7 @@
end
- # TestNG test framework.
+ # TestNG test framework. To use in your project:
# test.using :testng
#
# Support the following options:
@@ -192,32 +192,34 @@
# that match this pattern are used.
TESTS_PATTERN = [ /^Test/, /Test$/, /TestCase$/ ]
- def initialize #:nodoc:
- super :requires=>REQUIRES
- end
+ class << self
+
+ def applies_to?(project) #:nodoc:
+ project.test.compile.language == :java
+ end
- def supports?(project) #:nodoc:
- project.test.compile.language == :java
end
- def tests(path) #:nodoc:
- # Ignore anonymous classes.
- base = Pathname.new(path)
- candidates = super(path).map { |file| Pathname.new(file).relative_path_from(base).to_s.ext('').gsub(File::SEPARATOR, ',') }.
- reject { |name| name =~ /\$/ }.select { |name| TESTS_PATTERN.any? { |pattern| name =~ pattern } }
+ def tests(project) #:nodoc:
+ return [] unless project.test.compile.target
+ target = Pathname.new(project.test.compile.target.to_s)
+ Dir["#{target}/**/*.class"].
+ map { |file| Pathname.new(file).relative_path_from(target).to_s.ext('').gsub(File::SEPARATOR, '.') }.
+ reject { |name| name =~ /\$/ }.select { |name| cls_name = name.split('.').last
+ TESTS_PATTERN.any? { |pattern| cls_name =~ pattern } }
end
def run(tests, task, dependencies) #:nodoc:
cmd_args = [ 'org.testng.TestNG', '-sourcedir', task.compile.sources.join(';'), '-suitename', task.send(:project).name ]
cmd_args << '-d' << task.report_to.to_s
- cmd_options = { :properties=>task.options[:properties], :java_args=>task.options[:java_args],
+ cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args],
:classpath=>dependencies }
- tests.inject([]) do |failed, test|
+ tests.inject([]) do |passed, test|
begin
Buildr.java cmd_args, '-testclass', test, cmd_options.merge(:name=>test)
- failed
+ passed << test
rescue
- failed << test
+ passed
end
end
end
Modified: incubator/buildr/trunk/spec/compile_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/compile_spec.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/compile_spec.rb (original)
+++ incubator/buildr/trunk/spec/compile_spec.rb Fri Jan 11 16:48:12 2008
@@ -93,7 +93,7 @@
it 'should attempt to identify compiler if sources are specified' do
define 'foo' do
- Compiler.compilers.first.should_receive(:applies_to?)
+ Compiler.compilers.first.should_receive(:applies_to?).at_least(:once)
compile.from('sources').compiler
end
end
Modified: incubator/buildr/trunk/spec/java_compilers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java_compilers.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/java_compilers.rb (original)
+++ incubator/buildr/trunk/spec/java_compilers.rb Fri Jan 11 16:48:12 2008
@@ -3,7 +3,7 @@
describe 'javac compiler' do
it 'should identify itself from source directories' do
- write 'src/main/java/Test.java', 'class Test {}'
+ write 'src/main/java/com/example/Test.java', 'package com.example; class Test {}'
define('foo').compile.compiler.should eql(:javac)
end
@@ -192,17 +192,6 @@
compile.options.deprecation.should be_true
compile.options.source.should eql('1.5')
compile.options.target.should eql('1.4')
- end
- end
- end
-
- it 'should only inherit options it knows' do
- define 'foo' do
- compile.using(:warnings=>true, :errors=>true)
- define 'bar' do
- compile.using(:javac)
- compile.options.warnings.should be_true
- compile.options.errors.should be_nil
end
end
end
Modified: incubator/buildr/trunk/spec/java_test_frameworks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java_test_frameworks.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/java_test_frameworks.rb (original)
+++ incubator/buildr/trunk/spec/java_test_frameworks.rb Fri Jan 11 16:48:12 2008
@@ -2,7 +2,14 @@
describe Buildr::JUnit do
- it 'should be the default test framework when test cases are in java'
+ it 'should be the default test framework when test cases are in java' do
+ write 'src/test/java/com/exampe/FirstTest.java', <<-JAVA
+ package com.example;
+ public class FirstTest extends junit.framework.TestCase { }
+ JAVA
+ define 'foo'
+ project('foo').test.framework.should eql(:junit)
+ end
it 'should be picked if the test language is Java' do
define 'foo' do
@@ -24,14 +31,16 @@
end
it 'should include public classes extending junit.framework.TestCase' do
- write 'src/test/java/FirstTest.java', <<-JAVA
+ write 'src/test/java/com/example/FirstTest.java', <<-JAVA
+ package com.example;
public class FirstTest extends junit.framework.TestCase { }
JAVA
- write 'src/test/java/AnotherOne.java', <<-JAVA
+ write 'src/test/java/com/example/AnotherOne.java', <<-JAVA
+ package com.example;
public class AnotherOne extends junit.framework.TestCase { }
JAVA
define('foo').test.compile.invoke
- project('foo').test.tests.should include('FirstTest', 'AnotherOne')
+ project('foo').test.tests.should include('com.example.FirstTest', 'com.example.AnotherOne')
end
it 'should ignore classes not extending junit.framework.TestCase' do
@@ -55,21 +64,31 @@
it 'should pass when JUnit test case passes' do
write 'src/test/java/PassingTest.java', <<-JAVA
- public class PassingTest extends junit.framework.TestCase { public void testNothing() {} }
+ public class PassingTest extends junit.framework.TestCase {
+ public void testNothing() {}
+ }
JAVA
lambda { define('foo').test.invoke }.should_not raise_error
end
it 'should fail when JUnit test case fails' do
write 'src/test/java/FailingTest.java', <<-JAVA
- public class FailingTest extends junit.framework.TestCase { public void testFailure() { assertTrue(false); } }
+ public class FailingTest extends junit.framework.TestCase {
+ public void testFailure() {
+ assertTrue(false);
+ }
+ }
JAVA
lambda { define('foo').test.invoke }.should raise_error(RuntimeError, /Tests failed/) rescue nil
end
it 'should report failed test names' do
write 'src/test/java/FailingTest.java', <<-JAVA
- public class FailingTest extends junit.framework.TestCase { public void testFailure() { assertTrue(false); } }
+ public class FailingTest extends junit.framework.TestCase {
+ public void testFailure() {
+ assertTrue(false);
+ }
+ }
JAVA
define('foo').test.invoke rescue
project('foo').test.failed_tests.should include('FailingTest')
@@ -77,7 +96,9 @@
it 'should report to reports/junit' do
write 'src/test/java/PassingTest.java', <<-JAVA
- public class PassingTest extends junit.framework.TestCase { public void testNothing() {} }
+ public class PassingTest extends junit.framework.TestCase {
+ public void testNothing() {}
+ }
JAVA
define 'foo' do
test.report_to.should be(file('reports/junit'))
@@ -124,12 +145,18 @@
JAVA
write 'src/test/java/TestCase1.java', <<-JAVA
public class TestCase1 extends junit.framework.TestCase {
- public void testSameVM() { assertFalse(Shared.flag); Shared.flag = true; }
+ public void testSameVM() {
+ assertFalse(Shared.flag);
+ Shared.flag = true;
+ }
}
JAVA
write 'src/test/java/TestCase2.java', <<-JAVA
public class TestCase2 extends junit.framework.TestCase {
- public void testSameVM() { assertFalse(Shared.flag); Shared.flag = true; }
+ public void testSameVM() {
+ assertFalse(Shared.flag);
+ Shared.flag = true;
+ }
}
JAVA
define 'foo' do
@@ -151,7 +178,6 @@
describe Buildr::JUnit, 'report' do
-
it 'should default to the target directory reports/junit' do
JUnit.report.target.should eql('reports/junit')
end
@@ -187,8 +213,11 @@
end
it 'should generate reports from all projects that ran test cases' do
- write 'src/test/java/TestSomething.java',
- 'public class TestSomething extends junit.framework.TestCase { public void testNothing() {} }'
+ write 'src/test/java/TestSomething.java', <<-JAVA
+ public class TestSomething extends junit.framework.TestCase {
+ public void testNothing() {}
+ }
+ JAVA
define 'foo'
project('foo').test.invoke
task('junit:report').invoke
@@ -202,65 +231,112 @@
describe Buildr::TestNG do
- before do
- write 'src/test/java/PassingTest.java',
- 'public class PassingTest { @org.testng.annotations.Test public void testNothing() {} }'
- write 'src/test/java/FailingTest.java',
- 'public class FailingTest { @org.testng.annotations.Test public void testNothing() { org.testng.AssertJUnit.assertTrue(false); } }'
- define('foo') { test.using :testng }
+ it 'should be selectable in project' do
+ define 'foo' do
+ test.using(:testng)
+ test.framework.should eql(:testng)
+ end
end
-
- it 'should be selectable in parent project'
+ it 'should be selectable in parent project' do
+ write 'bar/src/test/java/TestCase.java'
+ define 'foo' do
+ test.using(:testng)
+ define 'bar'
+ end
+ project('foo:bar').test.framework.should eql(:testng)
+ end
it 'should include TestNG dependencies' do
+ define('foo') { test.using :testng }
project('foo').test.compile.dependencies.should include(*artifacts(TestNG::REQUIRES))
project('foo').test.dependencies.should include(*artifacts(TestNG::REQUIRES))
end
it 'should include TestNG dependencies' do
+ define('foo') { test.using :testng }
project('foo').test.compile.dependencies.should include(*artifacts(JMock::REQUIRES))
project('foo').test.dependencies.should include(*artifacts(JMock::REQUIRES))
end
it 'should include classes starting with and ending with Test' do
- ['TestThis', 'ThisTest', 'ThisThat'].each do |name|
- write File.join(project('foo').test.compile.target.to_s, name).ext('class')
- end
- project('foo').test.tests.map { |file| File.basename(file) }.should == ['TestThis', 'ThisTest']
+ write 'src/test/java/com/example/TestThis.java', 'package com.example; public class TestThis {}'
+ write 'src/test/java/com/example/ThisTest.java', 'package com.example; public class ThisTest {}'
+ define('foo') { test.using(:testng) }
+ project('foo').test.compile.invoke
+ project('foo').test.tests.should include('com.example.TestThis', 'com.example.ThisTest')
+ end
+
+ it 'should ignore classes not using Test prefix or suffix' do
+ write 'src/test/java/NotATestClass.java', 'public class NotATestClass {}'
+ define('foo') { test.using(:testng) }
+ project('foo').test.compile.invoke
+ project('foo').test.tests.should be_empty
end
it 'should ignore inner classes' do
- ['TestThis', 'TestThis$Innner'].each do |name|
- write "target/test/classes/#{name}.class"
- end
- project('foo').test.tests.map { |file| File.basename(file) }.should == ['TestThis']
+ write 'src/test/java/InnerClassTest.java', <<-JAVA
+ public class InnerClassTest {
+ public class InnerTest {
+ }
+ }
+ JAVA
+ define('foo') { test.using(:testng) }
+ project('foo').test.compile.invoke
+ project('foo').test.tests.should eql(['InnerClassTest'])
end
it 'should pass when TestNG test case passes' do
- project('foo').test.include 'PassingTest'
+ write 'src/test/java/PassingTest.java', <<-JAVA
+ public class PassingTest {
+ @org.testng.annotations.Test
+ public void testNothing() {}
+ }
+ JAVA
+ define('foo') { test.using(:testng) }
lambda { project('foo').test.invoke }.should_not raise_error
end
it 'should fail when TestNG test case fails' do
- project('foo').test.include 'FailingTest'
+ write 'src/test/java/FailingTest.java', <<-JAVA
+ public class FailingTest {
+ @org.testng.annotations.Test
+ public void testNothing() {
+ org.testng.AssertJUnit.assertTrue(false);
+ }
+ }
+ JAVA
+ define('foo') { test.using(:testng) }
lambda { project('foo').test.invoke }.should raise_error(RuntimeError, /Tests failed/)
end
it 'should report failed test names' do
- project('foo').test.include 'FailingTest'
- project('foo').test.invoke rescue
- project('foo').test.failed_tests.should eql(['FailingTest'])
+ write 'src/test/java/FailingTest.java', <<-JAVA
+ public class FailingTest {
+ @org.testng.annotations.Test
+ public void testNothing() {
+ org.testng.AssertJUnit.assertTrue(false);
+ }
+ }
+ JAVA
+ define('foo') { test.using(:testng) }
+ project('foo').test.invoke rescue nil
+ project('foo').test.failed_tests.should include('FailingTest')
end
it 'should report to reports/testng' do
+ define('foo') { test.using(:testng) }
project('foo').test.report_to.should be(project('foo').file('reports/testng'))
end
it 'should generate reports' do
- project('foo').test.include 'PassingTest'
- lambda { project('foo').test.invoke }.should change { File.exist?(project('foo').test.report_to.to_s) }.to(true)
+ write 'src/test/java/PassingTest.java', <<-JAVA
+ public class PassingTest {
+ @org.testng.annotations.Test
+ public void testNothing() {}
+ }
+ JAVA
+ define('foo') { test.using(:testng) }
+ lambda { project('foo').test.invoke }.should change { File.exist?('reports/testng/foo/index.html') }.to(true)
end
end
-
-
Modified: incubator/buildr/trunk/spec/sandbox.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/sandbox.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/sandbox.rb (original)
+++ incubator/buildr/trunk/spec/sandbox.rb Fri Jan 11 16:48:12 2008
@@ -3,7 +3,7 @@
# repository and cache these across test cases.
repositories.remote << 'http://repo1.maven.org/maven2'
Java.load # Anything added to the classpath.
-artifacts(TestFramework.frameworks.map(&:requires).flatten).each { |a| file(a).invoke }
+artifacts(TestFramework.frameworks.map(&:dependencies).flatten).each { |a| file(a).invoke }
task('buildr:initialize').invoke
# We need to run all tests inside a sandbox, tacking a snapshot of Rake/Buildr before the test,
Modified: incubator/buildr/trunk/spec/spec_helpers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/spec_helpers.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/spec_helpers.rb (original)
+++ incubator/buildr/trunk/spec/spec_helpers.rb Fri Jan 11 16:48:12 2008
@@ -142,7 +142,7 @@
# For example:
# lambda { task('build').invoke }.should run_task('test')
def run_task(task)
- InvokeMatcher.new task.to_a.first
+ InvokeMatcher.new [task]
end
class UriPathMatcher
Modified: incubator/buildr/trunk/spec/test_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/test_spec.rb?rev=611339&r1=611338&r2=611339&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/test_spec.rb (original)
+++ incubator/buildr/trunk/spec/test_spec.rb Fri Jan 11 16:48:12 2008
@@ -189,11 +189,6 @@
define('foo').test.dependencies.should include(project('foo').test.resources.target)
end
- it 'should include test framework dependencies' do
- define('foo') { test.using(:junit) }
- project('foo').test.dependencies.should include(*artifacts(project('foo').test.requires))
- end
-
it 'should clean after itself (test files)' do
define('foo') { test.compile.using(:javac) }
mkpath project('foo').test.compile.target.to_s
@@ -218,17 +213,14 @@
end
it 'should return no failed tests' do
- define('foo').test.invoke
+ define('foo') { test.using(:junit) }
+ project('foo').test.invoke
project('foo').test.failed_tests.should be_empty
end
it 'should return no passing tests' do
- define('foo').test.invoke
- project('foo').test.passed_tests.should be_empty
- end
-
- it 'should report no passed tests' do
- define('foo').test.invoke
+ define('foo') { test.using(:junit) }
+ project('foo').test.invoke
project('foo').test.passed_tests.should be_empty
end
@@ -239,84 +231,95 @@
describe Buildr::TestTask, 'with passing tests' do
- before do
- @tests = ['PassingTest1', 'PassingTest2']
- define 'foo'
- project('foo').test.stub!(:tests).and_return @tests
- project('foo').test.instance_eval do
- @framework.stub!(:run).and_return []
+ def tests
+ @tests ||= ['PassingTest1', 'PassingTest2']
+ end
+
+ def test_task
+ @test_task ||= begin
+ tests = self.tests
+ define 'foo' do
+ test.using(:junit)
+ test.stub!(:tests).and_return(tests.clone)
+ test.instance_eval { @framework.stub!(:run).and_return(tests.clone) }
+ end
+ project('foo').test
end
end
it 'should pass' do
- lambda { project('foo').test.invoke }.should_not raise_error
+ lambda { test_task.invoke }.should_not raise_error
end
it 'should report no failed tests' do
- lambda { verbose(true) { project('foo').test.invoke } }.should_not warn_that(/fail/i)
+ lambda { verbose(true) { test_task.invoke } }.should_not warn_that(/fail/i)
end
it 'should return passed tests' do
- project('foo').test.invoke
- project('foo').test.passed_tests.should == @tests
+ test_task.invoke
+ test_task.passed_tests.should == tests
end
it 'should return no failed tests' do
- project('foo').test.invoke
- project('foo').test.failed_tests.should be_empty
+ test_task.invoke
+ test_task.failed_tests.should be_empty
end
it 'should execute teardown task' do
- lambda { project('foo').test.invoke }.should run_task('foo:test:teardown')
+ lambda { test_task.invoke }.should run_task('foo:test:teardown')
end
end
describe Buildr::TestTask, 'with failed test' do
- before do
- @tests = ['FailingTest1', 'FailingTest2']
- define 'foo'
- project('foo').test.stub!(:tests).and_return @tests
- project('foo').test.instance_eval do
- @framework.stub!(:run).and_return ['FailingTest1']
+ def test_task
+ @test_task ||= begin
+ define 'foo' do
+ test.using(:junit)
+ test.instance_eval do
+ @framework.stub!(:tests).and_return(['FailingTest', 'PassingTest'])
+ @framework.stub!(:run).and_return(['PassingTest'])
+ end
+ end
+ project('foo').test
end
end
it 'should fail' do
- lambda { project('foo').test.invoke }.should raise_error(RuntimeError, /Tests failed/)
+ lambda { test_task.invoke }.should raise_error(RuntimeError, /Tests failed/)
end
it 'should report failed tests' do
- lambda { verbose(true) { project('foo').test.invoke rescue nil } }.should warn_that(/FailingTest1/)
+ lambda { verbose(true) { test_task.invoke rescue nil } }.should warn_that(/FailingTest/)
end
it 'should return failed tests' do
- project('foo').test.invoke rescue nil
- project('foo').test.failed_tests.should == ['FailingTest1']
+ test_task.invoke rescue nil
+ test_task.failed_tests.should == ['FailingTest']
end
it 'should return passing tests as well' do
- project('foo').test.invoke rescue nil
- project('foo').test.passed_tests.should == ['FailingTest2']
+ test_task.invoke rescue nil
+ test_task.passed_tests.should == ['PassingTest']
end
it 'should not fail if fail_on_failure is false' do
- project('foo').test.using(:fail_on_failure=>false).invoke
- lambda { project('foo').test.invoke }.should_not raise_error
+ test_task.using(:fail_on_failure=>false).invoke
+ lambda { test_task.invoke }.should_not raise_error
end
it 'should report failed tests even if fail_on_failure is false' do
- project('foo').test.using(:fail_on_failure=>false)
- lambda { verbose(true) { project('foo').test.invoke } }.should warn_that(/FailingTest1/)
+ test_task.using(:fail_on_failure=>false)
+ lambda { verbose(true) { test_task.invoke } }.should warn_that(/FailingTest/)
end
it 'should return failed tests even if fail_on_failure is false' do
- project('foo').test.using(:fail_on_failure=>false).invoke
- project('foo').test.failed_tests.should == ['FailingTest1']
+ test_task.using(:fail_on_failure=>false).invoke
+ test_task.failed_tests.should == ['FailingTest']
end
it 'should execute teardown task' do
- lambda { project('foo').test.invoke rescue nil }.should run_task('foo:test:teardown')
+ lambda { test_task.invoke rescue nil }.should run_task('foo:test:teardown')
end
end
@@ -379,7 +382,7 @@
describe Buildr::Project, '#test.compile' do
it 'should identify compiler from project' do
- write 'src/test/java/Test.java'
+ write 'src/test/java/com/example/Test.java'
define('foo') do
test.compile.compiler.should eql(:javac)
end
@@ -418,8 +421,9 @@
it 'should include the test framework dependencies' do
define 'foo' do
test.compile.using(:javac)
+ test.using(:junit)
end
- project('foo').test.compile.dependencies.should include(*artifacts(project('foo').test.requires))
+ project('foo').test.compile.dependencies.should include(*artifacts(JUnit.dependencies))
end
it 'should clean after itself' do
@@ -525,35 +529,49 @@
end
it 'should reset tasks to specific pattern' do
- define('foo') { define 'bar' }
+ define 'foo' do
+ test.using(:junit)
+ test.instance_eval { @framework.stub!(:tests).and_return(['something', 'nothing']) }
+ define 'bar' do
+ test.using(:junit)
+ test.instance_eval { @framework.stub!(:tests).and_return(['something', 'nothing']) }
+ end
+ end
task('test:something').invoke
['foo', 'foo:bar'].map { |name| project(name) }.each do |project|
- project.test.include?('something').should be_true
- project.test.include?('nothing').should be_false
- project.test.include?('SomeTest').should be_false
+ project.test.tests.should include('something')
+ project.test.tests.should_not include('nothing')
end
end
it 'should apply *name* pattern' do
- define 'foo'
+ define 'foo' do
+ test.using(:junit)
+ test.instance_eval { @framework.stub!(:tests).and_return(['prefix-something-suffix']) }
+ end
task('test:something').invoke
- project('foo').test.include?('prefix-something-suffix').should be_true
- project('foo').test.include?('prefix-nothing-suffix').should be_false
+ project('foo').test.tests.should include('prefix-something-suffix')
end
it 'should not apply *name* pattern if asterisks used' do
- define 'foo'
+ define 'foo' do
+ test.using(:junit)
+ test.instance_eval { @framework.stub!(:tests).and_return(['prefix-something', 'prefix-something-suffix']) }
+ end
task('test:*something').invoke
- project('foo').test.include?('prefix-something').should be_true
- project('foo').test.include?('prefix-something-suffix').should be_false
+ project('foo').test.tests.should include('prefix-something')
+ project('foo').test.tests.should_not include('prefix-something-suffix')
end
it 'should accept multiple tasks separated by commas' do
- define 'foo'
+ define 'foo' do
+ test.using(:junit)
+ test.instance_eval { @framework.stub!(:tests).and_return(['foo', 'bar', 'baz']) }
+ end
task('test:foo,bar').invoke
- project('foo').test.include?('foo').should be_true
- project('foo').test.include?('bar').should be_true
- project('foo').test.include?('baz').should be_false
+ project('foo').test.tests.should include('foo')
+ project('foo').test.tests.should include('bar')
+ project('foo').test.tests.should_not include('baz')
end
it 'should execute only the named tasts' do
@@ -727,11 +745,11 @@
it 'should run test actions marked for integration' do
task 'action'
define 'foo' do
- test.using :integration
- test { task('action').invoke }
+ test.using :integration, :junit
end
- lambda { task('test').invoke }.should run_tasks().but_not('action')
- lambda { task('integration').invoke }.should run_task('action')
+ lambda { task('test').invoke }.should_not change { project('foo').test.passed_tests }
+ lambda { task('integration').invoke }.should change { project('foo').test.passed_tests }
+ project('foo').test.passed_tests.should be_empty
end
it 'should not fail if test=all' do
@@ -772,43 +790,58 @@
describe 'integration rule' do
- before do
+ it 'should execute integration tests on local project' do
define 'foo' do
- test.using :integration
+ test.using :junit, :integration
define 'bar'
end
- end
-
- it 'should execute integration tests on local project' do
lambda { task('integration:something').invoke }.should run_task('foo:test')
end
it 'should reset tasks to specific pattern' do
+ define 'foo' do
+ test.using :junit, :integration
+ test.instance_eval { @framework.stub!(:tests).and_return(['something', 'nothing']) }
+ define 'bar' do
+ test.using :junit, :integration
+ test.instance_eval { @framework.stub!(:tests).and_return(['something', 'nothing']) }
+ end
+ end
task('integration:something').invoke
['foo', 'foo:bar'].map { |name| project(name) }.each do |project|
- project.test.include?('something').should be_true
- project.test.include?('nothing').should be_false
- project.test.include?('SomeTest').should be_false
+ project.test.tests.should include('something')
+ project.test.tests.should_not include('nothing')
end
end
it 'should apply *name* pattern' do
+ define 'foo' do
+ test.using :junit, :integration
+ test.instance_eval { @framework.stub!(:tests).and_return(['prefix-something-suffix']) }
+ end
task('integration:something').invoke
- project('foo').test.include?('prefix-something-suffix').should be_true
- project('foo').test.include?('prefix-nothing-suffix').should be_false
+ project('foo').test.tests.should include('prefix-something-suffix')
end
it 'should not apply *name* pattern if asterisks used' do
+ define 'foo' do
+ test.using :junit, :integration
+ test.instance_eval { @framework.stub!(:tests).and_return(['prefix-something', 'prefix-something-suffix']) }
+ end
task('integration:*something').invoke
- project('foo').test.include?('prefix-something').should be_true
- project('foo').test.include?('prefix-something-suffix').should be_false
+ project('foo').test.tests.should include('prefix-something')
+ project('foo').test.tests.should_not include('prefix-something-suffix')
end
it 'should accept multiple tasks separated by commas' do
+ define 'foo' do
+ test.using :junit, :integration
+ test.instance_eval { @framework.stub!(:tests).and_return(['foo', 'bar', 'baz']) }
+ end
task('integration:foo,bar').invoke
- project('foo').test.include?('foo').should be_true
- project('foo').test.include?('bar').should be_true
- project('foo').test.include?('baz').should be_false
+ project('foo').test.tests.should include('foo')
+ project('foo').test.tests.should include('bar')
+ project('foo').test.tests.should_not include('baz')
end
it 'should execute only the named tasts' do