I want to test javaFX application by using junit. I checked several approaches as follow:
user TestFX api: these api works sometime on a test method, in other word, for some execution of a special test, it's work !!!
List use JFXRunner : I used test runner which is defined in this question, but it for a few of the methods to be run and when number of test methods be large(e.g. >20) , test methods waiting forever !!!
define a test runner class such as JavaFXThreadingRule which has been intruduced in this question. these approach works only for a single test and when run some test, test method go into waiting forever same as JFXRunner.
what is the problem really? by debugging test method, I found that by using lath for initializing javaFX, after running several method, remaining method will be waiting for ever. When I set a special time for awaiting method of lath, it work's correctly by it is not logically to set a constant time to test application. How can solve this problem.
for approach 2,3; I used Platform.exit() command for exiting from GUI Application; so test runner which use latch to initialize JavaFX platform wait forever. So, it was my code fault.So, calling Platform.exit() method prevents to execute remaining test methods.
Related
I am running some simple performance tests with JUnit 4 and using Jenkin's perfReport so that I can generate a performance report.
While running these tests, I noticed that the test method execution includes execution time of methods annotated with JUnit 4's #before and #after.
I came across a similar post: Exclude #Before method duration from JUnit test time, however I require my output format in a JUnit-style report since the Jenkin's perfReport parses JUnit-style format only.
As such, is there a way to exclude the execution time of these annotated methods?
I solved it by performing the following:
Extending the BlockJUnit4Runner
Overriding the runChild() method, as this is where test notifiers are received
Writing a custom runLeaf() method, as this is where the test notifiers are fired to notify the test has started or stopped.
Overriding the methodInvoker() method, as this is where the test method is invoked
Creating a new Statement class that functionally, performs the same set of actions as a invokeMethod() statement object created in methodInvoker. This class however, receives the test notifier, thus allow you to control how and when the test is considered to have started.
One issue of the above approach is that you will need to extract code sections that help to run JUnit rules, in order to preserve rule execution as these methods are strangely private.
Here is comment about setting default timezone for test code in #Before method of JUnit test. But TimeZone.setDefault is static method. Can it affect other test which are run after test with #Before and TimeZone.setDefault completes successful?
There are many things to check here, it depends on how do you run the tests.
The following factors may come into considerations:
Since you've tagged "maven" in a question: Maven's surefire/failsafe plugins responsible for running the tests can run multiple tests simultaneously in 1 or many JVMs, it all depends on their configurations.
So tests may start failing sporadically during the build even if they pass locally.
#Before and #After are called before and after each test in the test case respectively. #After is called even if the test fails. So probably memorizing the default timezone and setting it back after the test should be ok, but not "re-setting" the state in an "#After" block may lead to incorrect definitions in subsequent tests.
The better approach IMHO is using java.time.Clock abstraction. See this question for examples
Another possible option is refactoring a code to use some "factory" for providing current date / time. Then in Unit Test you could instantiate this factory and "inject" it as a dependency into the code-under-test. A kind of hand-crafted Clock
It will effect the other tests (as you assumed), as it won't be reset after running a single test.
Either reset it to "normal" by an #After method, or maybe change the code to take/inject the timestamp for "now" and make the code do it's calculation from there. From my experience this will give you alot more flexibility.
I am writing unit tests and I'm stuck with a method which has infinite loop.
I have a main class which uses main method for execution and hence i have to use junit.framework.Test which does not have annotation such as #Test(timeout=1000), instead it calls the main class by creating its constructor.
Now the issue is : I have written all my test cases and its probably working fine too seeing the output but the test is stuck in an infinite loop.
From my main test class which is using junit.framework.Test instead of org.junit.Test. I called a public method of another class which has something like
public class AnotherClass{
public void method()
{
for( ; ;) // this is an infinite loop
{
.....
}
}
}
This is because it is actually monitoring a directory continuously and the program has to keep running until terminated manually.
My main test class calls this class's method and it never returns control to my test class again. Since, I'm writing tests, i cannot modify that method.
How do I terminate or take back control from that class(back to my test class)?
I tried using timer/thread in my test class to stop it from execution after certain time, but that does not work because the control goes over to the other class whose public method is called and its stuck there forever.
Any ideas on how to do this?
Please let me know, if you need any more info on this. Thanks
Note: The class which has infinite loop is not a test class, its a main class in package, so I cannot make any modifications there.
I have a solution which is kind of based on this logic but I'm hoping to find something better than this or may be finding what other solutions are possible for this.
I think you really need to partition the problem into smaller parts and then combine the solutions together to get the final solution:
you have a program that has infinite loop that you cannot change, but you need to test it
the only way to get the execution back to the test is by executing the logic in a separate thread
You need to kill/stop the thread after that
in Java you cannot generally do that easily, you might consider using ExecutorThread and cancelling the Futures, maybe even daemon threads
You need to have a timeout like behavior
easiest way is to use JUnit or TestNG build-in feature
The final solution will be the combination of all the partial solutions.
I am writing several different selenium tests as page objects, and want to be able to run them from within a single, central class. I have figured out how to run one test from a different class, but when I try to run multiple tests, only a single one will complete.
I have tried running them sequentially with org.junit.runner.JUnitCore.main("com.etc"), but after
testing the first class, the entire test ends. In the code:
org.junit.runner.JUnitCore.main("com.etc.test.HomePageCheck");
System.out.print("test");
the print command is never run, even if the test runs successfully
I have also tried creating multiple threads, but once any test completes, the whole process seems to end and leave the remaining tests hanging.
To reiterate, I have Class1 with several jUnit tests, and Class2 with other jUnit tests. I want to be able to run a Class3, whcih will run both Class1 and Class2 and complete all tests for those other classes.
I do not think I want to use Selenium Grid, I would rather just run the tests locally on a machine, either in sequence or, preferably, in parallel.
I figured it out, here is the code(second line is key, the others are just to get the output)
Result aTest;
aTest= org.junit.runner.JUnitCore.runClasses(new Class<?>[]
{
Events.class,SearchCheck.class});
for(Failure i:aTest.getFailures())
{
System.out.println(i.getException()+"\nat: "+i.getDescription());
System.out.println("trace: "+i.getTrace());
System.out.println();
}
}
Thanks everyone
Edit: actually testSuite also works extremely, and is probably the better way to do this.
I am configuring my own Spring test runner and I try to define test execution order. But I want to change it in the process depending on failure of some test cases. Each test case configuration has it's own id and onFailId that indicates id of the next test to be executed in case of failure. If the test pass, simply the test with the next id is executed. There might be some scenarios when I want to rerun or execute earlier test again.
How can I force this logic, e.g. in test failure listener?
I figured out and implemented a solution. Defining a sorting method before running test suite is not enough. All methods mentioned e.g. here How to run test methods in specific order in JUnit4? in junit4 allow setting order before execution only.
I had to overload childrenInvoker method in my runner - that is SpringJUnit4ClassRunner - by default, it calls runChlidren (private method) which runs all children tests in a loop.
If you replace this loop by your own code, you can specify additional logic after each test execution - such as choosing the next test to be run.