How to execute a JUnit package inside a jar - java

I have a project where a one single package contains all JUnit tests. (But those are not in src/test, but in src/main). In eclipse environment I can select the package and do run as JUnit. Then it will execute classes in alphabetical order. But what I want to do now is to do the same but using the jar i built. How can i do it ? (in command line)

Closest solution to this problem I can think of is to add a suite class to your src code and run the suite from command line. If you want you can use the dynamic classpath search that cpsuite gives you and do the following (this will also be more generic and not involves in adding suite class to your project):
Write a jar with with this class:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.IncludeJars;
import org.junit.runner.RunWith;
#RunWith(ClasspathSuite.class)
#IncludeJars(true)
public class MySuite {
}
Include this jar in the classpath and run something like this from the command line:
java -cp <path-to-where MySuite jar>:<path-to-tested-jar + all its dependencies>:<path-to cpsuite.jar + all its dependencies> org.junit.runner.JUnitCore <full-package-name-to-where-MySuite-is-in>.MySuite

Related

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.

JUnit - Java project structure

I have the following directory structure:
project/hamcrest-core-1.3.jar
project/junit-4.12.jar
project/build/
project/ija/ija2016/HomeWork2Test.java
project/ija/ija2016/homework2/model/cards/Card.java
project/ija/ija2016/homework2/model/cards/CardDeck.java
project/ija/ija2016/homework2/model/cards/CardStack.java
project/ija/ija2016/homework2/model/board/AbstractFactorySolitaire.java
project/ija/ija2016/homework2/model/cards/FactoryKlondike.java
The HomeWork2Test.java was given to us (I cannot edit this one) and contains tests for the other classes. In the header it has these imports:
package ija.ija2016.homework2;
import ija.ija2016.homework2.model.board.AbstractFactorySolitaire;
import ija.ija2016.homework2.model.board.FactoryKlondike;
import ija.ija2016.homework2.model.cards.Card;
import ija.ija2016.homework2.model.cards.CardDeck;
import ija.ija2016.homework2.model.cards.CardStack;
So I made the Card, CardStack and CardDeck classes into a package by specifying:
package ija.ija2016.homework2.model.cards;
in each of the files.
And the AbstractFactorySolitaire and FactoryKlondike have:
package ija.ija2016.homework2.model.board;
Now we are supposed to run the tests in the HomeWork2Test.java class using JUnit. However, when I try to run the following command from the project folder:
javac -cp junit-4.12.jar -d build ija/ija2016/homework2/HomeWork2Test.java
I get errors telling me that the:
package.ija2016.homework2.model.cards does not exist
package.ija2016.homework2.model.board does not exist
I don't exactly understand how to fix the project structure. Also how do I run the JUnit test?
Thank you for replies.
Well I think you are mixing concepts (compiling and running junit tests)
1st you need to compile your Classes (let's compile them to build
dir):javac -d build ija/ija2016/homework2/model/cards/*.java ija/ija2016/homework2/model/board/*.java
2nd you need to compile your test class (you will need to add to classpath what you just compiled and the junit.jar dependency): javac -d build -cp build;junit-4.12.jar ija/ija2016/HomeWork2Test.java
Now you can run your test class (in order to run you need to add to the classpath the build dir and the jar dependencies): java -cp build;junit-4.12.jar;hamcrest-core-1.3.jar org.junit.runner.JUnitCore ija.ija2016.HomeWork2Test
If you want to know more check JUnit 4 Doc
if you are using Linux or MacOS use ":" instead ";" between dirs in classpath

How do I email java files to someone and have javac compile correctly?

I have several class files in a project (residing in the default package). My teacher needs me to email him the java files only, and these files need to compile on his computer without errors. To test this out, I copied my class files to another folder and ran javac myself. I get errors when I try to compile that say package org.junit does not exist import static or.junit.Assert.*; There are other errors as well but I'm assuming they're probably related to that first one.
Most of the class files in my directory are indeed test classes that I'm using to test methods with JUNIT. What files do I need to include or what changes do I need to make so that anyone could simply use javac and compile my java files?
Here's a sample of one of my classes:
import static org.junit.Assert.*;
import org.junit.Test;
public class SetRadiusTest {
#Test
public void test() {
Circle test = new Circle(200, 0, 0);
test.setRadius(200);
assertEquals(100, test.getRadius(), 1);
test.setRadius(50);
assertEquals(50, test.getRadius(), 1);
}
}
Check the java class path and it will tell you the dependencies you need to compile your application. running javac at the command line acts differently than when it is automatically compiled by an IDE like eclipse if the class paths do not match. For commonly used jar files like JUnit your teacher should probably already have it in their environment. You should only include need to include jar files which are not part of a common configuration.

Can you run all JUnit tests in a package from the command line without explicitly listing them?

Provided the test classes and JUnit are both on the classpath, one can run JUnit tests from the command line as follows:
java org.junit.runner.JUnitCore TestClass1 TestClass2
Now, is there a way to run all tests in a package (and sub-packages) as well?
I'm looking for something like
java org.junit.runner.JUnitCore com.example.tests.testsIWantToRun.*
Is there an easy way of doing that (that doesn't involve maven or ant)?
Junit lets you define suites of tests. Each suite defines a collection of tests, and running the suite causes all of the tests to be run. What I do is to define a suite for each package, listing the test classes for that package along with the suites for any sub-packages:
package com.foo.bar;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import com.foo.bar.baz.Suite_baz;
#RunWith(Suite.class)
#Suite.SuiteClasses({
ThisTest.class,
ThatTest.class,
TheOtherTest.class,
Suite_baz.class,
})
public class Suite_bar {
}
This isn't completely effortless. You have to construct the suites and manually update them with new test classes. I suppose it wouldn't be hard to write a little java program to generate these automatically, if someone wanted to.
I asked this question to be able to kick sets of a project's Cucumber tests on Jenkins off selectively, without really knowing what their RunTests classes would be called, what their CucumberOptions would contain, or where they would be located. I found a few helpful threads on StackOverflow in the meantime, which answer my question:
How do I Dynamically create a Test Suite in JUnit 4?
How to run multiple test classes with junit from command line?
Using those, I can kick my Cucumber tests off individually as follows:
First, I used the maven assembly plugin to get the tests packaged in a jar:
https://stackoverflow.com/a/574650/2018047
Then I copied the tests' dependencies to the target folder on Jenkins, as shown here:
https://stackoverflow.com/a/23986765/2018047
We already have a flag that skips the execution of our tests when it's set, so I package my tests without running them:
mvn clean install -DskipMyTestModule=true
And using the code from above and the invocation from below, I'll be able to make it all work...
java -Dcucumber.options="src/test/resources/features --tags #b --format pretty:STDOUT --format html:target/cucumber-b --format json:target/cucumber-b.json" -Dname=value -cp target/artifact-1.2.8-SNAPSHOT-tests.jar;target/test-classes/libs/junit-4.11.jar;target/test-classes/libs/* org.junit.runner.JUnitCore com.example.foo.bar.test.cucumber.RunTest
Hope this helps someone in the future. :)
With JUnit 4 this is supported using an extension called cpsuite. All you need to do is add it to your test classpath (maven io.takari.junit:takari-cpsuite), create a dynamic test suite class:
package com.mycompany;
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
#RunWith(ClasspathSuite.class)
#ClasspathSuite.IncludeJars(true)
public class RunAllTests {}
and run it:
java -cp ${CP} org.junit.runner.JUnitCore com.mycompany.RunAllTests
Your classpath ${CP} should include your test jar, junit, hamcrest and cpsuite.

How to get JUnit 4.11 to recognize class in default package?

Similar to other questions on this subject, I am having problems getting JUnit 4.11 to recognize my class.
Similar to the question found here, I am using algs4.jar to write a class, Percolation, which is all in the default package. Just as in the post I linked, I too had difficulty importing algs4 into my class to use the required WeightedWuickUnionUF class found within. I was finally able to compile the program with the following setup.
> echo $CLASSPATH
/Users/dj/Library/Java/Extensions/algs4.jar:
/Users/dj/Library/Java/Extensions/hamcrest-core-1.3.jar:
/Users/dj/Library/Java/Extensions/junit-4.11.jar:
/Users/dj/Library/Java/Extensions/stdlib.jar
Percolation.java
import java.util.Arrays;
import algs4.*;
public class Percolation {
private WeightedQuickUnionUF union_find_ds;
...
}
test_Percolation.java
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.Assert.*;
#RunWith(JUnit4.class)
public class test_Percolation{
private static Percolation perc;
#BeforeClass
public static void testSetup(){
perc = new Percolation(5);
}
#AfterClass
public static void testCleanup(){
perc = null;
}
#Test(expected = IndexOutOfBoundsException.class)
public void testIndexErrorThrown(){
perc.open(0,5);
}
}
Compilation was accomplished with the following commands. Both .java files are in the same folder, so too is a directory titled algs4.jar with the algs4.jar fully expanded such that each class exists as its own file. Therefore in the working directory there are the following files.
Percolation.java
test_Percolation.java
algs4/WeightedQuickUnionUF.class
I feel that this is an important point because even though algs4.jar is within the classpath, the Percolation.java file ONLY compiles when I have algs4/WeightedQuickUnionUF.class in the current working directory. For some reason I cannot get the import to work with the .jar in the classpath.
>javac Percolation.java
>javac test_Percolation.java
Please note that in Percolation.java if I changed the import line from import algs4.*; to import algs4.WeightedQuickUnionUF; I receive the following error at compile time.
Percolation.java:23: error: cannot access WeightedQuickUnionUF
import algs4.WeightedQuickUnionUF;
^
bad class file: ./algs4/WeightedQuickUnionUF.class
class file contains wrong class: WeightedQuickUnionUF
Please remove or make sure it appears in the correct subdirectory of the classpath.
Having compiled both files successfully, I attempted to use the solutions found from the following question. Entering the command java org.junit.runner.JUnitCore test_Percolation or the more verbose but seemingly unecessary command java -cp /Users/dj/Library/Java/Extensions/junit-4.11.jar org.junit.runner.JUnitCore test_Percolation both yield the following error.
JUnit version 4.11
Could not find class: test_Percolation
Time: 0.002
OK (0 tests)
I suspect that there is something wrong with my system configuration on top of the effects of my limited knowledge of Java and importing using Java. I know these questions have been posted elsewhere, but the solutions to said questions have not worked on my machine. Perhaps I have missed a nuance of the answers to other questions.
I am using Mac OSX 10.8.5 doing all of the programming and compilling from the command line using javac 1.7.0_07.
Look at your command-line:
java -cp /Users/dj/Library/Java/Extensions/junit-4.11.jar org.junit.runner.JUnitCore
You've got the JUnit jar file on your class path - but not the current directory. So it won't be able to find any classes that aren't either "system" classes or in JUnit.
Try something like:
java -cp .:/Users/dj/Library/Java/Extensions/junit-4.11.jar org.junit.runner.JUnitCore
Ideally you should also start using packages though - and using more conventional class names. (test_Percolation violates normal conventions.)

Categories

Resources