I have Sprint Tool Suite 3.3 and the latest version of Infinitest installed. According to Infinitest, many of my classes have errors, but yet Maven builds just fine. Here is an example of some errors that the Problems tab in STS show:
InvalidDataAccessResourceUsageException (Table "ADDRESSTYPEREF" not found; SQL statement:...SeedAddressTypes.java /... line 34 Infinitest Test Failure
AssertionFailure (null id in com..model.base.Menu entry (don't flush the Session after an exception occurs)) in TestMenuBuilderIT.sortByTopMenu TestMenuBuilderIT.java
All the tests that show an error are integration that use Java Config for the EmbeddedDatabase:
public class TestMenuBuilderIT extends BaseItegration {
#Autowired
private MenuRepository menuRepository;
#Test
public void sortByTopMenu() {
List<Menu> testMenu = menuRepository.findAll(); <== offending line
...
}
And the configuration class:
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration( loader = AnnotationConfigContextLoader.class, classes = { JpaConfig.class } )
public abstract class BaseItegration {
..
}
#Configuration
#EnableTransactionManagement
#ComponentScan( basePackages = { ...} )
#ImportResource( { "classpath:applicationContext.xml"} )
public class JpaConfig {
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType( EmbeddedDatabaseType.H2 ).setName( "testdb" )
.addScript( "classpath:embeddedDatabase.sql" ).build();
}
I don't see why this would work fine in Maven, but Infinitest has these DB related errors. I could not find any documentation saying that JavaConfig wouldn't work with Infinitest. I am able to right click and run each test "As A Unit Test" successfully.
Does anyone know what might cause this?
Related
In my Java selenium application for running automation testscripts, I want to integrate with Spring/Spring boot to use make use of .properties files for different environment to run.
Is there any example or how to proceed, I have seen many links , but not able to find the correct way of implementing it.
Depending on the environment the app is in, it should pick the corresponding .properties file.
ReadConfigurations.java // Where it should read the properties file and get some values like,
public class ReadConfigurations {
// #Value( "${local.driverpath}" )
// private String getdriverpath;
// #Value( "${login_name}" )
// String getLoginName;
}
application-local.properties
local.driverpath = ..\\chromedriver_win32\\chromedriver.exe
local.implicit_wait_time=30
local.app_url = http://localhost:8080/app
local.login_name=
local.login_password =
application-test.properties
local.driverpath = ..\\chromedriver_win32\\chromedriver.exe
local.implicit_wait_time=30
local.app_url = http://testurl:8080/app
local.login_name=
local.login_password =
public class LoginTest {
ReadConfigurations readConfigurations;
#Test
private void login() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", readConfigurations.getDriverPath);
}
}
For running tests, I assume you want to read properties from test package.
So, annotate your ReadConfigurations with #Configuration and #TestPropertySource
#Configuration
#TestPropertySource("application-${spring.profiles.active}.properties")
public class ReadConfigurations {
// this should be added to resolve ${..}
#Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
return new PropertySourcesPlaceholderConfigurer();
}
#Value( "${local.driverpath}" )
String getDriverPath;
#Value( "${local.login_name}" )
String getLoginName;
...
}
Then start your tests with local or test spring profile.
-Dspring.profiles.active=test
#SpringBootTest
public class LoginTest {
#Autowired
ReadConfigurations readConfigurations;
#Test
private void login() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", readConfigurations.getDriverPath);
}
}
This worked for me for the Getting started Spring Boot project:
https://github.com/spring-guides/gs-spring-boot/tree/main/initial
./mvnw test -Dspring.profiles.active=test
I have a jar which will be included in spring boot application, I am trying to do an integration test in this, the project has the configuration class for creating the data source and JDBC template, I am using testing,
There is no application class in this project when this jar included in another project that project fetches data perfectly fine but not in same project
spring-boot-starter-test is added as a dependency
Configuration
#Configuration
public class DatabaseAccesManagementConfig {
#Bean(name = "accessmngmtDataSource")
#Qualifier("accessmngmtDataSource")
#ConfigurationProperties(prefix = "accessmngmt.datasource")
public DataSource accessmngmtDataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "accessmngmtJdbcTemplate")
#Qualifier("accessmngmtJdbcTemplate")
public JdbcTemplate accessmngmtJdbcTemplate(#Qualifier("accessmngmtDataSource") DataSource accessmngmtDataSource) {
return new JdbcTemplate(accessmngmtDataSource);
}
}
Dao class
#Repository
public class ResourcePrivilegesDao {
static final Logger log = LoggerFactory.getLogger(ResourcePrivilegesDao.class);
#Autowired
#Qualifier("accessmngmtJdbcTemplate")
private JdbcTemplate jdbcTemplate;
public List<RP> getAll() {
log.debug("entering getAll()");
String sql = "SELECT * FROM rp";
RowMapper<RP> rowMapper = new RPRowMapper();
List<RP> result = this.jdbcTemplate.query(sql, rowMapper);
return result;
}
}
Test class
#SpringBootTest
#TestPropertySource(locations="classpath:application-test.properties")
#ContextConfiguration(classes = DatabaseAccesManagementConfig.class)
public class ResourcePrivilegesDaoTest {
#Autowired
DatabaseAccesManagementConfig databaseAccesManagement;
#Autowired
ResourcePrivilegesDao dao;
#Test
public void testGetAll() {
System.out.println(databaseAccesManagement);
List<ResourcePrivileges> list = dao.getAll();
Assert.notNull(list, "No resource privileges found");
Assert.notEmpty(list);
}
}
test property inside
environment=test
#Access management db details
accessmngmt.database.url=//xxyyy/am
accessmngmt.database.username=user
accessmngmt.database.password=password
In the test class, you missed the #RunWith(SpringRunner.class) which configure a unit test that need Spring's DI.
Take a look for the doc spring unit test
In order for the unit test to run a batch job, the framework must load the job's ApplicationContext. Two annotations are used to trigger this:
#RunWith(SpringJUnit4ClassRunner.class): Indicates that the class should use Spring's JUnit facilities
#ContextConfiguration(locations = {...}): Indicates which XML files contain the ApplicationContext.
Notice that, the SpringRunner is an alias for the SpringJUnit4ClassRunner. So we can use #RunWith(SpringRunner.class) instead of #RunWith(SpringJUnit4ClassRunner.class) with a shorter name.
Updated:
For the datasource properties injection, The #EnableConfigurationProperties annotation should annotated on the Test class.
Also, you use accessmngmt.datasource in DatabaseAccesManagementConfig class, while the prefix is not matched accessmngmt.database in application-test.properties. Here you must unify them, so you can inject the properties into the bean.
Test Class:-
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { WebsocketSourceConfiguration.class,
WebSocketSourceIntegrationTests.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"websocket.path=/some_websocket_path", "websocket.allowedOrigins=*",
"spring.cloud.stream.default-binder=kafka" })
public class WebSocketSourceIntegrationTests {
private String port = "8080";
#Test
public void testWebSocketStreamSource() throws IOException, InterruptedException {
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
ClientWebSocketContainer clientWebSocketContainer = new ClientWebSocketContainer(webSocketClient,
"ws://localhost:" + port + "/some_websocket_path");
clientWebSocketContainer.start();
WebSocketSession session = clientWebSocketContainer.getSession(null);
session.sendMessage(new TextMessage("foo"));
System.out.println("Done****************************************************");
}
}
I have seen same issue here but nothing helped me. May I know what I'm missing ?
I have spring-boot-starter-tomcat as compile time dependency in the dependency Hierarchy.
This message says:
You need to configure at least 1 ServletWebServerFactory bean in the ApplicationContext, so if you already have spring-boot-starter-tomcat you need to either autoconfigure that bean or to do it manually.
So, in the test there are only 2 configuration classes to load the applicationContext, these are = { WebsocketSourceConfiguration.class, WebSocketSourceIntegrationTests.class }, then at least in one of these classes there should be a #Bean method returning an instance of the desired ServletWebServerFactory.
* SOLUTION *
Make sure to load all the beans within your configuration class
WebsocketSourceConfiguration {
#Bean
ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
}
OR also enable the AutoConfiguration to do a classpath scanning and auto-configuration of those beans.
#EnableAutoConfiguration
WebsocketSourceConfiguration
Can be done also at the Integration Test class.
#EnableAutoConfiguration
WebSocketSourceIntegrationTests
For more information check the SpringBootTest annotation documentation
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html
in 2.0.5.RELEASE i faced a similar issue when I had the following.
package radon;
..
#SpringBootApplication
public class Initializer {
public static void main(String[] args) {
SpringApplication.run(Config.class, args);
}
}
package radon.app.config;
#Configuration
#ComponentScan({ "radon.app" })
public class Config {
..
}
Changing the package of Initializer from radon to radon.app fixed the issue.
this is because spring is not able to load the properties file at runtime, i was using spring profiles and wasn't providing the (program or vm) argument at runtime( java -jar application.jar) , adding vm argument of profile resolved the issue for me.
java -jar -Dspring.profiles.active=dev application.jar
or using program argument
java -jar application.jar --spring.profiles.active=prod --spring.config.location=c:\config
For web applications, extends *SpringBootServletInitializer* in main class.
#SpringBootApplication
public class YourAppliationName extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(YourAppliationName.class, args);
}
}
Does anyone know where I can find a sample application where Cucumber is used to test a Spring Boot application through Gradle? I can run the tests fine starting the server on the cmd line and using my IDE, but I need to be able to run them all programmatically on the CI server. I saw the answer on here but that solution did not work for me, most likely because I have multiple step def files.
Here is my setup
build.grade (Mentioned in the other question)
testCompile ("org.springframework.boot:spring-boot-starter-test",
...
"info.cukes:cucumber-spring:${cucumberVersion}")
CucumberTest.java
#RunWith(Cucumber.class)
#CucumberOptions(format = "pretty", features = "src/test/resources")
public class CucumberTest{
}
AbstractSpringTest.java (Extended by all the StepDef files)
#SpringApplicationConfiguration(classes = Application.class)
#RunWith(SpringJUnit4ClassRunner.class)
#Ignore
public abstract class AbstractSpringTest
{ ... }
It's not doing the correct thing on start up because its 1. trying to initialize my step def files and 2. My application is not started and the cucumber tests cannot make a connection.
Thanks.
EDIT: Or if someone can tell me how to start and stop the application using gradle, that would be acceptable as well.
I have solved the issue with some help from this question.
Here is the repository with the answer:
https://github.com/jakehschwartz/spring-boot-cucumber-example
In short, the AbstractSpringTest class needs to have the following annotations:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = DemoApplication.class, loader = SpringApplicationContextLoader.class)
#WebAppConfiguration
#IntegrationTest
I had a similar symptom, my cucumber wouldn't start up the Spring context...
Turns out I had missed (one of) the following dependencies:
build.gradle
testCompile "info.cukes:cucumber-junit:1.2.4"
testCompile "info.cukes:cucumber-java:1.2.4"
testCompile "info.cukes:cucumber-spring:1.2.4"
StepDefs.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(
loader = SpringApplicationContextLoader.class,
classes = Application.class
)
#WebIntegrationTest(randomPort = true)
public class StepDefs {
#Value("${local.server.port}")
int port;
}
Update: SpringBoot 1.5.1
#ContextConfiguration(
loader = SpringBootContextLoader.class,
classes = Application.class
)
Further to #jakehschwartz, if you want the web app to start on a random available port, AbstractSpringTest needs:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
#WebIntegrationTest({"server.port=0"})
public abstract class AbstractSpringTest {
#Value("${local.server.port}")
protected int serverPort;
...}
I did something like this to get Spring to work with JUnit parameterized tests. It should be the same concept for Cucumber, but I haven't tried it. I was using XML configuration, so that might make a difference.
RunWithSpringJUnit4
public abstract class RunWithSpringJUnit4 {
private TestContextManager testContextManager;
public RunWithSpringJUnit4() {
try {
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
CucumberTest
#RunWith(Cucumber.class)
#CucumberOptions(format = "pretty", features = "src/test/resources")
public class CucumberTest extends RunWithSpringJUnit4 {
}
First, you'll need to ensure that you have applied spring-boot in gradle. Invoke gradle build which will produce a runnable jar. Instead of having your manifest call for the Spring class as your main, have a wrapper that starts it in a thread, waits for it to settle down and runs Cucumber:
#RunWith(Cucumber.class)
public class LucasePsCucumberTest implements Runnable {
public static void main(String[] args) {
Thread t = new Thread(this);
t.start();
// wait for t
cucumber.api.cli.Main(null);
}
}
I am attempting to test my #Service and #Repository classes in my project with spring-boot-starter-test and #Autowired is not working for the classes I'm testing.
Unit test:
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(classes = HelloWorldConfiguration.class
//#SpringApplicationConfiguration(classes = HelloWorldRs.class)
//#ComponentScan(basePackages = {"com.me.sbworkshop", "com.me.sbworkshop.service"})
//#ConfigurationProperties("helloworld")
//#EnableAutoConfiguration
//#ActiveProfiles("test")
// THIS CLASS IS IN src/test/java/ AND BUILDS INTO target/test-classes
public class HelloWorldTest {
#Autowired
HelloWorldMessageService helloWorldMessageService;
public static final String EXPECTED = "je pense donc je suis-TESTING123";
#Test
public void testGetMessage() {
String result = helloWorldMessageService.getMessage();
Assert.assertEquals(EXPECTED, result);
}
}
Service:
#Service
#ConfigurationProperties("helloworld")
// THIS CLASS IS IN /src/main/java AND BUILDS INTO target/classes
public class HelloWorldMessageService {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message=message;
}
}
The commented class annotations on the unit test represent the various things I've tried to get this working. The test and the project packages are in the same package paths and the #ComponentScan works fine from my entry point (#RestController class with main method). The service #ComponentScan's and #Autowire's fine in my #RestController class in the src/main/java side, but does not in the test. I am required to add it again as a #Bean in my #Configuration class in order for #Autowired to work. The class is otherwise in scope just fine and I can reference and instantiate it just fine from the test. The problem appears to be that #ComponentScan does not appear to correctly traverse multiple entries in my test runner classpath, in this case /target/test-classes and /target/classes.
The IDE I am using is IntelliJ IDEA 13.
UPDATE - here are HelloWorldRs and its config:
#RestController
#EnableAutoConfiguration
#ComponentScan
public class HelloWorldRs {
// SPRING BOOT ENTRY POINT - main() method
public static void main(String[] args) {
SpringApplication.run(HelloWorldRs.class);
}
#Autowired
HelloWorldMessageService helloWorldMessageService;
#RequestMapping("/helloWorld")
public String helloWorld() {
return helloWorldMessageService.getMessage();
}
}
...
#Configuration
public class HelloWorldConfiguration {
#Bean
public Map<String, String> map() {
return new HashMap<>();
}
// This bean was manually added as a workaround to the #ComponentScan problem
#Bean
public HelloWorldMessageService helloWorldMessageService() {
return new HelloWorldMessageService();
}
// This bean was manually added as a workaround to the #ComponentScan problem
#Bean
public HelloWorldRs helloWorldRs() {
return new HelloWorldRs();
}
}
First, I'd recommend to use a newer #RunWith(SpringRunner.class) but that makes no difference, it is just shorter (and recommended).
Second, from the #EnableAutoConfiguration I see that you are using spring boot - which is certainly a good thing. There are some good reasons why not to use #ComponentScan directly. Can you try the following?
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(classes=YourApplication_or_other_Configuration.class)
public class HelloWorldTest {
... etc.
I don't know if this will turn out to be the solution, but don't use the default package (i.e. don't put *.java in "src/main/java" directly), and definitely don't use a #ComponentScan or #EnableAutoConfiguration in the default package. You will end up killing your application on startup as it tries to scan everything on the classpath (including all the Spring libraries).
SpringBoot 2.7.3, JUnit 5.8.2
If you want to have full control about the spring's configuration (and not rely on the hidden magic of auto configuration) I suggest to create an explicit configuration class:
#ComponentScan(basePackages = { "my.package.to.scan" })
public class MySpringTestConfig
{
// just for spring configuration annotations
}
and reference it in your test class:
#ContextConfiguration(classes = { MySpringTestConfig.class })
#ExtendWith({ SpringExtension.class })
class MySpringTest
{
...
}