Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

A colleague of mine was once at a seminar about agile development, where he heard it is possible to use unit tests as technical documentation. Something like using unit tests as an example of how to use the class.

A quick Google search provided TDD and Documentation, which proves it should be possible. But looking at our code, I see that we obviously failed to implement unit tests in such a way.

In my opinion unit tests are there to test code as a minimal unit, even with help of mock and fake classes and functions.

So, the questions are:

  • Isn't it the task of functional tests to show how a class (or set of classes) should be used?
  • If it is possible to use unit tests as technical documentation, are there some guidelines on how to implement such unit tests?
share|improve this question
2  
Unit tests are a source of documentation, but often should not be the only source. –  Garrett Hall May 16 '12 at 20:52
    
"But looking at our code, I see that we obviously failed to implement unit tests in such a way." ... ? Meaning your unit tests aren't understandable as example code? –  Steven Jeuris May 17 '12 at 0:31
    
@StevenJeuris We have many c++ unit tests, and some are long (30+ lines). I never looked into unit tests to see how the class is used. For that I used the doxygen documentation that we have and the code (where specific class is used), and I tried to understand from the class code what it is doing. This is new thing for me –  BЈовић May 17 '12 at 7:44

6 Answers 6

up vote 9 down vote accepted

If you are applying TDD, then each unit test you wrote corresponds to a functionality of a class. So as you write tests you are actually creating the class functionalities, dependencies, exceptions and also class documentation.

If you are not applying TDD, still unit tests give you idea about the class and what it does. Unit test names are very descriptive so you don't need to create a documentation mostly.

Consider a unit test like

public void Customer_Service_Can_Register_New_Customers(){...}
public void Customer_Service_Cannot_Register_Customers_With_Duplicate_Emails(){...}

These are self descriptive methods and easy to read too. So they also serve as documentation.

share|improve this answer

Unit tests, if well written DO serve as some documentation of a class or method or whatever.

Well written ones lead to more understanding by being easy to figure out what they are testing, but even poor tests give the reader some idea of how the thing being tested is supposed to act, and what things the author thought were important to test.

Heck, I've been known to write unit tests for external libraries - not because they need testing, but because I want to make sure my understanding of the library is correct. And in the future, if someone has questions about how I'm using things, well there's my understanding, right in the test code.

share|improve this answer
3  
Nice suggestion about tests for external code! –  Matt Fenwick May 16 '12 at 19:33
1  
The tests that check your understanding of a library are known as Characterization Tests. –  Carl Manaster May 21 '12 at 17:30
2  
@CarlManaster - I think I like the term Learning Test a little better - I know that Feathers lumps them in with Characterization Tests, but I think it's useful to distinguish tests intended to let you change something safely (Characterization Tests) from tests that just tell you about something. –  Michael Kohne May 21 '12 at 17:44

While functional tests can help you understand a whole piece of functionality, a unit test can help with understanding a small scope of code (like a single method).

Good unit tests will also server as good technical documentation, and there are a few things that can help write good, simple, and useful tests. The two most important points I've encountered are

  • Make sure that all your tests are independent. You should be able to run any subset of tests, in any order.

  • Make sure that you only test a single thing in each test. This keeps your tests specific, simple, but not brittle.

share|improve this answer

The idea of tests as acceptance criterias/documentation is an excellent one. However, unit tests tend to focus on architecture/code design rather than user stories - trying to document higher level use cases or requirements can be awkward. I haven't looked much into it (yet), but Behavior Driven Development might help with that problem.

share|improve this answer

I find examples much easier to learn from than documentation and unit tests serve great as that. Not only that, but they show me, by example, what NOT to do with a unit.

However, they can't be the only form of documentation. One must realize that brains all work differently. That's one thing I think people who recommend using JUST unit tests as your documentation or JUST the code completely miss. Even more poignant is the fact that even single brains learn different things from different mediums. I learn something completely different from a class diagram than I do just looking at code or reading API docs.

But at the end of the day, if diagrams and API docs are all you have then I'm probably screwed. I need examples. I need to see something being used. I might search the code for this, and lacking any other examples that's what I'm stuck with, but this will never tell me as much as a good unit test.

share|improve this answer

Testing today is all a mess of terminology where different people mean slightly different things, and definitions have changed over time.

For example, TDD used to be something that is now called BDD. The distinction is because what was unit-testing through test-driven development is now a much finer grained approach to testing methods (usually generated by automated tools). What used to be TDD was a slightly coarser way of testing units the size of classes, which I think is now called functional testing.

The idea that you can use (some form of) testing is that you can write a test that looks like how the user would use a unit of your code. It becomes an example for the docs, and a test at the same time.

So if you had a simple network class (for example). Rather than test each method individually, you'd approach testing that the class is the unit that needs testing. Then your unit test would exercise the whole unit by calling the method to initialise the object, setting the host and port, and calling a method to send data, possibly calling a method to receive too.

All that can fit into a single 'unit test' that would test the object by setting it into a configured state, and making it do some work. Further unit tests would exercise it with bad data, but you don't need to put those in the documentation.

This isn't considered unit testing today, but it all comes down to your definition of a unit.

share|improve this answer
    
Unit testing and functional testing are different things. If you start opening and closing connections, and using real resources, you are doing functional testing, and those tests are slow, whereas the unit tests have to be very fast. –  BЈовић Jun 3 at 5:52
    
You've bought into the hype of unit testing. They are not supposed to be small, or fast, or anything other than a means to test a unit of code in isolation. All the rest is guff made to make the bundled tooling appear correct. They can be slow and run daily, and large and full of example to work a class thoroughly. There is no simplistically-defined definition of a unit test. Don't get hung up on some arbitrary definition of what you're supposed to do, test your code in isolation, mocking or stubbing external connections and you have good testing. –  gbjbaanb Jun 3 at 9:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.