Description
Magnus Heino opened SPR-3653 and commented
The only thing I miss comparing in JUnit comparing with TestNG is the ability to group tests using annotations.
org.springframework.test.ConditionalTestCase makes it possible for subclasses to override isDisabledInThisEnvironment(String testMethodName) and in that method, looking at the test method name, decide if the test should run or not.
Add a annotation like this:
package org.springframework.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value=ElementType.METHOD)
@Retention(value=RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Environment {
String[] value();
}
Add this method to ConditionalTestCase
/**
* Should this test run?
* @param environment name of the test method environment
* @return whether the test should execute in the provided envionment
*/
protected boolean isDisabledInEnvironment(String environment) {
return false;
}
and change ConditionalTestCase.runBase to this:
public void runBare() throws Throwable {
Method runMethod = getClass().getMethod(getName(), (Class[])null);
boolean disabledInEnvironment = false;
if(runMethod.isAnnotationPresent(Environment.class)) {
String[] environments = runMethod.getAnnotation(Environment.class).value();
for (int i = 0; i < environments.length; i++) {
if(isDisabledInEnvironment(environments[i])) {
disabledInEnvironment = true;
}
}
}
// getName will return the name of the method being run
if (disabledInEnvironment || isDisabledInThisEnvironment(getName())) {
recordDisabled();
logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: " +
"Total disabled tests=" + getDisabledTestCount());
return;
}
// Let JUnit handle execution
super.runBare();
}
Then it's possible to annotate each test method with what environment it should run in. Applications can create own baseclasses of the spring Abstract* test classes and override isDisabledInEnvironment(String environment) . In there, a decision is made based on the environment that the method is annotated with.
Example:
public class AppTest extends ConditionalTestCase {
private final Log log = LogFactory.getLog(this.getClass());
@Environment({"database", "slow"})
public void testDatabaseSlow() {
log.debug("NO");
}
@Environment({"slow"})
public void testSlow() {
log.debug("YES");
}
@Environment({"database"})
public void testDatabase() {
log.debug("NO");
}
public void testNoAnnotation() {
log.debug("YES");
}
@Environment({})
public void testEmptyArray() {
log.debug("YES");
}
@Override
protected boolean isDisabledInEnvironment(String environment) {
if(environment.equalsIgnoreCase("database")) {
return true;
}
return false;
}
}
In a real scenario the isDisabledInEnvironment is moved to a application specific testcasebaseclass that inherits ConditionalTestCase, and this example class inherits from that new testcasebaseclass instead.
/Magnus
Issue Links:
- Introduce strategy for determining if a profile value is enabled for a particular test environment [SPR-4862] #9538 Introduce strategy for determining if a profile value is enabled for a particular test environment
- Allow multiple values be specified in the runtime for tests filtering by @IfProfileValue [SPR-5903] #10572 Allow multiple values be specified in the runtime for tests filtering by
@IfProfileValue