views:

1043

answers:

10

Can anyone suggest books or material Unit Tests? Some people consider codes without unit tests as legacy codes. Nowadays, Test Driven Development is the approach for managing big software projects with ease. I like C++ a lot, I learnt it on my own without any formal education. I never looked into Unit Test before, so feel left out. I think Unit Tests are important and would be helpful in the long run. I would appreciate any help on this topic.

My main points of concern are:

  1. What is a Unit Test? Is it a comprehensive list of test cases which should be analyzed? So lets us a say i have a class called "Complex Numbers" with some methods in it (lets says finding conjugate, an overloaded assignment operator and an overloaded multiplication operator. What should be typical test cases for such a class? Is there any methodology for selecting test cases?

  2. Are their any frameworks which can create unit tests for me or i have to write my own class for tests? I see an option of "Test" in Visual Studio 2008, but never got it working.

  3. What is the criteria for Units tests? Should there be a unit test for each and every function in a class? Does it make sense to have Unit Tests for each and every class?

+2  A: 
Jerry Coffin
The google C++ testing framework should also be mentioned: http://code.google.com/p/googletest/
Georg Fritzsche
+1 gf, googletest (and googlemock) is the best unit testing framework for C++. Amount of overhead when writing tests is about as minimal as it can get in C++. Other frameworks emphasize too much test suites and other irrelevant infrastructure, while googletest focuses on helping to write tests easily.
tequilatango
A: 

Here's something on when not to write unit tests (i.e. on when it's viable and even preferable to skip unit testing): Should one test internal implementation, or only test public behaviour?

The short answer is:

  • When you can automate integration tests (because it's important to have automated tests, but those tests don't have to be unit tests)
  • When it's cheap to run the integration test suite (no good if it takes two days to run, or if you can't afford to let every developer have access to an integration test equipment)
  • When it isn't necessary to find bugs before integration testing (which depends in part on whether components are developed separately or incrementally)
ChrisW
+1  A: 

I can't answer your question for Visual Studio 2008, but I know that Netbeans has a few integrated tools for you to use.

  1. The code coverage two allows for you to see which paths have been checked, and how much of the code is actually covered by the unit tests.
  2. It has the support for the unit tests built in.

As far as quality of tests I'm borrowing a bit from the "Pragmatic Unit Testing in Java with JUnit" by Andrew Hunt and David Thomas:

Unit testing should check for BICEP: Boundary, Inverse relationships, Cross-checking, Error conditions, and Performance.

Also quality of the tests are determined by A-TRIP: Automatic, Thorough, Repeatable, Independent, and Professional.

monksy
+1  A: 

In .NET I strongly recommend "The Art of Unit Testing" by Roy Osherove, it is very comprehensive and full of good advice.

Mathias
+1  A: 

Unit tests are simply a way to exercise a given body of code to ensure that a defined set of conditions leads to the expected set of out comes. As Steven points out, these "exercises" should check across a range of criteria ("BICEP"). Yes, ideally you should test all of your classes and all of the methods in these classes although there is always some room for judgement: testing shouldn't be an end in itself but rather should support the wider project goals.

Ok, so...theory is nice but to really understand Unit Testing, my recommendation would be to pull together the appropriate tools and just get started. Like most things in programming, if you have the right tools, it is easy to learn by doing.

First, pick up a copy of NUnit. It is free, easy to install and easy to work with. If you'd like some documentation, check out Pragmatic Unit Testing in C# with NUnit.

Next, go to http://www.testdriven.net/ and get a copy of TestDriven.net. It installs into Visual Studio 2008 and gives you right-click access to a full range of testing tools including the ability to run NUnit tests against a file, directory or project (typically, tests are written in a separate project). You can also run tests with debugging or, coolest of all, run all the tests against a copy of NCover. NCover will show you exactly what code is being exercised so you can figure out where you need to improve your test coverage. TestDriven.net costs $170 for a professional license but, if you are like me, it will very quickly become an integral tool in your toolbox. Anyway, I've found it to be an excellent professional investment.

Good luck!

Mark Brittingham
A: 

Buy the book "xUnit Test Patterns: Refactoring Test Code". Its very excellent. It does cover high-level strategy decisions as well as low level test patterns.

Frank Schwieterman
+7  A: 

An important point (that I didn't was originally realise) is that Unit Testing is a testing technique that can be used by itself, without needing to apply the full Test Driven methodology.

For example, you have a legacy application that you want to improve by adding unit tests to problem areas, or you find bugs in an existing app. and write a unit test to expose the problem code and then fix it. These are semi test-driven, but can completely fit in with your current (non-TDD) development process.

Two books I've found useful are:

Test Driven Development in Microsoft .NET

A very hands on look at Test Driven development, following on from Kent Becks' original TDD book.

Pragmatic Unit Testing with C# and nUnit

Short and to the point about what unit testing is, and how best to apply it.

In response to your points:

  1. A Unit test, in practical terms is a single method in a class that contains just enough code to test one aspect / behaviour of your application. Therefore you will often have many very simple unit tests, each testing a small part of your application code. In nUnit for example, you create a TestFixture class that contains any number of test methods. The key point is that the tests "test a unit" of your code, ie a smallest (sensible) unit as possible. You don't test the underlying API's you use, just the code you have written.

  2. There are frameworks that can take some of the grunt work out of creating test classes, however I don't recommmend them. To create useful unit tests that actually provide a safety net for refactoring, there is no alternative but for a developer to put thought into what and how to test their code. If you start becoming dependent on generating unit tests, it is all too easy to see them as just another task that has to be done. If you find yourself in this situation you're doing it completely wrong.

  3. There are no simple rules as to how many unit tests per class, per method etc. You need to look at your application code and make an educated assessment of where the complexity exists and write more tests for these areas. Most people start by testing public methods only because these in turn usually exercise the remainder of the private methods. However this is not always the case and sometimes it is necessary to test private methods.

In short, even experience unit testers start by writing obvious unit tests, then look for more subtle tests that become clearer once they have written the obvious tests. They don't expect to get every test up-front, but instead to add them as they think of them.

Ash
+1  A: 

Nowadays, Test Driven Development is the approach for managing big software projects with ease.

That is because TDD allows you to make sure after each change that everything that worked before the change still works, and if it doesn't it allows you to pinpoint what was broken, much easier. (see at the end)

What is a Unit Test? Is it a comprehensive list of test cases which should be analyzed?

A Unit Test is a piece of code that asks a "unit" of your code to perform an operation, then verifies that the operation was indeed performed and the result is as expected. If the result is not correct, it raises / logs an error.

So lets us a say i have a class called "Complex Numbers" with some methods in it (lets says finding conjugate, an overloaded assignment operator and an overloaded multiplication operator. What should be typical test cases for such a class? Is there any methodology for selecting test cases?

Ideally, you would test all the code.

  • when you create an instance of the class, it is created with the correct default values

  • when you ask it to find the conjugates, it does finds the correct ones (also test border cases, like the conjugate for zero)

  • when you assign a value the value is assigned and displayed correctly

  • when you multiply a complex by a value, it is multiplied correctly

Are their any frameworks which can create unit tests for me or i have to write my own class for tests?

See CppUnit

I see an option of "Test" in Visual Studio 2008, but never got it working.

Not sure on that. I haven't used VS 2008 but it may be available just for .NET.

What is the criteria for Units tests? Should there be a unit test for each and every function in a class? Does it make sense to have Unit Tests for each and every class?

Yes, it does. While that is an awful lot of code to write (and maintain with every change) the price is worth paying for large projects: It guarantees that your changes to the code base do what you want them to and nothing else.

Also, when you make a change, you need to update the unit-tests for that change (so that they pass again).

In TDD, you first decide what you want the code to do (say, your complex numbers class), then write the tests that verify those operations, then write the class so that the tests compile and execute correctly (and nothing more).

This ensures that you write the minimal code possible (and don't over-complicate the design of the complex class) and it also ensures that your code does what it does. At the end of writing the code, you have a way to test it's functionality and ensuring it's correctness.

You also have an example of using the code that you will be able to access at any point.

For further reading/documentation, look into "dependency injection" and method stubs as used in unit testing and TDD.

utnapistim
A: 

Nowadays, Test Driven Development is the approach for managing big software projects with ease.

TDD built on unit tests but they are different. You don't need to be use TDD to make use of unit tests. My personal preference is to write test first, but I don't feel I do the whole TDD thing.

What is a Unit Test?

A Unit Test is a bit of code that tests the behaviour of one unit. How one unit is defined differs between people. But in general they are:

  1. Quick to run
  2. Independent from each other
  3. Test only a small part (a unit ;) of your code base.
  4. Binary outcome - That is it passes or fails.
  5. Should only test one outcome of the unit (for each outcome create a different unit test)
  6. Repeatable

Are their any frameworks which can create unit tests

To write the tests - Yes but I've never seen anyone say anything nice about them.
To help you write & run tests, a whole bunch of them.

Should there be a unit test for each and every function in a class?

You have a few different camps in this - the 100%ers would say yes. Every method must be tested and you should have 100% code coverage. The other extreme is that unit tests should only cover areas that you have even encounter bugs or you expect to find bugs. The middle ground (and the stand I take) is to unit tests everything that is not "too simple to break". Setters/getters and anything that just calls a single other method. I aim to have 80% code coverage and a low CRAP factor (so a low chance I've been naughty and decided to not test something as it was "too complex to test).

The book that helped me "get" unit tests JUnit in Action. Sorry I don't do much in the C++ world, so I can not suggest a C++ based alternative.

mlk
+2  A: 

While you've already accepted an answer to your question I'd like to recommend a few other books not yet mentioned:

  • Working Effectively with Legacy Code - Michael Feathers - As far as I know this is the only book to adequately tackle the topic of turning existing code that wasn't designed for testability into testable code. Written as more of a reference manual, its broken down into three sections: An overview of the tools and techniques, A series of topical guides to common road blocks in legacy code, A set of specific dependency breaking techniques referenced throughout the rest of the book.
  • Agile Principles, Patterns, and Practices - Robert C. Martin - Examples in java, there is a sequel with examples in C#. Both are easy to adapt to C++
  • Clean Code:A Handbook of Agile Software Craftsmanship - Robert C. Martin - Martin describes this as a prequel to his APPP books and I would agree. This book makes a case for professionalism and self-discipline, two essential qualities in any serious software developer.

The two books by Robert (Uncle Bob) Martin cover much more material than just Unit testing but they drive home just how beneficial unit testing can be to code quality and productivity. I find myself referring to these three books on a regular basis.

codeelegance
+1. I would say "Test Driven" by Lasse Kossela is a good introduction, more directly in tuned to TDD. There is also a book about "Brownfield Development in .NET" (I think) that may deal with shoehorning tests around existing code - haven't read it, though.
cwash