what unit test stands reports pom plugin for example does are java spring maven-2 surefire spring-test

java - unit - surefire reports are in



Las pruebas JUnit pasan en Eclipse pero fallan en Maven Surefire (16)

He escrito algunas pruebas de JUnit usando JUnit 4 y las bibliotecas de prueba de primavera. Cuando ejecuto las pruebas dentro de Eclipse, corro bien y paso. Pero cuando los ejecuto usando Maven (durante el proceso de compilación), fallan al dar un error relacionado con la primavera. No estoy seguro de qué está causando el problema, JUnit, Surefire o Spring. Aquí está mi código de prueba, la configuración del resorte y la excepción que recibo de Maven:

PersonServiceTest.java

package com.xyz.person.test; import static com.xyz.person.util.FjUtil.toFjList; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Transactional; import com.xyz.person.bo.Person; import com.xyz.person.bs.PersonService; import fj.Effect; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath*:personservice-test.xml" }) @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false) public class PersonServiceTest { @Autowired private PersonService service; @Test @Transactional public void testCreatePerson() { Person person = new Person(); person.setName("abhinav"); service.createPerson(person); assertNotNull(person.getId()); } @Test @Transactional public void testFindPersons() { Person person = new Person(); person.setName("abhinav"); service.createPerson(person); List<Person> persons = service.findPersons("abhinav"); toFjList(persons).foreach(new Effect<Person>() { public void e(final Person p) { assertEquals("abhinav", p.getName()); }}); } }

personservice-test.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <import resource="classpath:/personservice.xml" /> <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true"> <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="url" value="jdbc:derby:InMemoryDatabase;create=true" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="datasource" /> <property name="persistenceUnitName" value="PersonService" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect" /> <property name="showSql" value="true" /> <property name="generateDdl" value="true" /> </bean> </property> <property name="jpaPropertyMap"> <map> <entry key="hibernate.validator.autoregister_listeners" value="false" /> <entry key="javax.persistence.transactionType" value="RESOURCE_LOCAL" /> </map> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="dataSource" ref="datasource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" /> <bean id="beanMapper" class="org.dozer.DozerBeanMapper"> <property name="mappingFiles"> <list> <value>personservice-mappings.xml</value> </list> </property> </bean> </beans>

Excepción en Maven

------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.xyz.person.test.PersonServiceTest 23:18:51,250 WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01 23:18:51,281 WARN JDBCExceptionReporter:78 - Database ''InMemoryDatabase'' not created, connection made to existing database instead. 23:18:52,937 WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01 23:18:52,937 WARN JDBCExceptionReporter:78 - Database ''InMemoryDatabase'' not created, connection made to existing database instead. 23:18:52,953 WARN TestContextManager:429 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process ''after'' execution for test: method [public void com.xyz.person.test.PersonServiceTest.testCreatePerson()], instance [com.xyz.person.test.PersonServiceTest@1bc81bc8], exception [org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.] java.lang.IllegalStateException: No value for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3f563f56] bound to thread [main] at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199) at org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion(JpaTransactionManager.java:489) at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183) at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:426) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102) at org.apache.maven.surefire.Surefire.run(Surefire.java:180) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:599) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021) 23:18:53,078 WARN TestContextManager:377 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process ''before'' execution of test method [public void com.xyz.person.test.PersonServiceTest.testFindPersons()] for test instance [com.xyz.person.test.PersonServiceTest@79f279f2] org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access. at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:304) at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371) at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162) at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102) at org.apache.maven.surefire.Surefire.run(Surefire.java:180) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:599) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021) Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 15.625 sec <<< FAILURE! Results : Tests in error: testCreatePerson(com.xyz.person.test.PersonServiceTest) testCreatePerson(com.xyz.person.test.PersonServiceTest) testFindPersons(com.xyz.person.test.PersonServiceTest) Tests run: 3, Failures: 0, Errors: 3, Skipped: 0


De repente experimenté este error, y la solución para mí fue deshabilitar para ejecutar pruebas en paralelo.

Su kilometraje puede variar, ya que podría reducir el número de pruebas fallidas configurando surefire para ejecutar pruebas paralelas por "clases":

<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.7.2</version> <configuration> <parallel>classes</parallel> <threadCount>10</threadCount> </configuration> </plugin>

Como escribí primero, esto no fue suficiente para mi suite de pruebas, por lo que desactivé completamente el paralelismo al eliminar la sección <configuration> .


El resultado de la ejecución de prueba diferente de JUnit run y de la maven install parece ser un síntoma de varios problemas.

Desactivar la ejecución de la prueba de reutilización de hilo también eliminó el síntoma en nuestro caso, pero la impresión de que el código no era seguro para subprocesos seguía siendo sólida.

En nuestro caso, la diferencia se debió a la presencia de un frijol que modificó el comportamiento de la prueba. Ejecutar solo la prueba JUnit resultaría bien, pero ejecutar el objetivo de install del proyecto resultaría en un caso de prueba fallido. Como era el caso de prueba en desarrollo, inmediatamente fue sospechoso.

Resultó que otro caso de prueba era la instanciación de un bean a través de Spring que sobreviviría hasta la ejecución del nuevo caso de prueba. La presencia de frijol estaba modificando el comportamiento de algunas clases y produciendo el resultado fallido.

La solución en nuestro caso fue deshacerse del frijol, que no era necesario en primer lugar (otro premio más de la pistola de copiar y pegar ).

Sugiero a todos los que tengan este síntoma que investiguen cuál es la causa raíz. La desactivación de la reutilización de hilo en la ejecución de la prueba solo puede ocultarlo.


Esto me ha ayudado a solucionar mi problema. Tuve un síntoma similar en que maven fallaría, sin embargo, ejecutar pruebas junit funciona bien.

Como resulta que mi padre pom.xml contiene la siguiente definición:

<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <forkMode>pertest</forkMode> <argLine>-Xverify:none</argLine> </configuration> </plugin>

Y en mi proyecto lo anulo para eliminar el argLine:

<plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <forkMode>pertest</forkMode> <argLine combine.self="override"></argLine> </configuration> </plugin>

Con suerte, esto ayudará a alguien a solucionar el problema del plugin de surefire.


Esto no se aplica exactamente a su situación, pero tuve el mismo problema: las pruebas que pasarían en Eclipse fallaron cuando se ejecutó el objetivo de prueba de Maven.

Resultó ser una prueba anterior en mi suite, en un paquete diferente . ¡Esto me tomó una semana para resolver!

Una prueba anterior estaba probando algunas clases de Logback, y creó un contexto de Logback desde un archivo de configuración.

La última prueba fue probar una subclase de Spring''s SimpleRestTemplate, y de alguna manera, el contexto anterior de Logback se llevó a cabo, con DEBUG activado. Esto hizo que se realizaran llamadas adicionales en RestTemplate para registrar HttpStatus, etc.

Otra cosa es verificar si alguna vez se mete en esta situación. Resolví mi problema inyectando algunos Mocks en mi clase de prueba de Logback, de modo que no se crearon contextos de Logback reales.



No necesita inyectar un DataSource en el JpaTransactionManager ya que EntityManagerFactory ya tiene un origen de datos. Pruebe lo siguiente:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean>


Por lo general, cuando las pruebas pasan en eclipse y fallan con maven, es un problema de classpath porque es la principal diferencia entre los dos.

De modo que puede verificar el classpath con maven -X test y comprobar el classpath de eclipse a través de los menús o en el archivo .classpath en la raíz de su proyecto.

¿Estás seguro, por ejemplo, de que personservice-test.xml está en el classpath?


Tengo el problema similar, pero con IntelliJ IDEA + Maven + TestNG + spring-test. ( la prueba de primavera es esencial, por supuesto :)) Se corrigió cuando cambié la configuración de maven-surefire-plugin para desactivar las pruebas de ejecución en paralelo. Me gusta esto:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <skipTests>${maven.test.skip}</skipTests> <trimStackTrace>false</trimStackTrace> <!--<parallel>methods</parallel>--> <!-- to skip integration tests --> <excludes> <exclude>**/IT*Test.java</exclude> <exclude>**/integration/*Test.java</exclude> </excludes> </configuration> <executions> <execution> <id>integration-test</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <skipTests>${maven.integration-test.skip}</skipTests> <!-- Make sure to include this part, since otherwise it is excluding Integration tests --> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/IT*Test.java</include> <include>**/integration/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin>


Tuve el mismo problema (las pruebas JUnit fallaron en Maven Surefire pero se aprobaron en Eclipse) y logré resolverlo configurando forkMode para siempre en la configuración segura de maven en pom.xml:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> <configuration> <forkMode>always</forkMode> </configuration> </plugin>

Parámetros Surefire: http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html

Editar (enero de 2014):

Como señaló Peter Perháč , el parámetro forkMode está en desuso desde Surefire 2.14. A partir de Surefire 2.14 use esto en su lugar:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.16</version> <configuration> <reuseForks>false</reuseForks> <forkCount>1</forkCount> </configuration> </plugin>

Para obtener más información, consulte Opciones de horquilla y Ejecución de prueba paralela


Tuve el mismo problema, pero el problema para mí fue que las aserciones de Java (por ejemplo, assert (num> 0)) no estaban habilitadas para Eclipse, pero estaban habilitadas cuando se ejecutaba maven.

Por lo tanto, ejecutar las pruebas jUnit desde Eclipse no capturó el error de aserción.

Esto se pone de manifiesto cuando se utiliza jUnit 4.11 (a diferencia de la versión anterior que estaba usando) porque imprime el error de aserción, por ejemplo

java.lang.AssertionError: null at com.company.sdk.components.schema.views.impl.InputViewHandler.<init>(InputViewHandler.java:26) at test.com.company.sdk.util.TestSchemaExtractor$MockInputViewHandler.<init>(TestSchemaExtractor.java:31) at test.com.company.sdk.util.TestSchemaExtractor.testCreateViewToFieldsMap(TestSchemaExtractor.java:48)


Tuve el mismo problema, y ​​la solución para mí fue permitirle a Maven manejar todas las dependencias, incluso a las jarras locales. Usé Maven para dependencias en línea y configuré la ruta de compilación manualmente para las dependencias locales. Por lo tanto, Maven no estaba al tanto de las dependencias que configuré manualmente.

Usé esta solución para instalar las dependencias jar locales en Maven:

¿Cómo agregar archivos jar locales en el proyecto maven?


Tuve este problema hoy probando un método que convirtió un objeto que contenía un Map en una cadena JSON. Supongo que Eclipse y el plugin Surefire de Maven usaban diferentes JRE que tenían diferentes implementaciones de ordenamiento de HashMap o algo así, lo que hacía que las pruebas pasaran por Eclipse y las pruebas se ejecutaran por surefire para fallar ( assertEquals falló). La solución más fácil fue usar una implementación de Map que tenía un pedido confiable.


Tuve un problema similar con una causa diferente y, por lo tanto, una solución diferente. En mi caso, en realidad tenía un error en el que un objeto singleton tenía una variable miembro modificada de forma no segura para los hilos. En este caso, seguir las respuestas aceptadas y eludir las pruebas paralelas solo ocultaría el error que realmente reveló la prueba. Mi solución, por supuesto, es arreglar el diseño para que no tenga este mal comportamiento en mi código.


Tuve un problema similar, la anotación @Autowired en el código de prueba no funcionaba usando la línea de comandos de Maven mientras funcionaba bien en Eclipse. Acabo de actualizar mi versión JUnit de 4.4 a 4.9 y el problema fue resuelto.

<dependency> <groupId>junit</groupId <artifactId>junit</artifactId> <version>4.9</version> </dependency>


Tuve un problema similar: las pruebas JUnit fallaron en Maven Surefire, pero pasaron en Eclipse cuando utilicé la biblioteca JUnit versión 4.11.0 del Repositorio de paquetes de SpringSource. Particulary:

<dependency> <groupId>org.junit</groupId> <artifactId>com.springsource.org.junit</artifactId> <version>4.11.0</version> </dependency>

Luego lo reemplacé con la siguiente biblioteca JUnit versión 4.11 y todo funciona bien.

<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency>


[No estoy seguro de que esta sea una respuesta a la pregunta original, ya que el stacktrace aquí se ve ligeramente diferente, pero puede ser útil para otros.]

Puede obtener pruebas que fallan en Surefire cuando también está ejecutando Cobertura (para obtener informes de cobertura de código). Esto se debe a que Cobertura requiere proxies (para medir el uso del código) y existe algún tipo de conflicto entre esos y los proxies de Spring. Esto solo ocurre cuando Spring usa cglib2, que sería el caso si, por ejemplo, tiene proxy-target-class="true" , o si tiene un objeto que está siendo proxy que no implementa interfaces.

La solución normal para esto es agregar una interfaz. Entonces, por ejemplo, los DAO deben ser interfaces, implementados por una clase DAOImpl. Si se conecta automáticamente a la interfaz, todo funcionará bien (porque cglib2 ya no es necesario, se puede usar un proxy JDK más simple para la interfaz y Cobertura funciona bien con esto).

Sin embargo, no puede usar interfaces con controladores anotados (obtendrá un error de tiempo de ejecución al tratar de usar el controlador en un servlet) - No tengo una solución para las pruebas de Cobertura + Spring que autorizan a los controladores.