2

We have a separate Java project completely dedicated to functional testing of our web application with TestNG and Selenium (we refer to it as the Test Suite). It is pretty sophisticated and uses Spring for dependency injection extensively.

The entry point, where Application context is initialized and the beans used to initialize other beans are defined, is the AbstractTest class, which is a base class for all test classes in the suite, and is declared like this:

@ContextConfiguration("classpath*:applicationContext*.xml")
public class AbstractTest extends AbstractTestNGSpringContextTests {
    ...

Now I need to add two listeners:

  • public class CustomSuiteListener implements ISuiteListener — to perform some actions before our tests run (e.g. log in to the web application and set it up via Web UI), and
  • public class CustomTestMethodInterceptor implements IMethodInterceptor — to filter away those methods that should not run this time based on external decision mechanism (e.g. known open bugs).

Both these listeners require to load the application context because all settings (web application URL, credentials, database etc) are declared there; also bean autowiring would be of much help there.

For now, in both listeners I have to explicitly create a new application context in this fashion:

public class CustomSuiteListener implements ISuiteListener {

    @Override
    public void onStart(ISuite suite) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
        WebDriverProvider provider = (WebDriverProvider) applicationContext.getBean("webDriverProvider");
        ObjectInitializer objectInitializer = (ObjectInitializer) applicationContext.getBean("objectInitializer");
        // other beans...

The problem is that, in addition to application context init in AbstractTest, every such call results in application context being loaded again and again; given that the suite is already big and is promising to grow fast, this results in a huge time waste.

The question is: is there any way to initialize application context once and then use it universally within our Test Suite?

Actine
  • 2,867
  • 2
  • 25
  • 38

2 Answers2

1

Spring-test provides some annotation that do what you need. I used it with Junit, but I am almost sure it works in the same way with testNg. Here an example:

@ContextConfiguration("classpath:pu-testContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)

By default, the context is in a cache and it can be reused between two tests. If you have a side effect, you have to change the value of "dirtiesContext" as I did above.

mcoolive
  • 3,805
  • 1
  • 27
  • 32
0

Why not place the the applicationcontext in the setup method of your test and reference it from there. An example would be like this in Junit

Blockquote

ApplicaitonContext ctx;
setup()
 {
ctx = new Class...
}
user1230731
  • 55
  • 1
  • 6
  • Did not quite understand the idea, or how it is relevant to the question. – Actine Jul 27 '14 at 21:28
  • The the testing framework is initialized with the setup method, you will only call new (instantiate) one context of contexts. The default scope is already singleton to it initializes one object per class at runtime. – user1230731 Jul 27 '14 at 22:14