JUnit Test Cases #Before and #After annotations - java

We are following below practices to write JUnit tests for our methods.
Each method will be having their own class which holds all the tests which are required for that method. For e.g.: class test {...}
#Before will consists of per-requisites setup for methods like "Entity" so that when we do Edit we don't need to copy/paste code for adding an entity at each method level.
Now here my question is, shall we delete all the data which we entered by writing code to trash test-data in #after method or just let it be?
I know we can make it configurable but what is best practice? keep it or delete it. As per my gut feeling deleting should be better as if there is some duplicate data already in db - it may trigger wrong true or false.

It depends on how much you adhere to the Don't Repeat Yourself principle. It's also worth remembering that you have #After called after each #Test and #AfterClass called after all the #Test have run. With this granularity, it should be simple to remove duplication but still split those tasks that should only run at the very end, or after each test.

As a best practice I would recommend to clear your data storage between every test, to guarantee each test is isolated from other tests.
This could be done with the #After method if you want to keep some of the settings alive (from the #BeforeClassfor example). It could also be done in the #Before method for example by overriding variables with a new instance for every test, if you do so you do not need a clean up after the tests.
To clean up your settings of the #BeforeClass method you should use #AfterClass for example to close a Database connection or something simular what only needed to be done once. But this is not needed for every kind of unit test.

Related

Should I use the same variables throught entire Unit Test?

I am creating Unit Tests in Java and for each method, I create the same lists, variables, etc. On the other hand, of course I thought that I could create all of these variables as global and set their values in the setup() method (in #Before), but I am not sure if the values may be changed when running tests due to multithreading, etc. So, what is the best way for this situation?
Nothing to worry about. JUnit will create a new instance of your test class, and then run each #Before method, and only then run the #Test method, and it does that song and dance routine all over again for every #Test annotated method in that class. You're using #Before exactly as it was intended: It's for storing initialization code that is required for all the tests in that test class.
JUnit does it this way because 'test independence' is nice to have: Tests, preferably, fail or pass independent of the ordering in which you execute them.
Every so often the init process is so expensive that it's not worth it to pay the 'cost' of running it over and over again for every test. The annotation #BeforeClass exists specifically for that purpose. The javadoc of #BeforeClass even spells out that this compromises test independence and should therefore only be used if the setup work you do within such a method is sufficiently expensive (computationally or otherwise) to make that tradeoff.
In other words:
Your worries about test independence are real, but they apply to #BeforeClass. #Before doesn't suffer from this problem; that code is re-run for every test.
NB: You can toss all this out the window if you have static stuff going on. Don't have static stuff in test code unless you really know what you're doing. I assume you don't have that in which case - carry on, your tests are independent.

JUnit using #Before over #BeforeClass [duplicate]

This question already has answers here:
Difference between #Before, #BeforeClass, #BeforeEach and #BeforeAll
(7 answers)
Closed 4 years ago.
According to this answer, the #Before annotation is executed once before each test, whereas the #BeforeClass annotation is only executed once before all tests.
My intuition tells me to always use #BeforeClass, so the question is, why even use #Before? Is there a case where the #Before annotation performs better/faster than the #BeforeClass annotation?
Each test should be isolated. By using BeforeClass then the state of the previous test could be hanging about and messing up the later tests.
One generally uses BeforeClass to setup an expensive external resource and Before to reset the world (be that the external resource or local).
One final note:
performs better/faster
In this case I would say the two properties should be treated independently here (that is better!=faster). As long as the total time to run your complete tests suite is under 10 minutes then "faster" is simply not important.
Once you go above that magic ten minutes (and at this point you will definitely be talking integration tests not unit tests) then start looking for ways to make things "faster".
I'll give you an example:
Say you need to validate a form in your web application. You are going to use Selenium for that.
Your test class will have 10 tests. You don't need to open and close your webdriver browser each time you start your test suite. In such case, you iniatilize your webdrive browser on a #BeforeClass method.
However, for each validation test you need to reset your form. This action you will perform on a #Before method.
This is a very simple example, but may make things clearer.
When you use #BeforeClass it suggests that you do initialization before all the tests. So one test might depend on other one (e.g. if tests change the state of fields), so I would encourage usage of #Before, or even better to do preparations for the test method inside the method itself.
There are very rarely cases when your tests need exactly the same initial state, so why couple them together?

JUnit - Listener for when ALL test classes have been executed?

I've been searching for a while but I still can't find a way to do what I want.
I run my unit tests in Eclipse with the "Run as JUnit test" on the whole project.
I implemented a custom RunListener which record some test results information in a singleton (Just FYI, this is not meant to record only test results, I know we can export junit reports for that regard. This is meant to catch additional information which are in test methods custom annotations).
I'd like to persist the singleton information on disk once ALL test have been executed.
(The keyword being ALL :) )
I know I can override testRunFinished (This is what I do right now),
but this method is called everytime all tests of one single class are executed (So once by test class).
Is it because the Eclipse "Run as" consider each class as a Suite by default?
While it works, it is not really efficient to persist the singleton state thousands times.
Also, I'd like to give a proper name to the persisted file (Like the binary versions + date) but I can't right now since I don't know when ALL tests have been executed so each time the file is persisted it would create a new file (Date containing milliseconds) although the tests are not over (and the singleton data is thus incomplete)
Any idea ?
Thanks !
In the end, I created a TestSuite, with an #AfterClass static method to only persist once my singleton state.
This means I have to add all my test classes in the Suite.
Fortunately, thanks to JavaRocky, I dynamically included all my test classes with a custom annotation.
See answer here: How do I Dynamically create a Test Suite in JUnit 4?.
If someone has an easier way to accomplish a #AfterAllTestRuns ... let me know !

Using #Before method in JUnit

I saw this question: Repeating code in JUnit tests earlier today. How do you write this code when you are starting? You see that there is a method addDrivingRecord(...). This method does not exist when you first start writing so do you make that test, ensure that it works, then proceed with setUp() method, or do you instead wait until you have written the addDrivingRecord(...) method and then refactor it to the #Before? I will explain further if needed.
If I understood well your asking if you should:
use addDrivingRecord in the test method
ensure it goes green (it works)
refactor addDrivingRecord to #Before
or
use addDrivingRecord in the test method
refactor addDrivingRecord to #Before
ensure it goes green (it works)
If it's your question I should go for the first option: first use method, then implement and go green, then refactor your test.
Because two reasons:
You should test/implement one thing at a time, so you will write one test method. Then you will make it green. Only then you should write another method and realize that code can be refactored in a #Before
A good practice is write test methods and only when you realize there are common things move them to #Before. That way you don't enforce innecesary things in initialization. Moreover, if you find that another test needs a very different #Before method it probably belongs to another test class.

How to deal with interdependent JUnit tests?

I have a question about JUnit testing.
Our JUnit suite is testing various functions that we wrote that interact with our memory system.
The way our system was designed, requires it to be static, and therefore initialized prior to the running of the tests.
The problem we are having is that when subsequent tests are run, they are affected by tests prior to it, so it is possible (and likely) that we are getting false positive, or innaccurate failures.
Is there a way to maintain the testing order of our JUnit tests, but have it re-initialize the entire system, as if testing on the system from scratch.
The only option we can think of is to write a method that does this, and call it at the end of each test, but as there are lots and lots of things that need to be reset this way, I am hoping there is a simpler way to do this.
I've seen problems with tests many times where they depend on each other (sometimes deliberately!).
Firstly you need to setup a setUp method:
#Before
public void setUp() {
super.setUp();
// Now clear, reset, etc all your static data.
}
This is automatically run by JUnit before each test and will reset the environment. You can add one after as well, but before is better for ensuring a clean starting point.
The order of your tests is usually the order they are in the test class. But this should never be assumed and it's a really bad idea to base code on that.
Go back to the documentation. If you need more information.
The approach I took to this kind of problem was to do partial reinitialization before each test. Each test knows the preconditions that it requires, and the setup ensures that they are true. Not sure if this will be relevant for you. Relying on order often ends up being a continuing PITA - being able to run tests by themselves is better.
Oh yeah - there's one "test" that's run as the beginning of a suite that's responsible for static initialization.
You might want to look at TestNG, which supports test dependencies for this kind of functional testing (JUnit is a unit testing framework):
#Test
public void f1() {}
#Test(dependsOnMethods = "f1")
public void f2() {}

Categories