Eclipse junit testing in the same project - java

This is a relatively open question. If I have built an application in a project in Eclipse and I then want to test this project, should I create the JUnit code within the same project or create a separate project. For instance...
ShopSystem maybe the name of my main project - should I create a project called say, ShopSystemTest?
In general - how far "away" should the testing code be stored from the main project folder? If I store the testing code within the main project and then export the main project as a runnable jar it will take the testing code with it, which isn't ideal...
Suggestions?

While there is no only right way, the usual approach is to keep unit tests in the same project.
You can create a second source folder (like test), where you put your test classes into the same packages as the classes under test. This also allows you to test package-private classes while not flooding your main source packages with test classes.
Your source folder/package structure would then look like this:
-sources
-main
-my.package
-MyClass.java
-test
-my.package
-MyClassTest.java
You can then configure your build to not include the test source folder when packing the JAR.

I like the maven convention a lot: There is a separate source tree for main and test in the same project, main code gets deployed, test code doesn't. Package structures can be (but don't have to be) identical.
project
src
main
java // source files
resources // xml, properties etc
test
java // source files
resources // xml, properties etc
And in eclipse, when you choose new -> JUnit test case, you just change the source folder to src/test/java and leave the suggested package as is.
(One of the benefits of remaining in the same package is having access to protected and package scoped members, although this is not 'proper' unit test behavior)
Update: Here's some code to illustrate my last point:
Main class (in src/main/java):
package com.test;
public class Foo{
static class Phleem{
public Phleem(final String stupidParameter){
}
}
String bar;
protected String baz;
protected Object thingy;
}
Test class (in src/test/java):
package com.test;
import org.junit.Test;
public class FooTest{
#Test
public void testFoo(){
final Foo foo = new Foo();
foo.bar = "I can access default-scoped members";
foo.baz = "And protected members, too";
foo.thingy = new Foo.Phleem("And I can access default-scoped classes");
}
}

Typically you have -
/src/main/java (for codes)
/src/test/java (for tests)

Consider the maven way : In a maven project, soruces are organized this way
src
|--main
| |--java
|--test
|--java
Your source code goes in src/main/java, your junit test code goes in src/test/java, they both are source folder (and as a consequence you can put your jUnit code in the same package as your Java code, but in a different source folder).
The interest is that for usual coding, your jUnit classes are in code packages, but on jar creation, you can take classes coming only from src/main/java and not release your tests.

Related

How to detect a nested Unit Test classes (not under test folder) in Java

I know that it's quite hard to test many features of Java language. For example, it would be impossible to test a private variables of a class or similar methods.
I generally tackle this by making a nested class, where this nested class is a unit test, such that :
public class MyClass{
private String somePrivate;
// omitted for brevity
#RunWith(MockitoJUnitRunner.class)
public static class MyClassUnitTest{
#InjectMockito
MyClass myclassMocked;
// so forth...
}
}
thus no need for reflection/powermock or others!
This structure helps me to test all unreachable members or methods of a class.
But it appears that i also should make an automated build where maven will look up this nested classes for unit tests and run it when i mvn clean test in the deployment.
I've been trying to find any answer on this but to no avail i couldn't find any spec of maven or maven-surefire-plugin to say that 'hey please look at these nested classes in the src/main folder and mark them as unit test'. Also, i am using springboot to package all of my project (thus most of the dependencies are with spring)
Anyone up for solution?
For example, it would be impossible to test a private variables of a class or similar methods
You don't need to do this - private methods are private, and they are indirectly tested by testing methods that use them.
You should not be embedding test code or libs such that they have to ship with production software, period.
Don't do what you are proposing.
Edit based on your comment:
As for how you would do it technically, Maven only supports 1 directory for test sources.
You could do something like create an integration test setup that would find the tests in your src/main directory, but the reason this is not easy to do with Maven is because Maven promotes sane patterns and your pattern is not one of those.
Howto add another test source folder to Maven and compile it to a separate folder?

Exporting multiple JUnit classes into single executable jar

I am trying to export JUnit classes into 1 executable JAR. I can't do this because it doesn't have a main.
What I have tried:
I tried making a testingSuite but that did not work as well. I can run the JUnit class from Eclipse, I can also run the testingSuite - and it calls all JUnit classes I tell it too - they work fine in eclipse. Note, I had to go down to JUnit4 to use the testingSuite. Since I could not export the testingSuite either, I tried making a new class with one main method that calls the testingSuite, I cannot get this to run from Eclipse.
I have been going through Stack overflow and other sites for about 2 days, so now I will post =).
Anyone know how I can export multiple JUnit test classes into 1 executable Jar that can run all the classes when it is opened?
If you're goal is to run some selenium tests and if your tests arn't too big, why not use selenium ide (firefox plugin, and here for chrome)?
It depends on if you want these tests to be maintainable and evolutive but if they're just there to check things still work, give it a try. Plus it will allow your BA to write their own tests. No need to know about programming, just click. Sort of.
This whole end to end test thing is very expensive to maintain but if your app doesn't evolves too much on the surface (its UI) then it might be worthy.
For an in depth article about testing in general, including testing pyramid, read this by Martin Fowler, it's very good.
I was able to make it work by having a regular class call my Test Suite Class which calls my JUnit Test Classes. I don't know why it wasn't working before, but this time when I tried to export and there was a new option there.
Solution Below
JUnit test suite class (runs all the test classes I put into #SuiteClasses, called by 'TestRunner' class)
package myPackageName;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({ TestClass1.class, TestClass2.class })
public class AllTests {
}
TestRunner Class, the class that is exported into the executable jar. This was the missing piece, without it, export would not work.
package myPackageName;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(AllTests.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
Export Steps
Click File, Click Export
Open java Folder, Click 'Runnable JAR file', Click next
Launch Configuration drop down shows an option 'myPackageName - TestRunner'. This is where I was able to pick the class that contains the main method that will be run by the JAR. (the issue I was having before, it wasn't there and if I selected other classes that appeared it gave an export error).
I used the 'package required libraries into generated JAR' option for library handling, I think its correct because I have selenium libraries.
Click Finish
Run JAR by opening windows explorer and clicking it. Or, open CMD, cd to file directory, and run java -jar myJarName.jar.

How to execute an individual JUnit test from its corresponding test resources

For each of the class, we have a corresponding test class and test resource. For example, for class Example.java under src/main/java, we have test class TestExample.java under src/test/java and resource directory called Example under src/test/resources.
I can run all test cases directly from test resources if they share the same directory structure. I can execute on test resource directory under src/test/resources and IntelliJ will automatically launch all test classes under the same directory path under src/test/java. My question is, how could I make IntelliJ just run one test class on that test directory instead of all the other test classes? If I try to execute on the specific class name, it says 0 test classes found in package, but I can just go to the parent directory and execute, which will execute all the classes within that directory. Is there any way I can execute a single test class within a directory through test resource?
There is likely several ways to do what you want, this is one way:
You need to tell IntelliJ which test you want to run, one way to do that is to click the "Tests" tab to switch the project view to show the tests. You may prefer the "Packages" tab if you work with the resources, it will show a package-centric view grouping your tests and test resources in the same structure.
After that, locate the test, right-click and select "run" from the popup menu.
Since you used an IntelliJ tag on this question, I'm assuming you are using Maven as the lifecycle framework of you project.
Under this assumption, I'd suggest you use the surefire plugin found here
One of the many nice features surefire has is the ability to group tests and run specific test groups only (copied from the content of the link above):
Using JUnit Categories
JUnit 4.8 introduced the notion of Categories. You can use JUnit categories by using the groups parameter. As long as the JUnit version in the project is 4.8 or higher, the presence of the "groups" parameter will automatically make Surefire select the junit47 provider, which supports groups.
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.11</version>
<configuration>
<groups>com.mycompany.SlowTests</groups>
</configuration>
</plugin>
</plugins>
This will execute only those tests annotated with the #Category(com.mycompany.SlowTests.class) annotation and those tests annotated with #Category(com.mycompany.SlowerTests.class) if class/interface SlowerTests is subclass of SlowTests:
public interface SlowTests{}
public interface SlowerTests extends SlowTests{}
public class AppTest {
#Test
#Category(com.mycompany.SlowTests.class)
public void testSlow() {
System.out.println("slow");
}
#Test
#Category(com.mycompany.SlowerTests.class)
public void testSlower() {
System.out.println("slower");
}
#Test
#Category(com.cmycompany.FastTests.class)
public void testSlow() {
System.out.println("fast");
}
}
The #Category annotation can also be applied at class-level.
Check that your test directory is marked as "test root",
see https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000741910--0-test-classes-found-in-package-after-upgrading-to-2017-3
After you open the test class in IntelliJ, you should see a green circle with a small triangle on bottom. It's present on left hand side where the line numbers appear on the editor. If you click on it you should be able to kick off tests for that class only. You can also kick off individual tests within a test class.

Avoid code duplication at test level with Util class

I've got a Java project in Maven with the following (simplified) structure:
module-alpha
src
main
test
java
TestUtils.java <-----------------------
module-beta
src
main
test
java
TestUtils.java <-----------------------
...
module-yotta
src
main
test
java
TestUtils.java <-----------------------
There is a class TestUtils.java repeating itself along the project. (It's a simple class I wrote as a library for needed stuff in every unit test.)
How can I avoid this code redundancy?
You need to create a different maven project that include TestUtils.java and build it as a jar e.g. test.jar.
Then use test.jar as a local dependency of relevant projects.

Cant import src/main/java classes into src/test/java jUnit tests in maven-spring-web project. IDE - Eclipse

I'm working on a maven-spring-web project in Eclipse. I am getting some problem working with jUnit tests, it seems to me a configuration issue.
Project structure:
src > main > java : business logic goes here
src > test > java : jUnit test cases are parked here.
The trouble is that imports are not working when im trying to import some business logic classes from src>main>java into my jUnit test cases. The reason is that the physical folder structure is :
Business logic classes : project_root > src > main > java
Test cases classes : project_root > src > test > java
I've tried cleaning, putting testResources directory in POM. I dont want to add classes folder in classpath. Pls advise.
You can't use default package in src/main/java, try to new a package and you can import the class then.
By default Maven uses the following naming conventions when looking for tests to run:
Test*
*Test
*TestCase
Your test class doesn't follow these conventions.

Categories

Resources