How does JUnit process Unit Tests? - java

I'm currently testing an interface for Java which enables to use R calls with Java. Therefore I need a connection which also encapsulates a process.
Now I need to know, how JUnit processes those Unit Tests. I'm using JUnit4 with it's #Before and #After annotations to init a new connection (internally it's a process) once per test.
With "how JUnit processes" I mean:
is every test executed in it's own thread? ( which could probably cause problems)
are those tests executed sequentially?
do they have a specific order (not that important, but would be nice to know)
My concern is that those tests could cause problems which wouldn't exist, if used properly (as documented) in a real environment.

The tests are executed sequentially. You should not rely on this fact, because that indicates you are not writing a pure unit test and have created an anti-pattern (in terms of testing). Each test must be its own separate piece of work with no external dependencies outside of After and Before initializations. I believe each test is executed in its own thread, once again this harkens back to your test suite not being pure unit tests.
My concern is that those tests could cause problems which wouldn't
exist, if used properly (as documented) in a real environment.
Unit tests only validate one small piece of a function, typically one possible logic branch. If you want to test the system integration you will need to do what is called integration testing. Further if you are looking to do multi-threaded testing I highly recommend: Multi-threaded TC

I believe that unless otherwise specified, JUnit is free to use as many threads as it likes to run your unit tests. You can restrict this to a single thread. The order is arbitrary as to which tests are run when. In theory, your tests should be properly thread-safe to avoid having nondeterminism issues if run from different threads.

is every test executed in it's own thread? ( which could probably cause problems) - one thread for all tests
are those tests executed sequentially? - yes
do they have a specific order (not that important, but would be nice to know) - no, it is principally impossible to tell beforehand the order of processing of #Test methods in the class. But using #Rules, you can read the number of the current test in their sequence
Of course, we are talking on different tests in one class.

For each test class:
Call #BeforeClass and/or #ClassRule annotations.
For each test (#Test):
Create an instance of the class
Call #Before and/or #Rule annotations
Call test method
Call #After and/or #Rule annotations
Call #AfterClass or #ClassRule annotations.
Usually everything works from the same thread - however don't rely on that as some rules (timeout) will fork a thread - and you can decide to run tests in parallel.

Related

Is there a way to unit test ScheduledExecutorService.scheduleAtFixedRate without using Thread.sleep?

I would like to unit test a class that executes a task using ScheduledExecutorService.scheduleAtFixedRate, and I can't find a way to "schedule" multiple runs of the task in a unit test without using Thread.sleep, which is slow and not as precise as I'd like. Is there any way to pass a mocked time reference to the executor service or other workarounds to simulate the passage of time?
Unit Tests verify behavior of your code in isolation from its dependencies.
The implementations of ScheduledExecutorService are provided by the JVM and therefore not your code, but a dependency that must be replaced with a test double while unittesting your code. (There might be a valid setup for a test that needs the ScheduledExecutorService implementation to be executed, but this is not a unit test then.)
So in case you are writing a unit test (and not some other kind of test as i.e. integration tests, that happens to be using the JUnit framwork) you should create a mock for the ScheduledExecutorService interface using a mocking framework (like Mockito or alike) and verify that your code calls the desired method on the mock.
To enable your test for this verification you should inject the implementation of ScheduledExecutorService interface into your code (preferably via constructor injection) and not have your unit under test acquiring it itself, so that you have a seam at which you can exchange the real implementation of ScheduledExecutorService interface whith the mock for the purpose of unit testing.

How can I run a test class only if another test was passed?

I am doing some Junit testing and I need to know how to run a Test class only if a specific test from another class was passed.
There is 'Categories' feature in JUnit. (See: https://github.com/junit-team/junit/wiki/Categories)
This question has already been replied in this post
In the #Before function you need to retreive a runtime value from your system and check that it matches your requirement. Everything will stop if it doesn't
IMHO, This is bad practice, even in a well-designed Integration test-suite. I would encourage you to rethink your overall test class design.
If these tests are truly meant to be unit tests, they should be atomic and independent of each other. See this post for a good read.
Having said that, I have often used JUnit 4.x to build & run rather large suites of Integration tests (backend functional tests that test a RESTful services responses). If this is your use case, I recommend restructuring your tests such that you never have one test in TestClassA depend on a test in TestClassB. That is a bad idea, as it will making your tests more fragile. And difficult for other devs to understand the intention of your tests, taken together as a whole.
When I have found that I have dependencies across multiple test classes, I have factored out a "test-superclass" to both test classes and do my "setup work" in that superclass. Or you can factor out a utility class that contains static methods for creating somewhat complex test conditions to start with.
But, even using JUnit as a vehicle to run these kind of "integration" tests should be done with caution and careful intent.

Narrowing down a bad test by running junit tests in various combinations using Maven or other tool

I have 1000 junit tests and one "bad" test that is modifying a shared resource causing a subsequent test to fail. It passes if run alone. I'm looking for a Maven plugin or Java application or tool that will take as input a test class name. It will then run the 1000 tests in various combinations until it finds the "bad" test. Assume it is one "bad" test.
As you may noticed, writing dependant tests IS the problem ! Every solutions would be a workaround, maybe with side effectfs, complexity the first one.
Assuming you REALLY can't change that, you may have different strategies to solve your issue, but they are not necessary related to maven :
Ordering
Order your test to run the "bad one" at the end ... be carefull that you me affected again if you have a second bad test !
User TestNG instead of JUnit and #Groups and #AfterGroups annotations to split your tests and run them as you want
Use #AfterClass and BeforeClass with a test suite: Cleanup after all junit tests
Manually describe a Test Suite (not sure if you can achieve what you want)
Provide good data
Use setUp and tearDown methods to prepare and clean data in order to always have a stable environment, on each tests classes
Rollback the test that modify you resource (pretty the same thing indeed)
Step back thoughts :
Just a piece of minds :
If you cannot run tests independently, they are not unit tests.

what is the best place to verify if an external system is available before executing tests?

We are using JUnit to execute integration tests and also the system integration tests which rely on external test systems (not necessarily maintained by our own company).
I wonder where to put the code that checks if the system is available prior to running the test cases? So I can determine if there is a network or other issue and not one with the test itself.
JUnit allows to setup some parts of the test in JUnit-Rules. Is it a good idea to setup the service that communicates with the external system within the rule and do some basic checks ("ping") to the external system within the rule? Or to store the state and within the Test use a JUnit assume(rule.isAvailable) to avoid having the test executed?
Or would it be smarter to put this verification code in a custom JUnit Runner?
Or is there even another way to do this? (simply create some utils?)
The goal is to skip the tests if some conditions are not met since it is obvious the tests will fail. I know this indicates a bad exception handling but there is a lot of legacy code I can't change altogether.
I tried to find some articles myself but it seems the search terms ("test", "external system" and so on) are a little thankless.
thanks!
Consider using org.junit.Assume.* as described here. When assumptions fail, your tests are ignored by default. You can write a custom runner to do something else when your assumptions fail.
The key thing though is that the tests don't fail when assumptions like the availability of your external services fail.
If the ping applies to every single test in the class, I would put the ping call in the #Before method. #Before will get executed before every single test method (i.e., #JUnit -annotated methods).
If the ping does not apply to all tests in the class, then you would have to hit ping explicitly from those methods.

Java spring junit writing tests that persist data

I have written tests in the past using in memory databses.
What i wanted to know was is it possible to write tests in spring, junit, java, using in memory DB and the data is not rolledback after each test but kept in the db.
Basically whereby the tests are dependant on each other?
any ideas?
Rollbacking db changes or not is up to you.
But unit test should be independent from each other.
Small extract from a recent DZone article on the subject:
Make each test independent to all the others
Do not make chain of unit test cases. It will prevent you to identify the root cause of test case failures and you will have to
debug the code. Also, it creates dependency, means if you have to
change one test case then you need to make changes in multiple
testcases unnecessarily.
Try to use #Before and #After methods to setup per-requisites if any for all your test cases. If you need to multiple things to support
different test cases in #Before or #After, then consider creating new
Test class.
Your tests should be independent.
But if you want I guess you can try the #Rollback annotation.
I have not tried but have seen in the doc spec while doing transactions.

Categories