How to run classes inside Jar file? - java

I created a jar file that launches an application to allow the user to select which test they want to run. Each test has its own class and main method. The UI application passes parameters to the main method for the class that represents the test.
I was able to create the executable JAR file for the UI application but nothing happens when I select the test I want to run. I think it is that JAR file can only handle one main method.
Below is part of the code for the application that allows the user to select which test to run.
public class UI extends JFrame {
String[] args={Environment, Browser, TestingCoverage, DBLog, "UI"};
if (chckbxEQ_CA_Home.isSelected())
{
EQ_CA_Home.main(args);
}
if (chckbxEQ_CA_Condo.isSelected())
{
EQ_CA_Condo.main(args);
}
if (chckbxEQ_CA_Renter.isSelected())
{
EQ_CA_Renter.main(args);
}
}

You can do that using Junit library.
JUnitCore junit = new JUnitCore();
Result res = junit.run(yourTestClass);
Don't invoke the main() method to avoid any possible interruptions, just let the JUnitcore find the appropriate test methods.
And also don't forget to include Junit.jar in classpath (or) include it as part of your jar file (as a fat jar).

Related

NetBeans : JUnit no tests executed

So I'm getting this persistent error using netbeans. I've got a LinkedList class which I am testing via a JUnit test, which I created by clicking on LinkedList.java: Tools -> Create/Update Tests and this LinkedListTest.java class is now located in test packages.
My LinkedList.java file works correctly when tested in a file with a main method.
public class LinkedListTest {
#Test
public void testAddFirst() {
LinkedList linkedList = new LinkedList();
Country c1 = new Country("Australia");
linkedList.addFirst(c1);
assertEquals("Australias", linkedList.getValue(0)); // Should fail a test
} // default test methods beneath
All my imports check out. JUnit 5.3.1 and I had to download apiguardian1.1.0.jar from MVN repository to clear an error for:
reason: class file for org.apiguardian.api.API$Status not found
I right-click in this file and select Test File, or use Ctrl+F6, I've selected Test File from the original LinkedList file, I've even used Alt+F6 which tests the whole project. Yet I'm met with 'No tests executed.', an empty Test Results window, and no Notifications. What am I doing wrong?
Thanks for any help
Edit: I just switched from netbeans to eclipse.
You forget to extend Runner with class --
use like below with class -
public class LinkedListTest extends Runner {
}
Hope this help you.

How to invoke the Cucumber runner class from a different main method

I'm new to using Command Line Interface. So I just have a question on how to invoke the runner class of the cucumber using CLI technique.
I have a Java program which contains a main method. When testers pass the argument which is test case, it will fetch the feature file. The java program invoke a custom made API which will fetch the correct feature file.
Next I'll have to invoke the Cucumber runner class to execute the test case. I need to pass this particular feature file as the argument. Two questions, Can we invoke the runner class from a different main method. I did some research and I was not able to find a concrete answer.
Two questions,
cucumber.api.cli.Main.main(arguments); So how do i specify the jar location of my runner class.
`FeatureFileCreation.main("xxxxx"); - API that fetches the right feature file
String[] arguments = {"-", ""};
cucumber.api.cli.Main.main(arguments);
How do I specify where my jar is located? How can I pass my feature file?`
Should I create a main method in the runner class, something like this? For the sake of using CLI,Since I need to create a runnable jar. I should have a main method in my runner class.
`
#RunWith(Cucumber.class)
#Cucumber.Options(features="C:/Users/IBM_ADMIN/Desktop/CRAutomation/CR Regression1/src/My.feature",glue={"bell.canada.step.definition"})
public class AutomationRunnerAction {
public void main(){
}
}`
Please note that, Getting the right feature file is 1 java API. I will invoking that API from one main method of one java program. The runner class with step definition and methods are a diff java program.
Unfortunately the accept answer is not correct. If you look at the source of Main.main() you'll notice that it contains: System.exit(exitstatus) which terminates the system.
The proper way to run the commandline programatically would be to use Main.run() like this:
String [] argv = new String[]{ "-g","","./src/main/java/featureDetails/Testing.feature"};
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
byte exitstatus = Main.run(argv, contextClassLoader);
Try this if this works. You do not need any Runner class. Just call the static main method of Main class that corresponds to running cucumber from cli.
public static void main(String[] args) throws Throwable {
//Your code to get feature file full path
Main.main(new String[]{"-g", "classpath to step definition file", "Full path to feature file"});
// My stepdefinition is inside java package at cucumber.sample.test
// My feature file is inside src/test/resources/features/samplethree.feature
}
For additional parameters like tags or plugin use "-t","#Tags". Important the feature file path has to be the last option.
I am running this for Eclipse with Maven setting up classpath and jar dependencies.

Running cucumber test file from application button

I've set up a test file in src/main/java with my cucumber annotations containing class A, as well as a test file extending class A in src/test/java with the following annotation on class B:
#ContextConfiguration(locations = {"classpath:META-INF/application-config.xml", "classpath:META-INF/overrule.xml" })
This is working fine when I do a maven clean install.
What I would like to achieve though is being able to run a feature file through the cucumber setup of class A and see its output. So far I've managed to find a method which should allow me to run the cucumber test, but I can't seem to figure out what its arguments should be. Could anyone provide me with an example of how to implement the function cucumber.api.cli.Main.run()?
#Override
public void buttonClick(final ClickEvent event) {
try {
final String[] arguments = {"foo", "bar" };
cucumber.api.cli.Main.run(arguments, ClassLoader.getSystemClassLoader());
} catch (final Throwable e) {
e.printStackTrace();
}
}
I would invoke the command line version using cucumber.api.cli.Main.main(args);
where args is a String array with the parameters set. I would not use the run command you refer to.
The documentation describes all available options.
Another source may be the getting started project supplied by the Cucumber team: https://github.com/cucumber/cucumber-java-skeleton
It may be of specific interest to look into the Ant build script https://github.com/cucumber/cucumber-java-skeleton/blob/master/build.xml to see what arguments they supply to Cucumber.

How to keep a jar file external but still use its classes in my Android project?

I need to have a jar file located in a main/assets directory within an Android project. It is important the jar file is located there.
With my main Android project is there a way to reference this jar file in my code and to use its classes?
To be clear I don't want to add the jar to the main project once compiled.
EDIT: I have tried the link below and it seems to load the Class file I've stated. But I'm strugging how to define constructor arguments for the dynamically loaded Class.
android-custom-class-loading-sample
EDIT2
Nearly there. I've confirmed the class is loaded from my classes.jar. I'm stuck instantiating it though.
On the licenseValidatorClazz.getConstructor line I get the error below. I'm guessing I'm missing something from my Interface file?
java.lang.NoSuchMethodException: [interface com.google.android.vending.licensing.Policy, interface com.google.android.vending.licensing.DeviceLimiter, interface com.google.android.vending.licensing.LicenseCheckerCallback, int, class java.lang.String, class java.lang.String]
public Class licenseValidatorClazz = null;
public LicenseValidator validator;
...
// Initialize the class loader with the secondary dex file.
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),
null,
mContext.getClassLoader());
try {
// Load the library class from the class loader.
licenseValidatorClazz = cl.loadClass("com.google.android.vending.licensing.LicenseValidator");
validator = (LicenseValidator) licenseValidatorClazz.getConstructor(Policy.class,DeviceLimiter.class,LicenseCheckerCallback.class,int.class,String.class,String.class).newInstance(ddd, new NullDeviceLimiter(),
callback, generateNonce(), mPackageName, mVersionCode);
} catch (Exception exception) {
// Handle exception gracefully here.
exception.printStackTrace();
}
I have an Interface which contains the functions to pass to the loaded class.
public interface LicenseValidator
{
public LicenseCheckerCallback getCallback();
public int getNonce();
public String getPackageName();
public void verify(PublicKey publicKey, int responseCode, String signedData, String signature);
public void handleResponse(int response, ResponseData rawData);
public void handleApplicationError(int code);
public void handleInvalidResponse();
}
TO use an external jar to be associated with your application and use it during runtime, it needs to be in dalvik format since normal jars cannot work under dalvikVM.
Convert your files using the dx tool
using aapt cmd , add those classes.dex to your jar file.
Now this jar which contains files in dalvik format can be loaded into our project.
Here is a post which explains the procedure to accomplish it.
There are steps to accomplish this.
You have to make a copy of your JAR file into the private internal storage of your aplication.
Using the dx tool inside the android folder, you have to generate a classes.dex file associated with the JAR file. The dx tool will be at the location /android-sdks/build-tools/19.0.1 (this file is needed by the Dalvik VM, simply jar can not be read by the dalvik VM))
Using the aapt tool command which is also inside the same location, you have to add the classes.dex to the JAR file.
This JAR file could be loaded dynamically using DexClassLoader.
If you are making a JAR from any one your own library, you have to do this steps (1-4) every time when there is a change in your library source code. So you can automate this steps by creating a shell script(in Mac/Linux/Ubuntu) or batch scripts(in Windows). You can refere this link to understand how to write shell scripts.
Note : One situation for implementing this method is, when it is impossible to add the JAR files directly to the build path of core project and need to be loaded dynamically at run time. In normal cases the JAR files could be added to the build path.
please check this link for the detailed code and implementation.
How to load a jar file at runtime
Android: How to dynamically load classes from a JAR file?
Hope this helps!!
You should try out the Services API - java.util.ServiceLoader
You define a service interface and its implementations in your jar.
package com.my.project;
public interface MyService { ... }
public class MyServiceBarImpl implements MyService { ... }
public class MyServiceFooImpl implements MyService { ... }
Then you define the services contained within the jar file in the META-INF/services/ directory. For instance, in the file 'META-INF/services/com.my.project.MyService', you list the provider classes.
# Known MyService providers.
com.my.project.MyServiceBarImpl # The original implementation for handling "bar"s.
com.my.project.MyServiceFooImpl # A later implementation for "foo"s.
Then, in your main codebase, you can instantiate a MyService instance with the ServiceLoader:
for (MyService service : ServiceLoader.load(MyService.class)) {
//Perform some test to determine which is the right MyServiceImpl
//and then do something with the MyService instance
}
These examples are taken more-or-less straight from the API, although I've changed the package names to make them slightly less annoying to read.

Showing JUnit view in Eclipse when running tests from Code

When I run just my Testclass in Eclipse I get the JUnit view showing the tree structure and if the test was successful. If I start my Test from code:
JUnitCore core = new JUnitCore();
core.run(SimpleTests.class);
the view does not show. Can I change this?
On your toolbar click Windows-->Show View-->Others.
Type "Junit" without quotes. Select from list and click OK.
I suppose you run your code in the main method like this example :
public class MiniTest extends TestCase
{
#Test
public void test()
{
System.out.println("Running test");
}
public static void main(String[] args)
{
JUnitCore core = new JUnitCore();
core.run(MiniTest.class);
}
In this case, it will not show your view because you launch your program as a java application (alt-shift-X-J). You will see "Running test" in the console but that is.
If you want to see the Junit View you must launch your program as a Junit test (alt-shit-X-T).
Note that with this manner the main() is not necessary, Eclipse will directly launch the method tagged with #Test. You can also group tests with #Suite.
You can't interact with the JUnit view from your code using JUnitCore.
You can however, add your tests to the JUnitView if you use a #Parameterized test, or if you implement your own test runner. Try extending the Suite class and reimplement one of the constructors with the tests that you want to execute.
I get this problem from time to time.
There is something corrupted in the eclipse workspace.
The only solution for me is to create a new workspace and bring in the projects.
It's a serious pain when there are fifty projects in the workspace.
If the view doesn't show, go to Window -> Perspective -> Reset Perspective..

Categories

Resources