News

  • 2013-07-03 - Version 1.0-beta-6 has been released.
    - Return-values from parameterized-callback methods are no longer always default values. There is now basic intuitional support for return-values with an extra twist in the new fold support, which - as an intentional side-effect - enables callback-parameterization of JUnit Rules!
    - Bugfix to ensure proper information from CallbackControlPanel#getLatestCallbackResults when there are nested callback method invocations at play
  • 2013-05-02 - Version 1.0-beta-5 has been released.
    - Fix to preserve integration with version 3.2.x of Spring Framework
    - API interface CallbackControlPanel was moved to the new package org.callbackparams.ext.
    An alias is still available in the original package to preserve some backward compatibility (that will soon be broken, however).
    - New API interface Wrapping, around which the mechanism for implicit and default implementations of callback-interfaces will be built.
    The first part of this mechanism is now available - and it should be quite useful for third-party framework developers that want to offer their framework users some annotation-based API for (callback-)parameterized testing.
  • 2011-11-15 - Version 1.0-beta-4 has been released.
    - Support for traditional parameterization and API-modifications to clearly point out the type of parameterization. There are now two different annotations for specifying how a field is to be parameterized:
    @ParameterizedValue specifies traditional parameterization for a boolean or enum field
    @ParameterizedCallback replaces @CallbackField to specify a callback-injected field (of interface type)
    - Fixes that improve Powermock-integration
    - Fixes for some classloading-related issues
    - Fix for combine issues that relate to combined values that occur more than once
  • 2011-03-19 - Version 1.0-beta-3 has been released.
    Fixes for BddRunner so that its functionality now better matches the documented behavior.
  • 2011-02-06 - Version 1.0-beta-2 has been released.
    The most noticeable change is that some deprecated JUnit-4 API has been removed and the remaining API has undergone a few feature and documentation improvements.
  • 2011-01-25 - The beta-1 release of CallbackParams is now available at Maven Central:
    - groupId: org.callbackparams
    - artifactId: callbackparams
    - version: 1.0-beta-1
    See Maven Setup below for more information!
  • 2011-01-16 - The initial release callbackparams-1.0-beta-1 is now available at SourceForge.
    Keep in mind that the mandatory dependencies to JUnit and BCEL are not part of this download!

What Is This?

CallbackParams is a JUnit add-on that offers elegant and maintainable patterns for parameterized testing. It was originally intended as a mean to quickly reach reasonable test-coverage for untested legacy code.
It is completly non-intrusive on build-processes, thanks to its seamless integration with JUnit (as well as several 3rd-Party add-ons). - I.e. if an IDE or build-configuration can run JUnit then CallbackParams can also be used.

Tutorial Articles

The ways of CallbackParams are best learned through this article series:

  1. Patterns That Simplify Maintenance

    Explains the easy-to-maintain parameterization patterns of CallbackParams by comparing them to those of traditional test parameterization.

  2. Validation of Validation Failures

    Shows how some of the CallbackParams features can be particularly useful when testing behaviour that is outside of the application's happy-path - e.g. when testing validation and failure behaviour. Among other stuff this article includes an example on how to test Struts2 validation.

Key Features

On top of being yet-another-parameterized-testing-framework CallbackParams separates itself with at least three defining features ...

- Automated Combining of Parameter-Values -

The framework takes care of combining the parameter-values. This might look like a cheap way to generate many tests with little code but as can be seen here and here the great advantage is the improved maintainability that is released when the burden of combining parameter-values is eliminated.

- Callback Parameterization -

The combined parameter-values can be accessed through a callback-interface by invoking any of its callback-methods. An invocation of a callback-method works as a composite invocation on all of the testrun's parameter-values that offer an implementation of the corresponding callback-interface.

More pedagogic examples on how this actually works can be found in the tutorial article Patterns That Simplify Maintenance.

(From version 1.0-beta-4 the field-annotation @ParameterizedValue can be used to achieve traditional parameterization, with explicit references to individual parameter-values.)

- Seamless Integration with JUnit Add-Ons from 3rd Party -

The preferred way to run CallbackParams tests is to annotate the test-class:

import org.callbackparams.junit4.CallbackParamsRunner
import org.junit.runner.RunWith

@RunWith(CallbackParamsRunner.class)
public class MyParameterizedTest {

CallbackParamsRunner is an implementation of Runner, which is implemented by many other JUnit Add-Ons out there. Almost all of these runners assume you choose between different ~end-to-end~ runners for your test, i.e. a test can be run with prominent runners such as PowerMockRunner or SpringJUnit4ClassRunner - but not both at the same time!!!

But CallbackParamsRunner does only concern itself with test-parameterization and leaves the actual test-execution to some other suitable runner, which can be explicitly specified with the annotation @WrappedRunner:

@RunWith(CallbackParamsRunner.class)
@WrappedRunner(PowerMockRunner.class)
public class MyParameterizedPowerMockTest {

... or ...

@RunWith(CallbackParamsRunner.class)
@WrappedRunner(SpringJUnit4ClassRunner.class)
public class MyParameterizedSpringTest {

This approach to test-parameterization can be described in terms of AOP. JUnit's annotation @RunWith exposes a pointcut. The class CallbackParamsRunner acts as an advice for this pointcut by making the necessary modifications to the test-class and then delegates test-execution back to JUnit's built-in Runner implementation or to the specified third-party implementation, which in turn can be regarded as the next advice for the pointcut.

More on this feature can be found here.

Requirements

Dependencies

  • BCEL version 5.2 - http://commons.apache.org/proper/commons-bcel/

    BCEL (Byte Code Engineering Library) is internally used by CallbackParams to make byte-code modifications on test-related classes. - Most of the CallbackParams functionality is partly enforced through byte-code modifications.

  • JUnit http://junit.org

    JUnit-3.8.x or later is supported but JUnit-4.x is strongly recommended, because CallbackParams' most powerful APIs (e.g. CallbackParamsRunner and @WrappedRunner) demand it. - Keep in mind that JUnit-4.x is backward-compatible, i.e. it supports the JUnit-3.8.x API as well so (unless stuck with Java-1.4) there is no reason for not upgrading!

JDK version 1.5 (or later) is recommended

JDK-1.5 (Java5) or later is strongly recommended.
However, if your test-classes can be compiled under JDK-1.4 then CallbackParams will work fine since all of its non-tiger internals are compiled to JVM-1.4 byte-code. But this does of course also mean JUnit-3.8.x and no support for neither annotations nor enums.
The limited JDK-1.4 support has been preserved because CallbackParams was originally intended as a mean to quickly reach reasonable test-coverage for untested legacy-code - and several of the legacy systems out there still use JDK-1.4.

Get It!

Download from Sourceforge project site

CallbackParams can be downloaded from the Sourceforge project site:

http://sourceforge.net/projects/callbackparams/files

Keep in mind that the mandatory dependencies to JUnit and BCEL must be downloaded separately.

Maven Setup

These dependencies need to be added to your pom.xml:

    <dependency>
      <groupId>org.callbackparams</groupId>
      <artifactId>callbackparams</artifactId>
      <version>1.0-beta-6</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

CallbackParams has a mandatory dependency to BCEL, which jar will be included as a transitive dependency. The JUnit-dependency is specified as an optional dependency, which forces the developer to explicitly define which JUnit-version to use. (In practice, CallbackParams works with almost any version of JUnit.)