wood burning stoves 2.0*
The moose likes Testing and the fly likes JUnit tests that depend on other tests Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Engineering » Testing
Bookmark "JUnit tests that depend on other tests" Watch "JUnit tests that depend on other tests" New topic
Author

JUnit tests that depend on other tests

Simon Joseph Aquilina
Ranch Hand

Joined: Feb 14, 2006
Posts: 102
Hello, I have read that unit tests should ideally be independent from one another. However I can think of several scenarios where one unit test cannot be completely independent from another unit test.

For example imagine a simple program that moves a file from Folder A to Folder B.

The first unit test I can think of is to put a file in folder A and check if after a few seconds the file is moved to folder B.
The second unit test is to check the content of the file in folder B and see if this is correct.

However the second test can never be done unless the first test is successful.
What I did in the past is call the first test from the second test

Or maybe JUnit is not the right testing tool for this type of work?

Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4458
    
    6

I'm not convinced that JUnit can't be used to test these scenarios. However, to call these kind of tests "unit" tests is not appropriate. One of the things a unit test shouldn't do is access the file system. A test that crosses system boundaries and does things like access the file system or call a web service or hit a database is an integration test. A unit test should be fast, very fast. Accessing the file system slows the test down. So does accessing a database, a web service, etc.

As for your assertion that some unit tests cannot be completed independently of each other, I have to disagree in this case. As with most things in programming, you need to break things up into smaller chunks to separate responsibilities and concerns. You have to make some assumptions when you test things in isolation. In your scenario, you think that because step A (move file) must be performed before step B (check file contents in target folder), then you also need to test in that order. It doesn't have to be that way though. If I were testing for step B (check file contents), I would use two sets of input to test the class that performs step B (let's call it the Checker): the first is the "good" version and the second one will be a "corrupted" version. That is, I assume that if step A was successful, then the Checker would get the good input. Otherwise, it would get the bad/corrupted input. I would end up with at least two tests for Checker: one that tests its behavior when it gets good input and another that checks behavior when it gets bad input.

Now there's still the problem of accessing a file in a unit test. Well, that's easy enough to solve too. I'd refactor so that I'm using a Reader (an abstract class) in the Checker class. That way, I can give it a StringReader for unit testing so I can avoid accessing the file system. The test input would simply be Strings. This allows me to test core functionality faster. If I really want to see it work with a file as input, then I'd write an integration test (one that extends the unit test but overrides the methods that provide a Reader implementation) that passes in a FileReader. If the tests pass with a StringReader, it should also pass with a FileReader. The important thing to remember is that your tests and implementation are programmed to the abstract Reader class, not a particular implementation; you'd just have test helper methods that provide a particular implementation of Reader.

Note that I'm just guessing at the need to use a Reader but the idea is the same if you're doing something else to verify the result of step A: program to abstractions and in your unit tests, use a "fake" implementation that approximates what the actual input would be like.

All of this assumes you have classes that are factored in a way that allows you to test in the manner that I described. If you can't test in isolation as I described, then you probably need to refactor your code and separate concerns and responsibilities.

Hope this helps.


Junilu - [How to Ask Questions] [How to Answer Questions]
 
wood burning stoves
 
subject: JUnit tests that depend on other tests