Exporting multiple JUnit classes into single executable jar - java

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.

Related

Schedule a pipeline in gitlab that will execute only a single test [duplicate]

I am trying to find an approach that will allow me to run a single test from a JUnit class using only command-line and java.
I can run the whole set of tests from the class using the following:
java -cp .... org.junit.runner.JUnitCore org.package.classname
What I really want to do is something like this:
java -cp .... org.junit.runner.JUnitCore org.package.classname.method
or:
java -cp .... org.junit.runner.JUnitCore org.package.classname#method
I noticed that there might be ways to do this using JUnit annotations, but I would prefer to not modify the source of my test classes by hand (attempting to automate this). I did also see that Maven might have a way to do this, but if possible I would like to avoid depending on Maven.
So I am wondering if there is any way to do this?
Key points I'm looking for:
Ability to run a single test from a JUnit test class
Command Line (using JUnit)
Avoid modifying the test source
Avoid using additional tools
You can make a custom, barebones JUnit runner fairly easily. Here's one that will run a single test method in the form com.package.TestClass#methodName:
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
public class SingleJUnitTestRunner {
public static void main(String... args) throws ClassNotFoundException {
String[] classAndMethod = args[0].split("#");
Request request = Request.method(Class.forName(classAndMethod[0]),
classAndMethod[1]);
Result result = new JUnitCore().run(request);
System.exit(result.wasSuccessful() ? 0 : 1);
}
}
You can invoke it like this:
> java -cp path/to/testclasses:path/to/junit-4.8.2.jar SingleJUnitTestRunner
com.mycompany.product.MyTest#testB
After a quick look in the JUnit source I came to the same conclusion as you that JUnit does not support this natively. This has never been a problem for me since IDEs all have custom JUnit integrations that allow you to run the test method under the cursor, among other actions. I have never run JUnit tests from the command line directly; I have always let either the IDE or build tool (Ant, Maven) take care of it. Especially since the default CLI entry point (JUnitCore) doesn't produce any result output other than a non-zero exit code on test failure(s).
NOTE:
for JUnit version >= 4.9 you need hamcrest library in classpath
I use Maven to build my project, and use SureFire maven plugin to run junit tests.
Provided you have this setup, then you could do:
mvn -Dtest=GreatTestClass#testMethod test
In this example, we just run a test method named "testMethod" within Class "GreatTestClass".
For more details, check out http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html
The following command works fine.
mvn -Dtest=SqsConsumerTest -DfailIfNoTests=false test
We used IntelliJ, and spent quite a bit of time trying to figure it out too.
Basically, it involves 2 steps:
Step 1: Compile the Test Class
% javac -cp .:"/Applications/IntelliJ IDEA 13 CE.app/Contents/lib/*" SetTest.java
Step 2: Run the Test
% java -cp .:"/Applications/IntelliJ IDEA 13 CE.app/Contents/lib/*" org.junit.runner.JUnitCore SetTest

JUnit 5 (Jupiter) Testcases in eclipse projects not being run

I have an eclipse workspace (version 2019-12, non-maven) with multiple web projects, all containing java code, and some referencing each other. At the end of the reference 'graph' is a project dedicated to contain a test suite, which in turn is supposed to reference all other projects' tests.
All projects export their test-source folders. (All test classes are visible to the downstream projects).
I started to define the following suite:
package platformTest;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;
import de.***.PlatformEnvironmentTestcases;
import de.***.ClientTestcases;
#RunWith(JUnitPlatform.class)
#SelectClasses({
PlatformEnvironmentTestcases.class,
ClientTestcases.class
})
public class JUnit5TestSuite {
// test suite
}
However the referenced test classes (though successfully running on their own, and being directly referenced) are not being executed at all.
I tried:
setting the debug config to junit4, with the result that no tests are executed. It seems the compatibility layer between junit 4 and 5 is not working here.
setting the debug config to junit5, with the result that a message window pops up: "No tests found with test runner 'JUnit 5'.
setting the debug config to junit5 and selecting 'Run all tests in the selected project, package or folder:' which - surprisingly - is working, but I cannot select the workspace root, which means I can never select all projects, and this setup will only find the tests in the suit's project and the selected project, but not the rest.
I found multiple bugs referenced for older versions of eclipse displaying similar symptoms, but since I am running a very recent version, I suppose those should not apply anymore. Also I tried most of the workarounds suggested without success.

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.

Why is my JUnit test not running in Eclipse?

It's been 3 hours now and I still didn't find a solution, even though I seem to have read all related questions already.
I am building an Android application and I just want to create a couple of simple Unit Tests that test my basic functions. I don't need to test any Android related logic or activity features.
So I have created a new directory in my solution in which I have created a new JUnit Test Case.
To keep things simple my test methods are not testing much yet, but even when doing a Right Click > Run As > JUnit Test, it's not doing anything.
As you can see in my screenshot the JUnit pane on the left shows my test is terminated but does not show any test that has been executed.
I have created a simple Unit Test in a new Java Project and then it's working. If I repeat the same steps in a new Android Application Project it's not working.
What do I need to do to run my simple Unit Tests?!
Thanks!
(My Compiler Compliance Level is 1.6)
Go to Window -> Show View -> Error Log to see what the actual error is.
For my case it was No test found with test runner 'Junit 5'.
Then one can google for respective solution.
You either don't have JUnit on the build path or you don't have the library (jar) at hand. Make sure both are in place.
I think you will need an unit test suite if all else fails:
#RunWith(Suite.class)
#SuiteClasses({ GpsLocationTest.class })
public class AllTests {
}
There is one more thing you can do: check whether you import the right #Test annotation. Restart Eclipse and clean your project if the problem persists.
You may want to refer to the vogella guide about unit testing.
You can use AndroidTestCase, which inherits from junit.framework.TestCase, not org.junit.Test.
This is related to Memory Issue.
Simply add these line in VM argument:
right click on Junit Test -> Run as -> Run Configuration -> Arguments -> add "-XX:MaxPermSize=512m" under VM argument
The java Build path of the project has Junit4.jar lets say and the Run configuration for the test you are running has Junit5 - then it causes to terminate and nothing happens.

JUnit 4 Test Suites

How do I create test suites with JUnit 4?
All the documentation I've seen doesn't seem to be working for me. And if I use the Eclipse wizard it doesn't give me an option to select any of the test classes I have created.
import org.junit.runners.Suite;
import org.junit.runner.RunWith;
#RunWith(Suite.class)
#Suite.SuiteClasses({TestClass1.class, TestClass2.class})
public class TestSuite {
//nothing
}
You can create a suite like so. For example an AllTest suite would look something like this.
package my.package.tests;
#RunWith(Suite.class)
#SuiteClasses({
testMyService.class,
testMyBackend.class,
...
})
public class AllTests {}
Now you can run this in a couple different ways:
right-click and run in Eclipse as Junit test
create a runable Java Application; Main class='org.junit.runner.JUnitCore' and Args='my.package.tests.AllTests'
run from the command line:
$ java -cp build/classes/:/usr/share/java/junit4.jar:/usr/share/java/hamcrest-core.jar org.junit.runner.JUnitCore my.package.tests.AllTests
I think TestSuite has fallen out of favor. That might have been the style before 4.x, but it's not now as far as I know.
I just annotate the tests I want and then run the class. All the annotated tests are run. I might use Ant, but most of the time I have IntelliJ run them for me.
Here are the steps to create a JUnit suite in eclipse:
In the 'Package Explorer' view of the eclipse 'Java' perspective,
select your unit test(s) in their package, inside the eclipse java
project.
Right-click on any one of the selected tests.
In the pop-up menu, select New, Other…
Open the ‘Java’ folder, then open the ‘JUnit’ folder
Select ‘JUnit Test Suite’ and then select the ‘Next’ button
Select button ‘Finish’
Result: ‘AllTests.java’ suite file is created, with tests automatically
included
Select the Run button in eclipse
Result: all tests in suite run
You can now point to this suite file with ANT, Jenkins or other build configuration continuous integration tool.
Version info: this is for eclipse Neon and JUnit 4. You can also select JUnit 3 before selecting 'Finish' in step 6.
Of the top of my head create a TestSuite and the invoke addTests. If you want somesource to look at try any opensource lib like hibernate or something from apache and take a look under the test directory of the source for a Tests suite ...

Categories

Resources