I'm trying to test a method with #SpringBootTest and #ActiveProfile("test") in my class. When I run the new tests, everything works fine and the properties are loaded from the test YML file correctly. But when I run all tests, those same tests load the properties from the production YML file.
I've tried using #DirtiesContext, with BEFORE_CLASS and BEFORE_EACH_METHOD flags, on the new test class but it doesn't seem to help.
I have something similar to the following:
#ActiveProfiles("test")
#SpringBootTest
public class NewTestClass{
...
#Test
public void testThatLoadsPropertiesAndShouldLoadApplicationTestYmlFile() {
...
}
}
What am I missing here? is there a simple way of solving this problem?
UPDATE
I disabled the other Integration Tests on the project using #Disable from Junit 5 and checked if the problem persisted. surprisingly, it did. So I'm suspecting it is not an ApplicationContext caching problem.
Having the problem description provided I can only suggest the that there might be another test suite configured so that the context is setup using the production config (yml). Please consult this answer (the question raised is similar in a way...): https://stackoverflow.com/a/43332643/8085853
Ok, I believe I found the cause of the problem. I'm running all tests using IntelliJ, but "all tests" is being managed by the JUnit plugin and the single tests are being managed by the Gradle plugin. Once I used gradle to run "all tests", everything worked.
Related
I'm working on multi-module maven project using Spring Boot 2.4.0. I have written integration tests for a module. The test class looks similar to this.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringApplicationClassWithMainMethod.class)
public class XYZServiceIT {
#Test
public void test1() {...}
#Test
public void test2() {...}
}
To run the SpringApplicationClassWithMainMethod.class i.e., in order to load the Application context I need few environment variables that I set in eclipse. So, in order to run the above integration test while loading the SpringApplicationClassWithMainMethod.class I need those environment variables before the Application context is loaded.
Trial-1:
I have tried using #TestPropertySource(properties = {"key1=val1", "key2=val2"}) annotation, that didn't work.
Trial-2:
I have also tried the static block to set environment variables which didnt work.
Trial-3:
I also tried using the #ContextConfiguration with a ApplicationContextInitializer class, that didnt work as well.
All these attempts to build the project using maven only lead to a
IllegalState Failed to load ApplicationContext
error for the above test class. Is there any way I could load the environment variables before the Application context gets loaded?
I think the correct class naming convention for Integration tests in maven would be XYZServiceIT since *Test is reserved for unit tests already which are run before application context. You can change that if needed in your maven pom or simply stick with the conventional naming.
UPDATE
To pass environment variables to maven for your integration test use the following:
make sure you installed M2E from eclipse marketplace (found in menu > help > eclipse marketplace)
right click your project > Run As ... > 4 Maven Build ...
PS: afterwards you can find your run configuration at the top underneath the dropdown of the green arrow and in the run configuration settings if you need to rerun the tests in the future
configure maven environment parameters either inline (for the maven goal command) with verify -Dkey=val or in the bottom variable section. both work for unit and integrationtest. environment typically does NOT work for test stage. (If you don't have an JDK as the runner you will get an error. Follow this post to fix it if needed: No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?)
I hope that helps. You can also change pom.xml profiles if needed but i wouldn't recommend that.
This question is more of a best practices approach. The application we have is Spring Boot 1.5.4 and builds using Gradle. I'm in the process of creating nightly builds with Jenkins, and want to make sure all the unit tests pass in the project.
The project has a number of "tests" like this however:
#SpringBootTest(classes = {Application.class})
#RunWith(SpringRunner.class)
public class DatabaseCreationProcessImplTest {
This particular class creates a sample database image for developers to work off of. Granted we could make straight SQL scripts, but a Java process is useful since there's code that also queries for data from outside sources (e.g. Liferay.)
The reason we're using a unit test for this is because developers can easily run it in IntelliJ to load a new database image. However this isn't really a "test", it's using the test runner as a quick way to run a Java process.
I'm working on setting up nightly builds and I don't want this test to be included in the builds. I can do something like the following in the build script:
test {
exclude 'com/mydomain/service/util/impl/DatabaseCreationProcessImplTest.class'
}
However by doing this, if running the unit test individually in the IDE with the Spring test runner, it is unable to find any tests. I thought about passing in a Boolean value in the Jenkins task for doing this, e.g.
test {
systemProperties 'property': 'value'
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
}
// Exclusions go here
if (Boolean.getBoolean('exclude.tests')) {
exclude 'com/mydomain/service/util/impl/DatabaseCreationProcessImplTest.class'
}
}
However this seems like a hack/kludge... any ways looking for some "best practices" approach for handling this. Is JUnit the right way for quickly running Java processes? Are there other alternatives? Is it possible to create a Gradle script which developers can use to invoke common Java (Spring Boot) process as well?
I think you could group your not-really-tests in a test suite with JUnit's #SuiteClasses annotation:
#Suite.SuiteClasses(DatabaseCreationProcessImplTest.class)
public class NotReallyTests {}
And then use a condition that you pass from your Jenkins command line to exclude the not-really-tests suite:
test {
if (project.hasProperty('excludeNotReallyTests')) {
useJunit {
excludeCategories 'fully.qualified.name.of.your.NotReallyTests'
}
}
}
Your Jenkins command line would then be
$ gradle -PexcludeNotReallyTests=true
It's a little less hacky than your solution in that it keeps track of the grouping of tests that are not really tests in the codebase instead of the build.gradle file.
The Testing API for Android provides several annotations that are used to group tests together. Then you can specify which tests to run by giving one of the annotations on the command line. I do not know the details of how to implement this. It is just a suggestion for you to explore on your own, if you are interested.
I am experiencing a strange behavior of Intellij IDEA 2016.3. Having a class with method foo and a JUnit test for the method when I get java.lang.Exception: No tests found matching Method foo when running the test. After I do mvn test it succeeds and then running the unit test right after executing mvn command it suddenly runs green. Seems like IDEA does not compile automatically. How can I fix this?
P.S. No settings were altered after upgrading to v. 2016.3
If you're using a theory testing framework like Junit's or Robolectric's, make sure to run the class containing the test you want, instead the test itself. Since these frameworks use the test methods as instance methods instead of static methods, any testing framework looking for a normal public static test won't find anything.
The same issue i got with Gradle (4.5+) + new Build Cache feature
Sometimes it's unable to find new test methods and throws exception (like you mentioned in topic)
Solution: clean .gradle, build and out directories and try again ;)
Well, after "playing" a bit with run configurations of each unit test I noticed that each Run Config has a Build goal preset in the Before Launch option (See pic below):
After changing Build to Build Project the tests run fine.
If you originally run a test named "foo", and then rename it to "fooBar", you must subsequently run "fooBar" with a new Run Configuration.
If you use the same original Run Configuration for "foo" to run "fooBar", it still looks for a test named "foo" which it does not find (thus the Exception) because it was renamed to "fooBar". The new Run Configuration would correctly look for "fooBar" test.
I made this mistake unknowingly because I renamed a test, but then just clicked the green run button in IntelliJ: Doing that runs the last Run Configuration, which in this scenario has the old "foo" name.
Deleting Intellij's out directory fixed this issue for me.
In addition to the other answers here: the error can also happen when you forget #Test before your test method declaration. IntelliJ (2018.1) will still show you the green "Play-Button" for test execution, but that public method in your Test-Class will not be an actual test.
Make sure that your #test methods as well as the test class are public.
Since you got your answer and for others searching for solution,
Look if your test class is extending TestCase abstract class which is a JUnit 3 related. In order to fix this you have to start your method name with "test".
For example public void testFoo().
If JUnit 3 is not the case, you're missing #Test annotation from your JUnit 4 test method.
Note: If you're extending from TestCase and test methods are annotated with #Test and also your methods' names start with "test", then probably you're mixing JUnit 3 with JUnit 4. Don't do that. It will lead to other errors such as methods that annotated with #Ignore will not be ignored if those methods' names start with "test".
This situation can also occur if you do not place #Test annotation above the test method.
Maybe you just give a wrong name for test method.
I met this problem because I used '—' instead of '_' which intelliJ cannot represent.
I had to add test before the test Method Name.
methodtest() does not work but testMethod() worked
Make sure #org.junit.Test is added on top of your method. I forgot them and that fixed it for me!
Make sure you've correct runner mentioned above your class.
I was getting this weird message when I was using runner CucumberWithSerenity.class. When I changed to SerenityRunner.class it got fixed.
#RunWith(SerenityRunner.class)
//#RunWith(CucumberWithSerenity.class)
public class WordPressAppTest {
I'm using Serenity framework for web automation and use below runner class
import net.serenitybdd.cucumber.CucumberWithSerenity;
import net.serenitybdd.junit.runners.SerenityRunner;
import org.junit.runner.RunWith;
I feel IDEA ( 2017.2.6 ) can show some better error message than this
You may check that Run/Debug Configurations in the top of the IntelliJ screen.
Delete all of then with the "minus button" and hit "run" green button again to run the test.
You may reload the project on the maven tab on the right as well.
In my spring mvc project. I solved this problem by adding
#RunWith(SpringJUnit4ClassRunner.class)
to my test class.
In my case, I copied a test from another class and modified it, but while running the test it was still pointing to the previous one.
Build > Clean Project solved the problem
I am trying to run individual spock unit tests using intellij idea.
Consider:
// rest of code
def "Test Something"() {
// test code below
}
In above test, when I goto the test body and right context menu, I get two kinds of tests for Test Something. One is the grails test and other is the junit test.
Referring to this question, the accepted answer recommends using the jUnit runner. But using it, the code simply does not compile(probably because certain plugins and other classes are not available).
(I am not sure though as this is the desired behavior because I am just running a single test and not all tests. So wonder why is it compiling all classes ,including plugin classes not required by the test target class.)
Using the grails runner, I check the configuration and here is the screenshot:
So nothing looks wrong with the command there.
But the test on running gives Test framework quit unexpectedly error.
I try running same command from grails console(CMD windows) and it runs without any error message.
But on checking the output html files(in target/test-reports) I see that none of the tests actually ran!
So what is going on here and why are not individual tests running?
PS:
When I run All tests using test-app command, tests run as expected. Only individual (unit)tests are not running.
Part of the price paid for Spock's nice test naming, is that you can't specify an individual test to run anymore.
Here are some articles about it. The first seems pretty on-point:
Run a specific test in a single test class with Spock and Maven
This one isn't about running a single test, but has some relevance and talks about Spock's test-name conversions, plus Peter Niederwieser chimes in with comments:
Can TestNG see my Spock (JUnit) test results?
A workaround for this could be the #IgnoreRest annotation. Simply annotate the test you want to run with #IgnoreRest, and then specify that test class to run, and only the annotated test will run. http://spockframework.github.io/spock/javadoc/1.0/spock/lang/IgnoreRest.html
Try using the grails unit test and add the following in the command line part:
-Dgrails.env=development
This will run the test as we change the running environment to development . Hope this will help to everyone facing such problems.
Our test suite is growing quickly and we have reached a point where our more functional tests are dependent on other systems.
We use gradle test tasks to run these tests using the include and exclude filters but this is becoming cumbersome because we are having to name our tests in a particular way.
Our current approach is to name our tests in the following way:
class AppleSingleServiceTest {}
class BananaMultiServiceTest {}
class KiwiIntegrationTest {}
and then include tests in the relevant task using
include '**/*SingleServiceTest.class'
include '**/*MultiServiceTest.class'
include '**/*IntegrationTest.class'
Is it possible find test classes in gradle by looking at annotations?
#SingleServiceTest
public class AppleTest {}
I think any tests that are not annotated would then be run as normal unit tests, so if you forget to annotate a more functional test it will fail
An example of a single service test is a selenium test where any external dependencies of the SUT are stubbed
An example of a multi service test is one where some but maybe not all external dependencies are not stubbed
As of Gradle 1.6, Gradle supports selecting tests with JUnit #Category, like this:
test {
useJUnit {
includeCategories 'org.gradle.junit.CategoryA'
excludeCategories 'org.gradle.junit.CategoryB'
}
}
More details can be found in the docs.
The feature you are asking for doesn't currently exist, but you can make a feature request at http://forums.gradle.org. Or you can use the (cumbersome) JUnit #Category, which requires you to define test suites.
I had a similar need to filter tests with annotations. I eventually managed to create a solution. It is posted here.