How to use JUnit with Eclipse - java

I am a long time user of Eclipse but a novice when it comes to JUnit. I have lots of java projects and I want to start writing test cases around the methods in those projects. I'm just wondering the best way to set up the Eclipse environment for this purpose. Let's assume I have a typical project with a typical src directory in a specified package. How do I attach test cases to that project. Some concerns:
1. I don't want the test cases to be part of any build that I create on the project.
2. I want to refer to the clases in the test-suite.
Do I set up a separate test directory under the package I want to test? Do I have a separate test package? What is the best way to do this?

It's pretty dead simple:
Drag or otherwise place the JUnit jar file into your lib folder, then
modify your projects build settings to include it.
Create another source folder under your project called 'test'
Create your test packages underneath the 'test' source folder. Best
practice is to mimic the package names of your application.
Create your test classes inside of the test packages. Best practices
is to mimic your application classes that require testing, but append
Test at the end of the name. So for example in your main application
you might have a myapp.service.PrintService and as a corresponding
test you would have myapp.service.PrintServiceTest
Extend each test class from junit.framework.TestCase
Run your test classes using TestRunner.
When you build your application's deployment bundle just exclude the 'test' source folder. Now, if you want really drop dead easy test integration then use Maven to setup your project. It bakes in all the best practices for you right off the bat.

The best (or at least the most common) way to organize the test code it is to have a separate source folder for the test code, thus keeping it nicely separated. In eclipse, you can add source folders under "Build Path" in the project's properties.
However, it is also a good idea to keep your test classes in the same packages as the classes to be tested (i.e. have the same package hierarchy in the test source folder). This allows you test code to call package private and protected methods, making it much easier to test internal behaviour that should not be exposed in the public API.

A simple solution would be to create another source directory specifically for test-related classes. For example, if your main classes live in $PROJECT_ROOT/src, you can put your test-related classes in $PROJECT_ROOT/src-test. I don't have Eclipse handy, but I know that you can modify the $PROJECT_ROOT/.classpath file (it's XML) to include this new directory:
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src-test"/> <!-- ADD THIS ONE -->
...
</classpath>
Now, all your test classes will see the main classes, but they won't be included in your build. I typically make sure that the test class lives in the same package as the class it's testing. That way, any protected members can be accessed from the test code.

Related

Java, IntelliJ, maven project - importing issues

This might be a silly question, but I need to know. I'll delete it if it's too silly to answer.
In a maven project in IntelliJ, I have the following structure:
procedure
e2e
cucumber (same level as common)
src
test
java
e2e
support
File: ScenarioState.java
package e2e.support
common (same level as cucumber)
src
main
java
common
testdata
File: Case.java
package common.testdata
Is there any way to import the package e2e.support (where ScenarioState.java resides) into the file Case.java in the common.testdata package?
I've been playing around with maven imports, dependencies etc., but I haven't found a way to do it. I might have to redesign some classes to get around it, but that would impact other parts of the project and I'd like to avoid it if possible.
If you really want to do that (and I would strongly recommend to either leave the project alone or restructure it first), define an additional source directory as in
How to add an extra source directory for maven to compile and include in the build jar?
But beware that a project like this will haunt you till the end of time.
One could have in the common's pom.xml a dependency to cucumber with <type>test-jar</type>.
However this violates the concept of src/main for the final product, and src/test for the unit-tests (not incorporated in the product, separate test classes).
(In src/test there can be other classes, so maybe easiest would be for common to have a src/test instead.)
If ScenarioState has nothing to do in src/main, one could place it in a more low-level library cucumberbase in src/main. And make a dependency in cucumber to cucumberbase with <scope>test</scope>. In <common> a normal dependency to cucumberbase.
Keep this main-test separation as otherwise other developers risk insanity.

Running a code with JUnit Test Cases

I have checked out a code from CVS and need to make changes to it. The code has 2 folders
Java
Test
The later has JUnit test cases. I'm not very familiar with JUnit but as far as my understanding is, the classes are duplicated in JUnit as class names. That's why I get the error in the test folder.
Class "xxxxx" already exists
I'm not sure how do I run this project without removing the folder test. Is there a way I can make eclipse ignore the JUnit test cases for now?
Go into the properties of the Eclipse project, open Java Build Path / Source and remove folder Test. Eclipse will then ignore the sources in that folder.
Test and normal java classes are merged together during build time, your error happens because the test classes have the exact same name as the normal classes. You should rename your test cases with some kind of prefix like Test to prevent them conflicting.
Doing things to work around the problem will only conflict later when you are changing the build platform, maybe your current build platform accepts it, but your future platform/editor may not, and then you have the real problems.

Java autogenerated getters-setters in project - best practice

Our project has started newly and wanted to know some of the best practices followed in industry. We have generated lot of DTOs(getters and setters) code for webservices using JaxB. we keep all the DTO classes along with regular pojos(logic written), its looks like large project due to this auto-generated code, also for code coverage it considers these classes also.
I am keen to know that these classes should be as a jar file in classpath or it should be as classes in project.
Thanks in Advance,
Madhavi
If your project uses Maven (or something similar) I would advise having the code generation and the generated code in a separate module of a multi module project.
This way the generated stuff is out of the way of the hand crafted code. You can also set up your Maven build process to then build this module first and the rest of the code can rely on the resulting artefact, be it a jar or something else.
You could also regenerate the generated code on each new build this way. Although this can be a lengthy process, depending on the service.
Generated files should not be mixed with your written files.
A common approach is to generate them to the target folder, e.g. target/generated-sources or something similiar. Of course, if they are rarely changed, you could also put them in a jar file that you import into your project.
I think its better to keep them in jar. As its auto generated code and no one is supposed to change. Whenever regenerated include new jar.

Running testing class from jar package in NetBeans

I have like 30 Java classes and 1 class for testing in a jar package.
To run the testing class, I need to create new NetBeans project , import all those 30 classes into /src , then import 1 testing class into /test and maybe add some libraries to the project also...
So that, after all I will be able to run the testing class...
Is there some other way to do it?
I open the jar package in NetBeans and see all the classes but it doesn't let me run the testing class since there is no main method in there..
A bunch of ways. If you're in NetBeans, and the class has a public static void main() method you can just right-click it and choose Run File.
But you're far better off writing your test as a JUnit or TestNG test - that way it is not included in your production bits, and continuous build tools and other things will be able to run your tests automatically because they look the way those tools expect.

Java: Resolve namespace conflict

We have a jar that we lost the source code to. I decompiled the jar and created new source from it. I want to then verify that the source code and the old jar have the same behavior. I am writing unit tests to do the verification the problem is that they both have same namespace / class name so I do not know how to disambiguate the old jar and the new source code. What can I do or is it impossible?
You need to only have one version on the class path at once to guarantee that you are running that version of the code. Develop your unit test separate from the code so you can drop in either version.
Give the new source a temporary namespace for testing purposes. Then instead of import, you can refer your new classes as:
com.yourfirm.test.packagename.TheClassName
the old ones can be simply imported and refered to as TheClassName. This way you can tell by looking at your test cases which is which.
Or simply run the tests with -cp oldpackage.jar and then -cp newpackage.jar.
It's possible, but you have to mess around with class loading. Instead of putting either of the jars on the classpath, you'll need to load them at runtime. Check out JCL for a library to allow you to do this. (Disclaimer: I have never used JCL.)
Basically, each test would have to load the class from the old JAR, grab the results of the method you're testing, then unload that JAR, load up the new one, run the same method against the new version, and compare the results.
I'd change which classes are being tested at runtime with the classpath. This approach would be less error-prone in terms of ensuring that you're running the same test code against both binaries. Otherwise you introduce more complexity around whether the tests are correct.
It sounds like you are trying to execute the tests against both jars at the same time. I don't know of a way to disambiguate the old/new jars if they are both in the classpath.
If your unit tests output results to stdout/stderr, you could run the tests against the original jar and save the results. Then run the tests against the new jar and save the results in a separate file. Then diff the files.
Another approach would be to refactor the new source code so that it has a unique namespace. You could then test against both jars at the same time, but it could be a lot of work to make existing programs use the new jar.
If you run your tests via ant (Junit-task), you can control the ant classpath seperately for both runs (once via jar, once via fileset of classes).

Categories