Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not instantiate TestExecutionListener

When I run my selenium test below from within Eclipse, I get a series of Could not instantiate TestExecutionListener messages in my log.

This is the actual test.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SeleniumConfig.class)
public final class TestWebpage {
   private static final Logger LOG = Logger.getLogger(TestWebpage.class);

   @Autowired
   private WebDriver driver;

   @Test
   public void testLoadingPage() {
      LOG.debug("Hello World!");
   }
}

And this is the log

0    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
5    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
6    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
7    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
8    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Using TestExecutionListeners: [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@152c95a3, org.springframework.test.context.support.DirtiesContextTestExecutionListener@22140b31]
127  [main] INFO  org.springframework.context.support.GenericApplicationContext  - Refreshing org.springframework.context.support.GenericApplicationContext@35523de0: startup date [Wed Oct 01 01:20:22 EST 2014]; root of context hierarchy
3961 [main] DEBUG org.rmb.selenium.external.TestWebpage  - Hello World!
3963 [Thread-8] INFO  org.springframework.context.support.GenericApplicationContext  - Closing org.springframework.context.support.GenericApplicationContext@35523de0: startup date [Wed Oct 01 01:20:22 EST 2014]; root of context hierarchy

Note that I am using Spring 4.1.0.RELEASE.

One Solution, three Extra Dependencies

I noticed in the answer to a previous question the suggestion to add @WebAppConfiguration

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SeleniumConfig.class)
@WebAppConfiguration
public final class TestWebpage {

Which I then needed three extra dependencies in my pom.xml to support:

javax.servlet-api
spring-jdbc
spring-web

Why do I need all this extra when I am not actually using JDBC at all, or anything using spring-web/servlet - this is just a selenium test with some of my own configuration.

Is there an easier way? Am I missing something bigger?

Config Class

This is the class I configure my tests with.

public final class SeleniumConfig {

   @Bean
   public String baseUrl() {
      return "http://localhost:8888/";
   }

   @Bean
   public WebDriver driver() {
      return new CloseableFirefoxDriver();
   }

   class CloseableFirefoxDriver extends FirefoxDriver implements DisposableBean {
      public void destroy() throws Exception {
         quit();
      }
   }
}

POM

My pom.xml (before I added the extra dependencies).

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>WebAppWithSeleniumTest</groupId>
   <artifactId>WebAppWithSeleniumTest</artifactId>
   <packaging>war</packaging>
   <version>0.0.1-SNAPSHOT</version>
   <name>WebAppWithSeleniumTest Maven Webapp</name>
   <url>http://maven.apache.org</url>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.11</version>
      </dependency>
      <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
         <version>1.2.16</version>
      </dependency>
      <dependency>
         <groupId>org.seleniumhq.selenium</groupId>
         <artifactId>selenium-java</artifactId>
         <version>2.43.1</version>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-test</artifactId>
         <version>${spring.version}</version>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${spring.version}</version>
      </dependency>
   </dependencies>
   <build>
      <finalName>WebAppWithSeleniumTest</finalName>
      <resources>
         <resource>
            <directory>src/main/resources</directory>
            <targetPath>${basedir}/target/classes</targetPath>
            <includes>
               <include>log4j.properties</include>
            </includes>
         </resource>
      </resources>
   </build>
   <description>Web App with Selenium Tests - a base</description>
   <properties>
      <spring.version>4.1.0.RELEASE</spring.version>
   </properties>
</project>
like image 640
Robert Mark Bram Avatar asked Sep 30 '14 15:09

Robert Mark Bram


2 Answers

If I leave in the three extra dependencies

javax.servlet-api
spring-jdbc
spring-web

I can leave my test class defined as this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SeleniumConfig.class)
public final class TestWebpage {

and I will get this logging:

0    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
20   [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@3997ebf6, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@25048104, org.springframework.test.context.support.DirtiesContextTestExecutionListener@4ab24098, org.springframework.test.context.transaction.TransactionalTestExecutionListener@7caee177, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@3d548b94]
132  [main] INFO  org.springframework.context.support.GenericApplicationContext  - Refreshing org.springframework.context.support.GenericApplicationContext@6f55137: startup date [Wed Oct 01 21:55:02 EST 2014]; root of context hierarchy
4183 [main] DEBUG org.rmb.selenium.external.TestWebpage  - Hello World!
4186 [Thread-8] INFO  org.springframework.context.support.GenericApplicationContext  - Closing org.springframework.context.support.GenericApplicationContext@6f55137: startup date [Wed Oct 01 21:55:02 EST 2014]; root of context hierarchy

No errors, but obviously Spring is doing a fair bit of work in the background.

Alternatively, I can remove the three extra dependencies and add this minimal @TestExecutionListeners annotation.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SeleniumConfig.class)
@TestExecutionListeners(listeners = {DependencyInjectionTestExecutionListener.class})
public final class TestWebpage {

I get logging as below:

0    [main] INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper  - Using TestExecutionListeners: [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@4fce6eaf]
117  [main] INFO  org.springframework.context.support.GenericApplicationContext  - Refreshing org.springframework.context.support.GenericApplicationContext@42695958: startup date [Wed Oct 01 21:59:05 EST 2014]; root of context hierarchy
4189 [main] DEBUG org.rmb.selenium.external.TestWebpage  - Hello World!
4190 [Thread-8] INFO  org.springframework.context.support.GenericApplicationContext  - Closing org.springframework.context.support.GenericApplicationContext@42695958: startup date [Wed Oct 01 21:59:05 EST 2014]; root of context hierarchy

At least no errors.

As to why I need any of this, I don't understand yet. I am leaving this here as a reference, at the very least to show the minimal changes required to get rid of the Could not instantiate TestExecutionListener messages.

like image 103
Robert Mark Bram Avatar answered Sep 29 '22 20:09

Robert Mark Bram


To stay close to the original Spring implementation, use this instead:

@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class })

as defined in org.springframework.test.context.TestContextManager:

    private static final String[] DEFAULT_TEST_EXECUTION_LISTENER_CLASS_NAMES = new String[] {
        "org.springframework.test.context.web.ServletTestExecutionListener",
        "org.springframework.test.context.support.DependencyInjectionTestExecutionListener",
        "org.springframework.test.context.support.DirtiesContextTestExecutionListener",
        "org.springframework.test.context.transaction.TransactionalTestExecutionListener" };

Only ServletTestExecutionListener should be evicted.

like image 37
Jean-Christophe Avatar answered Sep 29 '22 21:09

Jean-Christophe