Launch application before tests on condition - spring-boot

I have rest-assured tests marked with #SpringBootTest (which allows to start application before executing tests). But I have two use cases:
Run tests locally (current setup is ok for that).
Run same tests on already running host (not ok, as application is started before executing tests).
Is there any way to sometimes ignore #SpringBootTest or somehow turn off application initialization?
Adding minimal example:
#RunWith(SpringRunner.class)
//In case service.host provided: no need to run application
#SpringBootTest
public class RestTest {
#Value("service.host")
private String host;
#Before
public void setUp() {
if (StringUtils.isNotEmpty(host)) {
RestAssured.baseURI = host;
}
}
#Test
public void test() {
RestAssured.get("/test").then().assertThat().statusCode(HttpStatus.OK.value());
}
}

Related

Arquillian test not failing

When dependency injection in Arquillian test class fails, maven still claims that all tests are run and are passed. This is major issue if we have hundreds of tests and some tests show as Green in Jenkins, but in reality they are not driven at all.
Is there a way to make the above test fail in Jenkins/Maven? One can use any Interface long as there is no implementation added to deployment.
#ExtendWith(ArquillianExtension.class)
class FailingArquillianTestIssueIT {
#Inject
DummyInterface dummyInterface;
#Deployment(testable = true)
public static JavaArchive create() throws Exception {
JavaArchive archive = ShrinkWrap.create(JavaArchive.class).addAsManifestResource(EmptyAsset.INSTANCE,
"beans.xml");
return archive;
}
#Test
void test1() {
assertTrue(false);
}
}

how tests are getting executed in spring boot while doing integration with in memory server?

I am running integration tests for my API which deals with in-memory LDAP
server. Sometimes tests gets executed properly and sometimes not. Why is this happening ?
I have tried optimizing test-cases and reducing count of test-cases. Individually each test is passing successfully.
//LDAPInMem.java
public class LdapInMem {
{
function startServer()
{
InMemoryDirectoryServer server;
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig();
//some server configuration code
server.startListening();
}
}
//Integration test
import LDAPInMem
public class UserControllerIntegrationTest {
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#Before
public void setup()
{
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
LDAPInMem.startServer();
}
#Test
public void fun1()
{
//some mockMvc testcase which deals with in-memory server
}
#Test
public void fun2()
{
//some mockMvc testcase which deals with in-memory server
}
#Test
public void fun3()
{
//some mockMvc testcase which deals with in-memory server
}
}
These test-cases are failing sometimes even though everything else is fine. Why is this happening ? Is it thread related ? What can be done in this case to run these test-cases properly?

springboottest how to prevent running application

I have the standard Application class which runs a Spring batch ETL:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
with my Junit test doing something like:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class MyServiceTest {
#Autowired
MyService myService;
#Test
public void testInsertions() {
//do stuff with assertions
}
}
My problem is that when I execute the junit test, the application also kicks off the ETL then executes the test. How to prevent the application from running?
I think there are a lot of alternatives and it really depends on what you are trying to achieve.
One of the options would be to run your tests with a specific profile, like testing, and configure your ETLs (I'm assuming they are just jobs) to be configured based on some property or specific profile.
For example:
Testing class
#ActiveProfiles("testing")
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class MyServiceTest {
...
}
Job/ETL classes
#Component
#Profile("!testing")
public class JobEtlService {
}
Hope it helps.

Is it possible to fail fast Spring tests if the application cannot start?

I have this base test class in one Spring Boot module:
#ActiveProfiles("test")
#SpringBootTest(classes = {WebServiceApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class BaseWebServiceTest {
//...
}
If for some reason the application cannot start (in my case, if localstack docker image is not started of if Spring Cloud Contract stubs are not available, etc) the tests are still being run and obviously they all fail. Is there any way of skipping all tests if ApplicationContext is not loaded?
Is there any way of skipping all tests if ApplicationContext is not loaded?
No. There is no way to skip tests automatically if the ApplicationContext does not load.
However, you could make use of JUnit 4's assumption support and abort the execution of the tests based on some boolean condition that you choose. For example, if you can check whether the docker image started, you could then do something similar to the following.
public static boolean dockerImagedStarted() {
// return true if the Docker image started...
}
#BeforeClass
public static void ensureDockerImageStarted() {
org.junit.Assume.assumeTrue(dockerImagedStarted());
}
p.s. please note that there is an open JIRA issue requesting a built-in feature to avoid repeated attempts to load an ApplicationContext. See SPR-9548 for details.
You can create a runner that will ignore your tests in case that the ApplicationContext is not loaded
public class CustomRunner extends BlockJUnit4ClassRunner {
public CustomRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected boolean isIgnored(FrameworkMethod child) {
return shouldIgnore() || super.isIgnored(child);
}
/**
*
* #return if your test should be ignored or not
*/
private boolean shouldIgnore() {
// Some check if your docker is up
return true;
}
}
And the use #RunWith with the CustomRunner you have created
#RunWith(CustomRunner.class)
#ActiveProfiles("test")
#SpringBootTest(classes = {WebServiceApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class BaseWebServiceTest {
//...
}

Running multiple tests using RestAssured serially

I have a Spring Boot application which is capable of running Integration tests using Rest Assured.
There is a single test class which has multiple test cases. I wish to run the test cases serially as given in the class.
public class ItemControllerTest{
#Before
public void setUp(){
...
}
#Test
public void test1(){
...
}
#Test
public void test2(){
...
}
}
When I run integration test,it seems test2 is getting executed before test1.
But I want them to run in the order they are written
I am not familiar with spring-boot, but if you are using Junit to run your tests, then you can run them serially by adding the following annotation above your class:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ItemControllerTest{
// tests will run in order here
}

Resources