class Buildr::TestTask

The test task controls the entire test lifecycle.

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 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.

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

Attributes

dependencies[RW]

The dependencies used for running the tests. Includes the compiled files (compile.target) and their dependencies. Will also include anything you pass to with, shared between the testing compile and run dependencies.

failed_tests[R]

After running the task, returns all the tests that failed, empty array if all tests passed.

forced_need[RW]

Whether the tests are forced

options[R]

Returns various test options.

passed_tests[R]

After running the task, returns all the tests that passed, empty array if no tests passed.

project[R]

The project this task belongs to.

tests[R]

After running the task, returns all tests selected to run, based on availability and include/exclude pattern.

Public Class Methods

clear() click to toggle source

Used by the test/integration rule to clear all previously included/excluded tests.

# File lib/buildr/core/test.rb, line 182
def clear()
  Project.projects.each do |project|
    project.test.send :clear
  end
end
exclude(excludes) click to toggle source

Used by the test/integration to exclude specific tests

# File lib/buildr/core/test.rb, line 198
def exclude(excludes)
  excludes = wildcardify(Array(excludes))
  Project.projects.each do |project|
    project.test.send :exclude, *excludes if excludes.size > 0
    project.test.send :forced_need=, true
  end
end
include(includes) click to toggle source

Used by the test/integration to include specific tests

# File lib/buildr/core/test.rb, line 189
def include(includes)
  includes = wildcardify(Array(includes))
  Project.projects.each do |project|
    project.test.send :include, *includes if includes.size > 0
    project.test.send :forced_need=, true
  end
end

Public Instance Methods

classes() click to toggle source

Deprecated: Use tests instead.

# File lib/buildr/core/test.rb, line 403
def classes
  Buildr.application.deprecated 'Call tests instead of classes'
  tests
end
classpath() click to toggle source

Deprecated: Use dependencies instead.

# File lib/buildr/core/test.rb, line 246
def classpath
  Buildr.application.deprecated 'Use dependencies instead.'
  @dependencies
end
classpath=(artifacts) click to toggle source

Deprecated: Use dependencies= instead.

# File lib/buildr/core/test.rb, line 252
def classpath=(artifacts)
  Buildr.application.deprecated 'Use dependencies= instead.'
  @dependencies = artifacts
end
clear() click to toggle source

Clear all test includes and excludes and returns self

# File lib/buildr/core/test.rb, line 396
def clear
  @include = []
  @exclude = []
  self
end
compile(*sources) → CompileTask click to toggle source
compile(*sources) { |task| .. } → CompileTask

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 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 tests. You can do so by calling with on the test task. The dependencies used here are also copied over to the junit task.

# File lib/buildr/core/test.rb, line 284
def compile(*sources, &block)
  @project.task('test:compile').from(sources).enhance &block
end
default_options() click to toggle source

Default options already set on each test task.

# File lib/buildr/core/test.rb, line 214
def default_options
  { :fail_on_failure=>true, :fork=>:once, :properties=>{}, :environment=>{} }
end
exclude(*names) → self click to toggle source

Exclude the specified tests. This method accepts multiple arguments and returns self. See include for the type of arguments you can use.

# File lib/buildr/core/test.rb, line 390
def exclude(*names)
  @exclude += names
  self
end
failures_to → file click to toggle source

We record the list of failed tests for the current framework in this file.

# File lib/buildr/core/test.rb, line 448
def failures_to
  @failures_to ||= file(@project.path_to(:target, "#{framework}-failed")=>self)
end
framework → symbol click to toggle source

Returns the test framework, e.g. :junit, :testng.

# File lib/buildr/core/test.rb, line 419
def framework
  unless @framework
    # Start with all frameworks that apply (e.g. JUnit and TestNG for Java),
    # and pick the first (default) one, unless already specified in parent project.
    candidates = TestFramework.frameworks.select { |cls| cls.applies_to?(@project) }
    candidate = @project.parent && candidates.detect { |framework| framework.to_sym == @project.parent.test.framework } ||
      candidates.first
    self.framework = candidate if candidate
  end
  @framework && @framework.class.to_sym
end
include(*names) → self click to toggle source

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
# File lib/buildr/core/test.rb, line 380
def include(*names)
  @include += names
  self
end
last_failures → array click to toggle source

We read the last test failures if any and return them.

# File lib/buildr/core/test.rb, line 457
def last_failures
  @last_failures ||= failures_to.exist? ? File.read(failures_to.to_s).split("\n") : []
end
report_to → file click to toggle source

Test frameworks that can produce reports, will write them to this directory.

This is framework dependent, so unless you use the default test framework, call this method after setting the test framework.

# File lib/buildr/core/test.rb, line 438
def report_to
  @report_to ||= file(@project.path_to(:reports, framework)=>self)
end
resources(*prereqs) → ResourcesTask click to toggle source
resources(*prereqs) { |task| .. } → ResourcesTask

Executes by the compile task to copy resource files over. See Buildr::Compile#resources.

# File lib/buildr/core/test.rb, line 293
def resources(*prereqs, &block)
  @project.task('test:resources').enhance prereqs, &block
end
setup(*prereqs) → task click to toggle source
setup(*prereqs) { |task| .. } → task

Returns the setup task. The setup task is executed at the beginning of the test task, after compiling the test files.

# File lib/buildr/core/test.rb, line 303
def setup(*prereqs, &block)
  @project.task('test:setup').enhance prereqs, &block
end
teardown(*prereqs) → task click to toggle source
teardown(*prereqs) { |task| .. } → task

Returns the teardown task. The teardown task is executed at the end of the test task.

# File lib/buildr/core/test.rb, line 312
def teardown(*prereqs, &block)
  @project.task('test:teardown').enhance prereqs, &block
end
using(options) → self click to toggle source

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.
# File lib/buildr/core/test.rb, line 352
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)
      self.framework = name
    elsif name == :integration
      options[:integration] = true
    else
      Buildr.application.deprecated "Please replace with using(:#{name}=>true)"
      options[name.to_sym] = true
    end
  end
  self
end
with(*specs) → self click to toggle source

Specify artifacts (specs, tasks, files, etc) to include in the dependencies list when compiling and running tests.

# File lib/buildr/core/test.rb, line 321
def with(*artifacts)
  @dependencies |= Buildr.artifacts(artifacts.flatten).uniq
  compile.with artifacts
  self
end

Protected Instance Methods

associate_with(project) click to toggle source
# File lib/buildr/core/test.rb, line 479
def associate_with(project)
  @project = project
end
framework=(name) click to toggle source
# File lib/buildr/core/test.rb, line 483
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(self, options)
  # Test framework dependency.
  with @framework.dependencies
end
include?(name) → boolean click to toggle source

Returns true if the specified test name matches the inclusion/exclusion pattern. Used to determine which tests to execute.

# File lib/buildr/core/test.rb, line 497
def include?(name)
  ((@include.empty? && !@forced_need)|| @include.any? { |pattern| File.fnmatch(pattern, name) }) &&
    !@exclude.any? { |pattern| File.fnmatch(pattern, name) }
end
only_run(tests) click to toggle source

Limit running tests to specific list.

# File lib/buildr/core/test.rb, line 538
def only_run(tests)
  @include = Array(tests)
  @exclude.clear
  @forced_need = true
end
only_run_failed() click to toggle source

Limit running tests to those who failed the last time.

# File lib/buildr/core/test.rb, line 545
def only_run_failed()
  @include = Array(last_failures)
  @forced_need = true
end
run_tests() click to toggle source

Runs the tests using the selected test framework.

# File lib/buildr/core/test.rb, line 503
def run_tests
  dependencies = (Buildr.artifacts(self.dependencies + compile.dependencies) + [compile.target]).map(&:to_s).uniq
  rm_rf report_to.to_s
  rm_rf failures_to.to_s
  @tests = @framework.tests(dependencies).select { |test| include?(test) }.sort
  if @tests.empty?
    @passed_tests, @failed_tests = [], []
  else
    info "Running tests in #{@project.name}"
    begin
      # set the baseDir system property if not set
      @framework.options[:properties] = { 'baseDir' => compile.target.to_s }.merge(@framework.options[:properties] || {})
      @passed_tests = @framework.run(@tests, dependencies)
    rescue Exception=>ex
      error "Test framework error: #{ex.message}"
      error ex.backtrace.join("\n") if trace?
      @passed_tests = []
    end
    @failed_tests = @tests - @passed_tests
    unless @failed_tests.empty?
      Buildr::write(failures_to.to_s, @failed_tests.join("\n"))
      error "The following tests failed:\n#{@failed_tests.join("\n")}"
      fail 'Tests failed!'
    end
  end
  record_successful_run unless @forced_need
end