Description
Scope of Change
This will extend the unittest API by adding a facility for providing values to a test.
Rationale
This will make it easier to discover problems in tests written using foreach
loops currently, and at the same time reduce the amount of code that needs to be written for tests with separate test methods for every value.
Functionality
Parameterized test case methods can be annotated with a @values
annotation.
Value sources
Inline
The values are taken from the annotation itself, as an array:
#[@test, @values(array(1, 2, 3))]
public function fixture($value) {
}
Locally sourced
The values are returned from a public instance method inside the current class
public function values() {
return array(1, 2, 3);
}
#[@test, @values('values')]
public function fixture($value) {
}
Outsourced
The values are returned from a public static method inside a class specified by a double-colon notation.
class ValueProvider extends Object {
public static function values() {
return array(1, 2, 3);
}
}
#[@test, @values('ValueProvider::values')]
public function fixture($value) {
}
Method sources - arguments
For the values sourced to methods, additional arguments may be provided by using the named annotation form. The source method is then invoked with the given arguments. If the args
key is omitted, the method is invoked without any arguments (and may thus use their defaults):
public function range($lo= 1, $hi= 3) {
return range($lo, $hi);
}
#[@test, @values(source= 'range', args= array(1, 10))]
public function fixture($value) {
}
Example 1: Refactoring multiple tests
This example collapses two separate methods into using the inline value source.
Before
/**
* Test name[=...
*
*/
#[@test, @expect('lang.FormatException')]
public function unbalanced_opening_bracket_in_key() {
$this->fixture->deserialize($this->input('name[=...'), Type::$VAR);
}
/**
* Test name]=...
*
*/
#[@test, @expect('lang.FormatException')]
public function unbalanced_closing_bracket_in_key() {
$this->fixture->deserialize($this->input('name]=...'), Type::$VAR);
}
After
/**
* Test unbalanced brackets such as "name[=..." and "name]=..." raise exceptions.
*
*/
#[@test, @expect('lang.FormatException'), @values(array('name[=...', 'name]=...'))]
public function unbalanced_bracket_in_key($key) {
$this->fixture->deserialize($this->input($key), Type::$VAR);
}
Security considerations
n/a
Speed impact
Negligible
Dependencies
n/a
Related documents
- http://nunit.org/index.php?p=parameterizedTests&r=2.5 - Parameterized Tests
- http://nunit.org/index.php?p=values&r=2.5 - ValuesAttribute (NUnit 2.5)
- http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers - Data Providers
- http://junit.sourceforge.net/javadoc/org/junit/runners/Parameterized.html - Class Parameterized
- http://css.dzone.com/books/practical-php-testing/practical-php-testing-patterns-46 - Practical PHP Testing Patterns: Parameterized Test