This article describes basic idea of TDD (Test-Driven-Development). Here you can find sample functions with tests and table with pros and cons based on our experience of using test driven software development.You can make your own decision of using TDD in your application development processes after reading the article.
General information about Test Driven Development
Recently there is a lot of discussion around agile technologies in general and TDD in particular. As it is heavily used in our team, I’d like to say a couple of words about it too. First, I want to speak a bit about Unit-testing in general. If you want to create big and well-working application, you need to test it, because even very good programmers make mistakes. You have two ways to solve that:
- Have many beta-testers
- Use TDD
Test process automation - why bother and how to do?
But even if you have a crowd of beta-testers, you still need to add automation to test process. It allows your crowd of testers spent more time to test functionality. What is a unit-testing? Imagine that your program consists of functions. For example, you need a program to find area of circle. You can write something like that:
public static void GetCircleArea(double r)
{
if (r<0) throw ArgumentOutOfRangeException;
return Math.PI * Square(r)
}
private static double Square(double r)
{
return r * r;
}
Now you naturally want to check if this is right.
[TestFixture]
public class CircleAreaTest
{
[Test]
public void GetCircleArea1()
{
Assert.AreEqual(Math.PI, tst.GetCircleArea(1));
}
[Test]
public void GetCircleArea2()
{
Assert.AreEqual(Math.PI*100, tst.GetCircleArea(10));
}
[Test]
public void GetCircleArea3()
{
Assert.AreEqual(0, tst.GetCircleArea(0));
}
}
Add something like that, if you think, that errors need to be checked too:
[Test, ExpectedException("System.ArgumentOutOfRangeException")]
public void GetCircleArea4()
{
tst.GetCircleArea(-1);
}
So, you can run all tests and check if everything is ok or something is broken. Sounds good till now, isn’t it? But if you have to test code which depends on some data, you need to prepare some data before test and clean it after that. For that purpose you can use keywords [SetUp], [TestFixtureSetUp], [TearDown], [TestFixtureTearDown]. You may need to create too much test stuff: test users, test configurations, test data etc. For example, our code in a part of a big project looks like this: [SetUp]
public void Setup()
{
NHibernateHelper.UseStaticSession(true);
log.Info("Start Setup");
ClearClient();
SetupClient();
NHibernateHelper.CloseSession();
log.Info("Setup Done");
}
ClearClient() and SetupClient() contains a lot of other code, which we use. So, preparation and cleanup test data can take a lot of your time. N.B. In big projects previous tests can affect next ones. In our practice there were situations, when single a test was green, but if you run whole fixture, it broke. This can signal you have bad SetUp in that test or some of previous tests hadn't cleared necessary data. The search of such errors is hard work. So, I want to give table with pros and cons of TDD:
Table with pros&cons of Test Driven Development
Pros | Cons |
Good indicator of project health: If all tests are green, you can be sure that everything works (if the tests were correct themselves ;-) ) | If some test does not work, you don’t know where the problem is, in program or in test. |
Time for testing after changes in project decreases greatly. Much of hand test work can be done with Unit tests. | Development time increases too. Every method needs testing, and if you have a big application with dependencies you need to prepare and clean your data for tests |
You can use tests as indicator of developers work | This is not ideal indicator, neither better nor worse than lines of code or man-a-hour |
If your application is written in Functional style, you will have none of drawbacks listed | Not many applications written using functional style. And all of them live in non-functional environment |
In all cases you should remember: “There is no silver bullet”. For our team and for our products this approach works perfect and I believe if you didn’t try it yet, you should – the chances you’ll like it are very high. Denis P, Alexey V, .Net team, Binary Studio