การทดสอบ JUnit ผ่านใน Eclipse แต่ล้มเหลวใน Maven Surefire


101

ฉันได้เขียนการทดสอบ JUnit โดยใช้ไลบรารี JUnit 4 และ Spring-test เมื่อฉันเรียกใช้การทดสอบภายใน Eclipse ให้รันได้ดีและผ่าน แต่เมื่อฉันเรียกใช้โดยใช้ Maven (ในระหว่างกระบวนการสร้าง) พวกเขาล้มเหลวโดยให้ข้อผิดพลาดเกี่ยวกับสปริง ฉันไม่แน่ใจว่าอะไรเป็นสาเหตุของปัญหา JUnit, Surefire หรือ Spring นี่คือรหัสทดสอบการกำหนดค่าสปริงและข้อยกเว้นที่ได้รับจาก 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>

ข้อยกเว้นใน 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

คุณมีการกำหนดค่าพิเศษของปลั๊กอิน surefire ใน POM ของคุณหรือไม่?
matt b

@matt ฉันไม่มีการกำหนดค่าที่แน่นอนใน pom ของฉัน
Abhinav Sarkar

1
ฉันมาที่บทความนี้เพราะฉันมีปัญหาเดียวกัน แต่ในกรณีของฉันฉันใช้วิธีแก้ปัญหาอื่น หลังจากเปิดใช้งานบันทึก DEBUG ในการทดสอบของฉันฉันพบว่า Spring Framework กำลังดูชื่อฐานข้อมูล MongoDB เก่าและชื่อนี้ถูกตั้งค่าใน jar เวอร์ชันเก่าที่สร้างขึ้นโดยโปรเจ็กต์อื่นบนพื้นที่ทำงานของฉัน (แม้ว่าจะถูกสร้างขึ้นหลายครั้งด้วย ชื่อใหม่) Maven Clen บางตัว + การลบไลบรารีใน. m2 ของฉันตามด้วย Maven Install ของโปรเจ็กต์ทั้งหมดเหล่านั้นช่วยแก้ปัญหาได้ แม้ว่าจะไม่มีเหตุผลที่โครงการจะดูขวดโหลเก่า ๆ (มันถูกเก็บไว้ที่ไหนสักแห่ง แต่น่าเสียดาย)
Cotta

คำตอบ:


111

ฉันมีปัญหาเดียวกัน (การทดสอบ JUnit ล้มเหลวใน Maven Surefire แต่ส่งผ่านใน Eclipse) และจัดการเพื่อแก้ปัญหาโดยตั้งค่าforkModeให้อยู่ในการกำหนดค่า maven surefire ใน pom.xml เสมอ:

<plugin>
    <groupId> org.apache.maven.plugins </groupId>
    <artifactId> maven-surefire-plugin </artifactId>
    <version> 2.12 </version>
    <การกำหนดค่า>
        <forkMode> เสมอ </forkMode>
    </configuration>
</plugin>

พารามิเตอร์ Surefire: http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html

แก้ไข (มกราคม 2014):

ดังที่Peter Perháčชี้ให้เห็นพารามิเตอร์ forkMode ถูกเลิกใช้งานตั้งแต่ Surefire 2.14 เริ่มต้นจาก Surefire 2.14 ใช้สิ่งนี้แทน:

<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>

สำหรับข้อมูลเพิ่มเติมโปรดดูที่ตัวเลือกส้อมและการดำเนินการทดสอบแบบขนาน


6
ดีใจที่ได้ยิน. ในกรณีของฉันปัญหาน่าจะเป็นไปได้มากว่าไฟล์คอนฟิกูเรชันที่อ่านโดยการทดสอบ JUnit อยู่ในหน่วยความจำทำให้ผลลัพธ์ของการทดสอบในภายหลังเสียหาย เมื่อ forkMode ถูกตั้งค่าเป็นจริงการทดสอบแต่ละคลาสจะถูกดำเนินการโดยไม่ระบุจุดสิ้นสุดของคลาสอื่น ๆ อย่างสมบูรณ์เพื่อรับประกันว่าการทดสอบจะดำเนินการโดยไม่มีผลข้างเคียง
simon

4
ลองใช้วิธีนี้โดยใช้ surefire 2.16 และได้รับ: "พารามิเตอร์ forkMode เลิกใช้งานตั้งแต่เวอร์ชัน 2.14 ใช้ forkCount และ reuseForks แทน" ดังนั้นระวังสิ่งนี้ใช้ได้เฉพาะในช่วงก่อน 2.14
Peter Perháč

1
คุณมักจะใช้จำนวนส้อมที่สูงขึ้นได้ความสำคัญที่นี่คือส้อมจะไม่ถูกนำมาใช้ซ้ำและส้อมเดียวจะทำให้การสร้างแพ็คเกจใช้เวลานานมาก
Sandy Simonton

1
บวกหนึ่งสำหรับการอัปเดตคำตอบของคุณในอีกสองปีต่อมา
Gerben Rampaart

1
@SteveChambers ฉันมาสายเล็กน้อยที่นี่ แต่ 1 ต่อคอร์ cpu ฉันคิดว่าสมเหตุสมผล (forkCount = 1C) - มันขึ้นอยู่กับเครื่องสร้างแน่นอน
Sandy Simonton

7

จู่ๆฉันก็พบข้อผิดพลาดนี้และวิธีแก้ปัญหาสำหรับฉันคือปิดการใช้งานเพื่อเรียกใช้การทดสอบพร้อมกัน

ค่าไมล์ของคุณอาจแตกต่างกันไปเนื่องจากฉันสามารถลดจำนวนการทดสอบที่ล้มเหลวได้โดยกำหนดค่าให้ Surefire ทำการทดสอบแบบขนานโดย´classes´:

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

อย่างที่ฉันเขียนครั้งแรกสิ่งนี้ไม่เพียงพอสำหรับชุดทดสอบของฉันดังนั้นฉันจึงปิดการใช้งานแบบขนานโดยสมบูรณ์โดยการลบ<configuration>ส่วนออก


7

ฉันมีปัญหาคล้ายกันคำอธิบายประกอบ@Autowiredในรหัสทดสอบไม่ทำงานภายใต้การใช้บรรทัดคำสั่ง Maven ในขณะที่ทำงานได้ดีใน Eclipse ฉันเพิ่งอัปเดต JUnit เวอร์ชันจาก 4.4 เป็น 4.9 และปัญหาได้รับการแก้ไขแล้ว

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

5

สิ่งนี้ใช้ไม่ได้กับสถานการณ์ของคุณ แต่ฉันมีสิ่งเดียวกัน - การทดสอบที่จะผ่านใน Eclipse ล้มเหลวเมื่อมีการเรียกใช้เป้าหมายการทดสอบจาก Maven

มันเป็นการทดสอบก่อนหน้านี้ในชุดของฉันในแพ็คเกจอื่น ฉันใช้เวลาหนึ่งสัปดาห์ในการแก้ปัญหา!

การทดสอบก่อนหน้านี้กำลังทดสอบคลาส Logback บางคลาสและสร้างบริบท Logback จากไฟล์กำหนดค่า

การทดสอบในภายหลังคือการทดสอบคลาสย่อยของ SimpleRestTemplate ของ Spring และบริบท Logback ก่อนหน้านี้ถูกจัดขึ้นโดยเปิด DEBUG สิ่งนี้ทำให้มีการเรียกเพิ่มเติมใน RestTemplate เพื่อบันทึก HttpStatus เป็นต้น

เป็นอีกสิ่งหนึ่งในการตรวจสอบว่ามีใครเคยอยู่ในสถานการณ์นี้หรือไม่ ฉันแก้ไขปัญหาของฉันโดยการฉีด Mocks ลงในคลาสทดสอบ Logback ของฉันดังนั้นจึงไม่มีการสร้างบริบท Logback ที่แท้จริง


ขอบคุณสำหรับตัวชี้ ฉันพบปัญหาที่คล้ายกันโดยที่โครงการ maven เริ่มต้นมีกรณีทดสอบแบบดั้งเดิมที่สร้างขึ้นโดยอัตโนมัติ (ซึ่งฉันไม่สนใจ) ในขณะที่ฉันใช้ SpringJUnit4ClassRunner สำหรับกรณีทดสอบใหม่ของฉัน การเพิ่มคำอธิบายประกอบ SpringJUnit4ClassRunner ในการทดสอบที่สร้างขึ้นอัตโนมัติช่วยแก้ปัญหาให้ฉันได้
Avnish

5

ฉันมีปัญหาที่คล้ายกัน แต่ใช้ IntelliJ IDEA + Maven + TestNG + spring-test ( การทดสอบฤดูใบไม้ผลิเป็นสิ่งสำคัญแน่นอน :)) ได้รับการแก้ไขเมื่อฉันเปลี่ยน config ของmaven-surefire-pluginเพื่อปิดใช้งานการทดสอบการรันแบบขนาน แบบนี้:

<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>

4

ผลการดำเนินการทดสอบที่แตกต่างจากJUnit runและmaven installดูเหมือนจะเป็นอาการของปัญหาต่างๆ

การปิดใช้งานเธรดที่ใช้การดำเนินการทดสอบซ้ำยังช่วยกำจัดอาการในกรณีของเราได้ แต่ความรู้สึกว่าโค้ดไม่ปลอดภัยต่อเธรดยังคงแข็งแกร่ง

ในกรณีของเราความแตกต่างเกิดจากการมีถั่วที่ปรับเปลี่ยนพฤติกรรมการทดสอบ การรันเพียงการทดสอบ JUnit จะให้ผลลัพธ์ที่ดี แต่การรันinstallเป้าหมายโปรเจ็กต์จะส่งผลให้เกิดกรณีทดสอบที่ล้มเหลว เนื่องจากเป็นกรณีทดสอบที่อยู่ระหว่างการพัฒนาจึงเป็นที่น่าสงสัยทันที

ส่งผลให้กรณีทดสอบอื่นกำลังสร้างอินสแตนซ์ของถั่วผ่าน Spring ซึ่งจะอยู่รอดได้จนกว่าจะมีการดำเนินการกรณีทดสอบใหม่ การปรากฏตัวของถั่วกำลังปรับเปลี่ยนพฤติกรรมของคลาสบางคลาสและสร้างผลลัพธ์ที่ล้มเหลว

วิธีแก้ปัญหาในกรณีของเราคือการกำจัดถั่วซึ่งไม่จำเป็นในตอนแรก (แต่ยังได้รับรางวัลอื่นจากปืนคัดลอก + วาง )

ฉันขอแนะนำให้ทุกคนที่มีอาการนี้ตรวจสอบว่าสาเหตุที่แท้จริงคืออะไร การปิดใช้งานเธรดซ้ำในการดำเนินการทดสอบอาจซ่อนไว้เท่านั้น


3

ฉันมีปัญหาเดียวกัน แต่ปัญหาสำหรับฉันคือการยืนยัน Java (เช่นการยืนยัน (num> 0)) ไม่ได้เปิดใช้งานสำหรับ Eclipse แต่ถูกเปิดใช้งานเมื่อเรียกใช้ maven

ดังนั้นการรันการทดสอบ jUnit จาก Eclipse จึงไม่พบทริกเกอร์ข้อผิดพลาดในการยืนยัน

สิ่งนี้ชัดเจนเมื่อใช้ jUnit 4.11 (ตรงข้ามกับเวอร์ชันเก่าที่ฉันใช้) เนื่องจากพิมพ์ข้อผิดพลาดในการยืนยันเช่น

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)

ในกรณีนี้ลิงค์นี้เกี่ยวข้อง: confluence.atlassian.com/display/JIRAKB/…
OhadR

... และในกรณีของการไล่ระดับสีให้เพิ่มสิ่งนี้: ทดสอบ {enableAssertions = false ignoredFailures = true}
OhadR

3

ฉันมีปัญหาที่คล้ายกันโดยมีสาเหตุที่แตกต่างกันดังนั้นวิธีแก้ปัญหาที่แตกต่างกัน ในกรณีของฉันจริง ๆ แล้วฉันมีข้อผิดพลาดที่อ็อบเจ็กต์ซิงเกิลตันมีตัวแปรสมาชิกที่แก้ไขด้วยวิธีที่ไม่ปลอดภัยเธรด ในกรณีนี้การทำตามคำตอบที่ยอมรับและการหลีกเลี่ยงการทดสอบคู่ขนานจะซ่อนเฉพาะข้อผิดพลาดที่เปิดเผยโดยการทดสอบเท่านั้น แน่นอนวิธีแก้ปัญหาของฉันคือการแก้ไขการออกแบบเพื่อไม่ให้ฉันมีพฤติกรรมที่ไม่ดีในโค้ดของฉัน


2

[ฉันไม่แน่ใจว่านี่เป็นคำตอบสำหรับคำถามเดิมเนื่องจาก stacktrace ที่นี่ดูแตกต่างกันเล็กน้อย แต่อาจเป็นประโยชน์กับคนอื่น ๆ ]

คุณสามารถรับการทดสอบที่ล้มเหลวใน Surefire ได้เมื่อคุณใช้ Cobertura ด้วย (เพื่อรับรายงานการครอบคลุมโค้ด) เนื่องจาก Cobertura ต้องการพร็อกซี (เพื่อวัดการใช้โค้ด) และมีข้อขัดแย้งบางอย่างระหว่างพร็อกซีเหล่านั้นกับสปริง สิ่งนี้จะเกิดขึ้นเฉพาะเมื่อ Spring ใช้ cglib2 ซึ่งจะเป็นกรณีตัวอย่างเช่นคุณมีproxy-target-class="true"หรือถ้าคุณมีอ็อบเจ็กต์ที่ถูกพร็อกซีที่ไม่ได้ใช้อินเทอร์เฟซ

การแก้ไขตามปกติคือการเพิ่มอินเทอร์เฟซ ตัวอย่างเช่น DAO ควรเป็นอินเทอร์เฟซที่ใช้งานโดยคลาส DAOImpl หากคุณเปิดอินเทอร์เฟซอัตโนมัติทุกอย่างจะทำงานได้ดี (เนื่องจากไม่จำเป็นต้องใช้ cglib2 อีกต่อไปสามารถใช้พร็อกซี JDK ที่เรียบง่ายกว่าไปยังอินเทอร์เฟซแทนได้และ Cobertura ก็ทำงานได้ดี)

อย่างไรก็ตามคุณไม่สามารถใช้อินเทอร์เฟซกับคอนโทรลเลอร์ที่มีคำอธิบายประกอบ (คุณจะได้รับข้อผิดพลาดรันไทม์เมื่อพยายามใช้คอนโทรลเลอร์ใน servlet) - ฉันไม่มีวิธีแก้ปัญหาสำหรับการทดสอบ Cobertura + Spring ที่ควบคุมอัตโนมัติ


2

ฉันมีปัญหาที่คล้ายกัน: การทดสอบ JUnit ล้มเหลวใน Maven Surefire แต่ส่งผ่านใน Eclipse เมื่อฉันใช้ไลบรารี JUnit เวอร์ชัน 4.11.0 จาก SpringSource Bundle Repository พาร์ติคัลลารี:

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

จากนั้นฉันก็แทนที่ด้วยไลบรารี JUnit เวอร์ชัน 4.11 และทุกอย่างทำงานได้ดี

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

นี้ได้เคล็ดลับสำหรับฉัน. การทดสอบของฉันทำงานทันทีเมื่อฉันเรียกใช้ Maven จากบรรทัดคำสั่ง อย่างไรก็ตามใน Eclipse ฉันต้องปิดและเปิดโปรเจ็กต์ใหม่ก่อนที่การทดสอบยูนิตจะทำงานในหน้าต่าง JUnit
Marvo

1

วันนี้ฉันมีปัญหานี้ในการทดสอบวิธีการที่แปลงวัตถุที่มีMapสตริง JSON ฉันถือว่า Eclipse และปลั๊กอิน Maven surefire ใช้ JRE ที่แตกต่างกันซึ่งมีการใช้งานการHashMapสั่งซื้อหรือบางสิ่งที่แตกต่างกันซึ่งทำให้การทดสอบที่รันผ่าน Eclipse ผ่านไปและการทดสอบที่รันผ่าน surefire ล้มเหลว ( assertEqualsล้มเหลว) วิธีแก้ปัญหาที่ง่ายที่สุดคือการใช้แผนที่ที่มีลำดับที่เชื่อถือได้


0

คุณไม่จำเป็นต้องฉีด DataSource ใน JpaTransactionManager เนื่องจาก EntityManagerFactory มีแหล่งข้อมูลอยู่แล้ว ลองทำดังต่อไปนี้:

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

การทดสอบล้มเหลว (มีข้อผิดพลาด) ใน Eclipse ถ้าฉันลบแหล่งข้อมูลออกจาก transactionManager bean
Abhinav Sarkar

0

โดยปกติเมื่อการทดสอบผ่านใน eclipse และล้มเหลวด้วย maven มันเป็นปัญหาของ classpath เนื่องจากเป็นข้อแตกต่างหลักระหว่างทั้งสอง

ดังนั้นคุณสามารถตรวจสอบ classpath ด้วย maven -X test และตรวจสอบ classpath ของ eclipse ผ่านเมนูหรือในไฟล์. classpath ในรูทของโปรเจ็กต์ของคุณ

คุณแน่ใจหรือไม่ว่า personservice-test.xml อยู่ใน classpath


ใช่เพราะฉันสามารถดูบันทึก INFO จากการโหลดบริบท Spring ในคอนโซลระหว่างการทดสอบ maven
Abhinav Sarkar

0

สิ่งนี้ช่วยฉันในการแก้ไขปัญหาของฉัน ฉันมีอาการคล้าย ๆ กันใน maven นั้นจะล้มเหลว แต่การทดสอบ junit ทำงานได้ดี

ตามที่ปรากฎว่า pom.xml หลักของฉันมีคำจำกัดความต่อไปนี้:

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

และในโครงการของฉันฉันแทนที่เพื่อลบ argLine:

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

หวังว่าสิ่งนี้จะช่วยใครบางคนในการแก้ไขปัญหาปลั๊กอิน surefire



0

ฉันมีปัญหาเดียวกันและวิธีแก้ปัญหาสำหรับฉันคืออนุญาตให้ Maven จัดการการอ้างอิงทั้งหมดรวมถึงไหในพื้นที่ด้วย ฉันใช้ Maven สำหรับการอ้างอิงออนไลน์และกำหนดเส้นทางการสร้างด้วยตนเองสำหรับการอ้างอิงภายใน ดังนั้น Maven ไม่ทราบถึงการอ้างอิงที่ฉันกำหนดค่าด้วยตนเอง

ฉันใช้วิธีนี้เพื่อติดตั้งการพึ่งพา jar ในเครื่องลงใน Maven:

จะเพิ่มไฟล์ jar ในเครื่องในโครงการ maven ได้อย่างไร


0

ในกรณีของฉันสาเหตุคือข้อบกพร่องในรหัส การทดสอบอาศัยลำดับขององค์ประกอบใน a HashSetซึ่งแตกต่างกันเมื่อรันใน Eclipse หรือใน Maven Surefire


-2

เป็นไปได้มากว่าไฟล์การกำหนดค่าของคุณจะอยู่ในsrc / main / resourcesในขณะที่ไฟล์นั้นต้องอยู่ภายใต้src / test / resourcesเพื่อให้ทำงานได้อย่างถูกต้องภายใต้ maven

https://cwiki.apache.org/UIMA/differences-between-running-unit-tests-in-eclipse-and-in-maven.html

ฉันกำลังตอบกลับสิ่งนี้หลังจากผ่านไปสองปีเพราะฉันไม่พบคำตอบที่นี่และฉันคิดว่ามันถูกต้อง


ไม่มันเป็นวิธีอื่น src/main/resourcesมองเห็นการทดสอบ แต่src/test/resourcesไม่สามารถมองเห็นรหัสการผลิตได้
Christoffer Hammarström

ลิงก์ที่คุณเพิ่มกำลังพูดถึงการอ้างอิง ระหว่างโปรเจ็กต์ไม่ใช่ใน main / test ในโปรเจ็กต์เดียวกัน
eis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.