I have these rules that I use for unit tests, primarily because I encounter so many teams that start writing end to end tests, call them unit tests, and give up because "testing takes too long". To me, a test is not a unit test if:
Tests that do those things are okay, but to me they aren't unit tests, and they should be segregated from true unit tests.
- It talks to a database
- Communicates across a network
- Touches the file system
- You can't run it at the same time as any of your other unit tests.
- You have to do special things to your environment to run it (like editing configuration files).
Posted by Jeffrey Fredrick at August 24, 2005 12:42 PM
TrackBack URL for this entry:
I personally don't have a problem with the "touches-the-file-system" one, if it's the _test_ touching the file system - e.g. to read in expected results.
Data-driven tests are often best configured by files, for example.
Posted by: Robert Watkins on August 24, 2005 08:48 PM
Those examples are examples of what I call the external dependencies antipattern (see http://www.exubero.com/junit/antipatterns.html#External_Dependencies). As you say, they're not really "unit" tests, but rather end-to-end or integration tests. Having said that, I'd probably agree with Robert: touching the filesystem (or at least loading resources from the classpath) is OK by me, especially if it helps produce better factored code in the unit tests themselves.
Posted by: Joe Schmetzer on August 26, 2005 08:14 AM
I'm tempted to change some of my tests that pull data from files and move them into code, perhaps even creating a separate interface that has the file contents as a constant. if you've got 1000 tests and you can change them from taking 1 second to taking .01 seconds...
Posted by: Jeffrey Fredrick on August 26, 2005 09:04 AM
I think I would have trouble with Java code that contained large chunks of text embedded throughout. It's a coding smell that I've learned to avoid through meditating the advice of our revered thought leaders and bitter experience. Just because it's a unit test doesn't excuse the programmer from good coding practices.
Having said that, if the strings were used with meaningful symbolic names (as you say, defined in an interface), I'd be happier.
While on the subject, Perl and other scripting/shell languages have the wonderful "here doc" notation for multiline strings (see http://www.stonehenge.com/merlyn/UnixReview/col12.html)
Is there a similar construct in Java?
Posted by: Joe Schmetzer on August 26, 2005 02:23 PM
Yes exactly, meaningful symbolic names hidden in the interface is exactly what I had in mind.
On the mailing list Chris Dollin recommended "Campaign for having a `fat strings` syntax in your Preferred Programming Language?", so you're not the only person to be thinking that direction.
Posted by: Jeffrey Fredrick on August 26, 2005 04:44 PM