Reputation: 1788
I have a Maven project that runs all unit tests fine locally, but when the same project is run on our Jenkins server, some unit test or other occasionally starts failing after a completely unrelated change. It's like it's running the tests in random order and not resetting the in-memory HSQLDB database before each test, so the output of one randomly-selected test is getting fed into the input of the next test. I thought the resetting of test data was part of the automatic JUnit process.
Anybody know what's causing this, and more importantly, how to cure it?
The Jenkins setup for the project is: Jenkins ver. 1.534, Maven 3.1.1, Java 1.7
The test that's currently failing is set up like so:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test-context.xml"})
public class MyAppStatusServiceTest {
@Autowired
MyAppStatusService service;
@Test
public void createTest() {
MyAppStatus test = new MyAppStatus();
test.setStatusCode('Y');
test.setStatusDefinition("Test Data");
test = service.save(test);
assertEquals("Test Data",test.getStatusDefinition());
}
@Test
public void readTest() {
MyAppStatus test = service.findOne(ApplicationStatus.PENDING.getCode() );
assertEquals("Pending",test.getStatusDefinition());
}
@Test
public void updateTest() {
MyAppStatus test = service.findOne(ApplicationStatus.PENDING.getCode());
test.setStatusDefinition("New Value");
test = service.save(test);
MyAppStatus readme = service.findOne(ApplicationStatus.PENDING.getCode());
assertEquals("New Value", StringUtils.trim(readme.getStatusDefinition()));
}
}
The error that comes back is the failure of the second test as follows:
org.junit.ComparisonFailure: expected:<[Pending]> but was:<[New Value]>
so it appears the bottom test is getting run, the data's not getting reset, and then the middle test is running (and failing). I can't duplicate this behavior locally so it's a little frustrating.
Upvotes: 0
Views: 583
Reputation: 11487
Junit
wont reset any test data which you have used in the test
. The test
order is always random, your test can fail even in your local environment it has nothing to do with jenkins
.
Use @Before annotated methods to insert records into the database and use @After annotation to delete records from the database.
Before
and After
annotation methods will get invoked before and after each test execution.
e.g
@Before
public void onceBeforeEachTest(){
// Insert test data records.
}
@After
public void onceAfterEachTest(){
// Delete test data records.
}
Upvotes: 2
Reputation: 441
The order of running the test methods is random, so it isn't guaranteed that createTest method will be ran first (even though it's defined first). You should move the test preparation part to a @Before
annotated method as was suggested by SJ.
Then if yo don't want to deal with cleaning the DB after every test method, you can run every test in a separate transaction which does rollback at the end. Putting @TransactionConfiguration
should do that.
Upvotes: 0