Skip to content

Create annotation to group tests [SPR-3653] #8334

Closed
@spring-projects-issues

Description

@spring-projects-issues

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:

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions