How to run multiple tests with Spring Boot - spring-boot

With Spring Boot 1.5, how could I run multiple tests which are in different classes?
E.g.
I have `Service1` tests in `Service1test.java`;
I have `Service2` tests in `Service2test.java`;
I shall need to run both in one go.

What I have done is as follows:
In the main class
#RunWith(Suite.class)
#Suite.SuiteClasses({
PostServiceTest.class,
UserServiceTest.class
})
public class DataApplicationTests {
#Test
public void contextLoads() {
}
}
In the PostServiceTest I have
#RunWith(SpringRunner.class)
#SpringBootTest
#Transactional
public class PostServiceTest {
#Autowired
IPostService postService;
#Before
public void initiate() {
System.out.println("Initiating the before steps");
}
#Test
public void testFindPosts() {
List<Post> posts= postService.findPosts();
Assert.assertNotNull("failure - expected Not Null", posts);
}
}
The second class, UserServiceTest has similar structure.
When I run the DataApplicationTests, it runs both the classes.

I will assume you are using IntelliJ, but the same stuff apply for all the IDEs.
Gradle and Maven have got a standarized project structure, that means all Test classes positioned inside the 'test-root' will be ran on either mvn test (to just test), or while you build (to check wether the code behaves correctly. In that case, if a test fails, build fails too).
Here's an image of a marked-green test directory on IntelliJ :
Your IDE should allow you to run specific tests, test suites or classes seperately, without the need to type out any command. IntelliJ provides some Icons on the separator column thingy (near to the line numbers) that enables you to run that specific stuff. Check out these green play buttons:
Be careful with creating test suites though. That way unless you manually configure the tests that need to be run, you will get duplicate runs because the build tools will run all the test suites independently and then all the tests! (That means that if test suite A contains test suite B and C, B and C are going to be ran 2 times: 1 each from A, and 1 each independently. The same applies for standalone test classes).

Related

writing load tests for junit springboot application

I have written the following junit test.
#SpringBootTest
public class abc {
#Autowired
private ActorService actorService;
#Test
#Transactional
public void testCorrectIdHandlingForNewInsertedActors() {
int elementsInDb = 0;
for (Actor a : this.actorService.findAll()) {
elementsInDb++;
}
Actor actor = this.actorService.saveAndSetId(new Actor());
assertEquals(elementsInDb + 1, actor.getId());
}
}
Now I want to write some load tests for performance testing but I don't know which tools I can use within my spring application. I am using gradle as my build tool. Any tutorial will be appreciated.
PS: I have already tried zerocode but does not work for me
You have some useful features out of the box such as #RepeatedTest and #Timeout (see the JUnit 5 annotations reference here) which respectively allow you to repeat a specific test method n times and set a maximum time limit before a test will fail automatically.
Other than that, for more complete and meaningful load testing you should consider relying on a full-fledged solution such as Apache JMeter or Gatling, rather than unit tests.

Sonarqube exclusion on Test Data

Fellow Members,
I am trying to configure Sonarqube on my service.
For tests, I have extracted test Data (setup) into a separate class - testData.java class.
My question is, how should I analyse my testData.java using Sonar. Since Sonar mandates all the files under test package to end with *Test.java. Therefore if I try to rename the file to something say testDataTest.java it asks me to add a Test to the class.
Since my class is a final class and does not contain any test, I have to add a hack to add a meaning less #Test.
I would like to understand what are the best practices here and how could I improvise.
An Example of my class:
#TestConfiguration
#Import({ TestSecurityConfig.class , TestAuthentication.class})
public class ConfigurationSetupForTest{
#Test
#DisplayName("This is a dumb test so Sonar will not give inclusion errors")
void dumbTest() {
assertTrue(true);
}
}
Thanks

junit add more test classes dynamically per user request (rerun tests) for integration testing

I am looking for a way to start the spring context, intialize all caches and after that ask the user on the command line (cmd) what tests he want to execute.
after the tests are run the user can choose to rerun the tests or run different tests until he decide to stop the programm.
this should be based on junit as it enables us to use the same tests within different execution environments (eg. jenkins build, ...)
is there a framework that support something like this or any other adwise how to implement this?
while(true) {
userInput = parseUserInputFromConsole();
if (userWantToExit(userInput)) {
break;
} else {
JunitResult = runJunitTetsBasedOnUserInput(userInput);
generateTestRunReport(JunitResult);
}
}
additional, one test exists of more then one step, but the steps should be reusable among tests. any idea how to implement this?
You can do this by using Spring #ActiveProfiles annotation, you need to basically set which tests are applicable for which run like below:
#ContextConfiguration
#ActiveProfiles({"dev", "integration"})
public class DeveloperIntegrationTests {
// class body...
}
You can look at here

Maven report on all tests on method level

I want to generate a report after maven runs the tests that will display a list of all tests that are run. I don't want the tests to be grouped by class, I just want a list of executed tests. For example if I have
class Test1 {
#Test
public void test1() {
}
}
class Test2 {
#Test
public void test2() {
}
}
After running the tests I want a report that looks like:
Test1.test1 PASSED time:2sec
Test2.test2 FAILED time:1sec
Is there a maven report plugin that does this or any other way that this can be done?
I've looked at maven test report format but it seems there you have to click class by class to see the failing methods.
I would appreciate any suggestions
I researched the documentation for both SureFire and Cobertura, and there does not appear to be a built-in report in the format you seek.
However, the file TEST-TestSuite.xml generated by SureFire will contain an entry for every individual test case at the method-level. So, your best bet is to develop a trivial XML transform that converts this file to the format you prefer.

Functional test in Spring: changes in database not visible in test

I have integration test (which runs under Jetty) where I open page (by using Selenium) and check that record about this activity was added to database (HSQL). But it does not work -- JPA (Hiberante) adds record (I see it in logs) but when I execute SELECT query there no records at all.
Test case:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"classpath:spring/DispatcherServletContext.xml"
})
#TransactionConfiguration(defaultRollback = false)
public class WhenUserOpenNotExistingPage
extends WhenUserAtAnyPage<NotFoundErrorPage> {
private final String currentUrl;
#Autowired
private SuspiciousActivityDao suspiciousActivities;
private String generateRandomUrl() {
return String.format(
"/tests/page-does-not-exists-%s.htm",
RandomStringUtils.randomNumeric(5)
);
}
public WhenUserOpenNotExistingPage() {
currentUrl = generateRandomUrl();
page.open(currentUrl);
}
#Test
#Transactional(readOnly = true)
public void incidentShouldBeLoggedToDatabase() {
SuspiciousActivity activity =
suspiciousActivities.findByPage(currentUrl);
assertNotNull(activity);
}
}
Also WhenUserOpenNotExistingPage() (constructorr) called twice (and I don't know why it happens and probably is the root of my problem).
Can you help me?
Thanks in advance!
I assume you are adding something to the database in the test case and the same database is being used by your application running on Jetty. If your database uses any isolation level above read uncommited, the changes you made in the test case won't be visible until that test case finishes. This is because you database code joins the transaction that was created when the test was starting.
By default this test transaction is rolled back after the test finishes, so the changes are visible within the current test (transaction), but aren't visible outside (by different threads/connections) and are rolled back. You are changing the default behaviour by using defaultRollback = false attribute, but this only means that changes you made in one test aren't visible by the web application (different database connection), but will be visible in subsequent test (after commit). Not really useful.
You have few options:
Get rid of Spring transactional test support. This means Spring won't create a new transaction every time you start a test and won't do commit/rollback. Now it is up to you when to start transaction and commit it before actually starting SElenium test.
This can easily be done by replacing #TransactionConfiguration with:
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
this will override default test execution listeners, removing TransactionalTestExecutionListener from the stack
You might run setup code from different thread or with propagation REQUIRES_NEW
Finally, you should consider doing setup outside of JUnit. Maybe you can do the setup from the application itself?
As for the constructor - new instance of JUnit test class is created per test. The authors of JUnit claim it makes the test more predictable and stateless (no dependencies between test) by cleaning up the test class prior to running every test. In practice, especially with integration tests, this is more a pain than a advantage.
By the way if you do some database manipulation in the test and commit the changes, watch out for test dependencies. The order in which tests are executed is not guaranteed in JUnit. This means that changes in one test shouldn't affect other tests.

Resources