klubi
klubi

Reputation: 1523

TestNG Listener equivalent for @BeforeClass, with access to context

I've spent several days looking for a way to move one of my @BeforeClass methods to listener class I can reference in xml where I define content os test suite.

Problem I'm facing is that I'm using Spring for DI, and in @BeforeClass method I add some attributes to testng context, so I can use them in other places (other listeners).

I tried using onStart(final ITestContext context) from ITestListener. But that method seems to be invoked before spring manages to create beans, and I cannot perform my operations, because all my beans are nulls.

I tried using onBeforeClass(ITestClass testClass) from IClassListener. But that method only provides ITestClass, which does not give me access to context, so I can't set my attributes.

Now I'm experimenting with onConfigurationSuccess(final ITestResult itr) from IConfigurationListener, but that requires using if statement to run my code only if configuration method name is equal to springTestContextPrepareTestInstance.

Does anyone know a better way of doing this?

[EDIT] code sample

@Component
public class CleanupHelper {

  private static SomeBean someBean;

  @Autowired
  public CleanupHelper(SomeBean someBean){
    CleanupHelper.someBean = someBean;
  }

  public static Object getSomething(){
    return someBean.getSomething();
  }
}
public class ExcludedGroupsListener implements IConfigurationListener {

    @Override
    public void onConfigurationSuccess(final ITestResult itr) {
        if (itr.getName().contains("springTestContextPrepareTestInstance")) {
            var something = CleanupHelper.getSomething();
            if (something != null && someOtherCondition) {

                itr.setAttribute("someObject", something);
            }
        }
    }
}

@ContextConfiguration(classes = TestConfig.class)
public class SomeTests extends AbstractTestNGSpringContextTests {

  @Test
  public void someTest(){
    // doSomething
  }

}
@Configuration
@ComponentScan(basePackages = "com.some",
        excludeFilters = @Filter(type = FilterType.REGEX, pattern = "com.some.else..*"))
public class TestConfig {
}

Above code works... unfortunately onConfigurationSuccess method is invoked after each configuration method.

Upvotes: 3

Views: 1546

Answers (1)

Rodrigo Vaamonde
Rodrigo Vaamonde

Reputation: 503

Try with Annotation Transformers.

You can add it in your testng.xml like any other listener.

And in there you can do things like:

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class TestAnnotationTransformer implements IAnnotationTransformer {

    @SuppressWarnings("rawtypes")
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {

        if (testMethod.getName().equals("MyTest1"))
            annotation.setGroups( new String[] {"GroupA" });

        if(ignoreTestDependencies)
            annotation.setIgnoreMissingDependencies(true);

    }

}

Just an example, but you have many things there to play with.

Just bear in mind that, as I stated in the comments, this runs before runtime, so you won't be able to change things on the go like you would do with a normal listener.

Upvotes: 0

Related Questions