Fake JavaFX Platform start - junit

In my project I have a peculiar setup for testing JavaFX components: First there is an Application that starts the component normally through a main method for visual inspection. But then there are subclasses of this Main classes which are the actual JUnit tests.
In the tests I do not want to run the application with the UI showing up (the tests should also be runnable in a system that has no window manager, e.g. cuntinuous integration). Normally this will throw an error, as the platform is not started. To prevent this, I call:
final Runnable dummyRunnable = new Runnable() {
#Override
public void run() {
System.out.println("Startup platform");
}
};
PlatformImpl.startup(dummyRunnable);
PlatformImpl however is internal API (com.sun.javafx.application.PlatformImpl). Which basically ties the test to a specific brand of JDK.
To figure out if this happens I actually call the method through reflection, so I can log the specific error cases.
Is there a way to reach the same thing (running the tests which are a subclass of Application, but do not call the start method, to run in headless mode)?

Related

Difference in running Cucumber-JVM vs Cucumber runner(Junit)

I am fairly new to Cucumber. I was experimenting with it by just creating few test features when I noticed the difference when running a single feature vs running the whole suite (from the IntelliJ).
I noticed that when I run single feature it runs using the cucumber-jvm option and in this case, the CucumberConfig(the blank class to define the runner and cucumber options) and the Runner is not utilized. However, when I run the whole suite it runs as a JUnit test and obviously, in this case, the Config class and the runner comes into the picture.
I confirmed this with the following sample code:
#RunWith(CustomRunner.class)
#CucumberOptions()
public class CucumberConfig {
#BeforeClass
public static void beforeClass()
{
System.out.println("This is run before Once: ");
}
#AfterClass
public static void afterClass()
{
System.out.println("This is run after Once: ");
}
}
CustomRunner
public class CustomRunner extends Cucumber {
public CustomRunner(Class clazz) throws InitializationError, IOException {
super(clazz);
System.out.println("I am in the custom runner.");
}
}
Also, I understand that while running as cucumber-junit we can't pass specific feature to run as in cucumber-jvm. Correct me if I am wrong.
My doubt is, is this the default behavior or am I doing something wrong. And, if this is default how can I make cucumber to always use the Config file.
I'll appreciate if someone can provide some insight on this.
When you're using IntelliJ IDEA to run the tests, IDEA will use cucumber.api.Main to run the tests. As such it will ignore CucumberConfig neither will it run #BeforeClass nor #AfterClass, these are only used by the JUnit runner.

Launching JUnit jupiter tests from inside a main method?

I have a Java class with a main method that I invoke to occasionally run some tests. Specifically, I'm trying to come up with a solution for quickly testing various code snippets that use the AWS SDK to create/read some S3 objects. I'm not really trying to build regular unit/integration tests, and I'm not interested in mocking the S3 code. I'm trying to quickly develop/debug some code using a test framework. I found the following SO question, and the answer about using JUnit5 Jupiter's Launcher and it intrigued me:
How do I run JUnit tests from inside my java application?
So I read the Junit5 chapter on the Launcher API and followed the example code. I came up with something like this:
class S3ManualTest {
public static void main(String[] args) {
LauncherDiscoveryRequest request =
LauncherDiscoveryRequestBuilder
.request()
.selectors(selectPackage("com.xyz.s3util"),
selectClass(S3ManualTest.class),
selectMethod(S3ManualTest.class, "happyPath")
)
.build();
Launcher launcher = LauncherFactory.create();
SummaryGeneratingListener listener = new SummaryGeneratingListener();
launcher.execute(request, listener);
TestExecutionSummary summary = listener.getSummary();
System.out.println("# of containers found: " + summary.getContainersFoundCount());
System.out.println("# of containers skipped: " + summary.getContainersSkippedCount());
System.out.println("# of tests found: " + summary.getTestsFoundCount());
System.out.println("# of tests skipped: " + summary.getTestsSkippedCount());
}
void happyPath() {
assertTrue(true); // Do useful stuff here
}
}
The launcher doesn't find any tests to run, even though I specifically selected the "happyPath" method. I have tried annotating the happyPath() method with #Test, and that seems to work, but it also has the undesired side effect that the method gets executed if I run all tests in that package, either from gradle, or from inside the IDE. Essentially, I want my test methods to be invoked with the JUnit5 framework, but only when I manually run the main method in the class. I was thinking about some custom annotations, or implementing some interface that would get picked up by the test engine, but haven't gone down that route yet. I'm guessing there's some easy way of accomplishing what I'm trying to do. Thanks.
I could only find a work around: disabling the happyPath() test method by default and override it in your program like explained here: https://junit.org/junit5/docs/current/user-guide/#extensions-conditions-deactivation
#Test
#Disabled
void happyPath() {
assertTrue(true); // Do useful stuff here
}
And in your launcher setup, deactivate the DisabledCondition:
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder
.request()
.selectors(selectMethod(S3ManualTest.class, "happyPath"))
.configurationParameter(
"junit.jupiter.conditions.deactivate",
"org.junit.*DisabledCondition")
.build();
You may also specify a dedicated switch, if you don't want deactivate DisabledCondition for the entire run:
#Test
#EnabledIf("'true'.equals(junitConfigurationParameter.get('manual'))")
void happyPath() {
assertTrue(true); // Do useful stuff here
}
with
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder
...
.configurationParameter("manual", "true")
.build();
The second work-around, if applied to more then a few methods, screams for a dedicated ExecutionCondition extension. See details at https://junit.org/junit5/docs/current/user-guide/#writing-tests-conditional-execution-scripts

Powermock: Notifications are not supported when all test-instances are created first

When I try to execute the below simplified JUnit test, it succeeds but i am getting an error message: Notifications are not supported when all test-instances are created first!
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(BlockJUnit4ClassRunner.class)
#PrepareForTest({ A.class })
public class TestA extends TestB {
#Test
public void test() throws Exception {
assertEquals(true, true);
}
}
public class TestB {}
public class A {}
When I remove the #PowerMockRunnerDelegate(BlockJUnit4ClassRunner.class), or the extends TestB or the #PrepareForTest({ A.class }), the message disappears. Even an emtpy #PrepareForTest({ }) makes the error message appear.
I found this post, but it is not the same problem, because I am not using an extended BlockJUnit4ClassRunner.
I am trying to understand why this error message appears.
I am using the latest version of Powermock (1.6.6) and JUnit 4.12 and running the test using java8.
PowerMock extends jUnit events message and fire some additional event during test life circle. PowerMockTestListener could be used to listen all jUnit and additional PowerMock events.
One of this event required that an instance per test is created. A jUnit runner usually creates an new instance of test class per each test method in class, but some of them could create only one instance of class for all tests. When #PowerMockRunnerDelegate is used then delegated runner responsible for creating test instance.
If event "test start" is fired without “test created” then PowerMock detects that all test instances are created before tests are started and cannot fire its internal events and this message is printed to system.err. So, you have the same issue as it has been described in post.
PowerMock has only one implementation PowerMockTestListener at current moment - AnnotationEnabler. This implementation is used for integration with EasyMock and Mockito and supporting annotation like #TestSubject, #Mock and so on. As result, then you see this message in console it means that these features could not work properly. But for Mockito case it could be easier fixed with using MockitoAnnotations.initMocks(this).
Very interesting that if you remove ‘extends TestB’ the message is disappeared. I’ll check this case and investigate why it happen.

swing uncaughtexceptionhandler

I am trying to build a general exception handler for a swing application as described here: http://www.javaspecialists.eu/archive/Issue081.html
I work in jython (python syntax getting compiled to java and executed). My code looks roughly like this (updated):
def launcher(func):
class launcherThread(Runnable):
def __init__(self):
super(launcherThread, self).__init__()
def run(self):
func()
#trying to get the name which can be used to instantiate this in java
cls = ExceptionGroup().getClass()
fullName = cls.__module__ + '.' + cls.__name__
System.setProperty("sun.awt.exception.handler", fullName)
Thread(ExceptionGroup(), launcherThread(), 'Cross ExceptionHandlerThread').start()
class ExceptionGroup(ThreadGroup):
def __init__(self):
super(ExceptionGroup, self).__init__("HardenedGroup")
def uncaughtException(self, thread, exception):
#make a fancy dialog displaying str(exception)
If I test it it works fine however in the production enviornment it failes.
For testing I launch my program in Eclipse (PyDev), the production enviornment is a third party application written in Java, that has a Jython console build in. The application supports adding of custom menu entries, and putting jython scripts on these.
The main difference I see between testing and production enviornment is that in the production enviornment the swing threads are allready started (the third party application utilitizes swing). Does this cause my ThreadGroup setting to fail, or is there another reason why this is not working?
How can I get the Involved threads (exceptions ar thrown as a result of buttonActions) to check their defaultException handlers? If (as I am afraid) it should turn out that the third party installed its own handler (all exceptions are written to a log file) how can I make a new swing worker thread? (I don't want to catch the exceptions created by the host application after all)
Question recap:
1. How can I check which threads are started for the function func passed into the launcher function and see thier uncaught exception handler?
2. Can I enforce a seperate swing dispatcher for my gui part and the main applications gui part? (If I exitOnClos on a frame of my add in, the third party application closes)?
Update:
Considering the anwser from lbalazscs I am trying to use the sun.awt.exception.handler property, but it has no effect, the exceptions still end up in the log file (applications dfeault behaviour). Am I using it right? (p.s.: I am on Java 1.6)
If you have Java 5 or higher, you can also use Thread.setDefaultUncaughtExceptionHandler(), which is also described in a newer "Java Specialists' Newsletter":
http://www.javaspecialists.eu/archive/Issue089.html
And here is the newest Java 7 version:
http://www.javaspecialists.eu/archive/Issue196.html
Also see this:
Why bother with setting the "sun.awt.exception.handler" property?
EDIT: This is how I use Thread.setDefaultUncaughtExceptionHandler (in Java...):
public static void setupGlobalExceptionHandling() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
handleException(e);
}
});
}

Android JUnit: Define a different Application subclass

So for my normal Android project, I have the following in AndroidManifest.xml:
<application android:name=".utilities.App" ...>
....
</application>
And then I have my App class:
public class App extends Application {
....
}
And then I have an Android JUnit Test project associated with the Android project. Everything is all fine and dandy and I can write JUnit tests. However, I'm trying to run code coverage with my JUnit tests and I'm getting bloated results. The reason is because my App class gets called and initialized as if my application were actually started. I do not want my custom App class to execute when I run the JUnit tests or code coverage. Any setup I would need for the JUnit tests will go in the appropriate JUnit setup() method. Is there any way I can prevent it from executing my custom App class or a way that any classes/methods/lines that are executed due to the creation of my App class aren't counted towards the code coverage?
A temporary solution that I've found will work unless someone has any better ideas.
Go into the main Android project's AndroidManifest.xml.
Change the android:name attribute from ".utilities.App" to "android.app.Application"
Run the code coverage utility/JUnit tests
Change the android:name attribute back from "android.app.Application" to ".utilities.App"
Re-deploy the app onto the device (so that it uses the right Application class when it runs external to the code coverage/JUnit tests)
I'm sure the real solution is to automate this process, but I'm too lazy to do so, and it just feels hackish and wrong. But at least it's a workaround unless someone has any ideas.