Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you do TDD in a non-trivial application? [closed]

Tags:

tdd

agile

I've read a number of books and websites on the subject of TDD, and they all make a lot of sense, especially Kent Beck's book. However, when I try to do TDD myself, i find myself staring at the keyboard wondering how to begin. Is there a process you use? What is your thought process? How do you identify your first tests?

The majority of the books on the subject do a great job of describing what TDD is, but not how to practice TDD in real world non-trivial applications. How do you do TDD?

like image 258
Its me Avatar asked Oct 17 '08 07:10

Its me


People also ask

Why is TDD difficult?

Writing GUI code with TDD is difficult. One area of TDD that's particularly challenging is programming GUIs. User interfaces are complex and difficult to test. They may also rely heavily on libraries, which can make writing clean tests and working through a design much more limited.

Which type of test do you write when doing test driven development?

With developer TDD you write a single developer test, sometimes inaccurately referred to as a unit test, and then just enough production code to fulfill that test. The goal of developer TDD is to specify a detailed, executable design for your solution on a JIT basis. Developer TDD is often simply called TDD.

Is TDD difficult?

Basically, TDD is hard! It needs skill, and it needs practice. The good news is that TDD rewards the effort. Once you get over the hurdle of working incrementally and writing fine-grained tests (hard), you'll find the implementation slots into place.


2 Answers

It's easier than you think, actually. You just use TDD on each individual class. Every public method that you have in the class should be tested for all possible outcomes. So the "proof of concept" TDD examples you see can also be used in a relatively large application which has many hundreds of classes.

Another TDD strategy you could use is simulating application test runs themselves, by encapsulating the main app behavior. For example, I have written a framework (in C++, but this should apply to any OO language) which represents an application. There are abstract classes for initialization, the main runloop, and shutting down. So my main() method looks something like this:

int main(int argc, char *argv[]) {
  int result = 0;

  myApp &mw = getApp(); // Singleton method to return main app instance
  if(mw.initialize(argc, argv) == kErrorNone) {
    result = mw.run();
  }

  mw.shutdown();
  return(result);
}

The advantage of doing this is twofold. First of all, all of the main application functionality can be compiled into a static library, which is then linked against both the test suite and this main.cpp stub file. Second, it means that I can simulate entire "runs" of the main application by creating arrays for argc & argv[], and then simulating what would happen in main(). We use this process to test lots of real-world functionality to make sure that the application generates exactly what it's supposed to do given a certain real-world corpus of input data and command-line arguments.

Now, you're probably wondering how this would change for an application which has a real GUI, web-based interface, or whatever. To that, I would simply say to use mock-ups to test these aspects of the program.

But in short, my advice boils down to this: break down your test cases to the smallest level, then start looking upwards. Eventually the test suite will throw them all together, and you'll end up with a reasonable level of automated test coverage.

like image 151
Nik Reiman Avatar answered Sep 29 '22 16:09

Nik Reiman


I used to have the same problem. I used to start most development by starting a window-designer to create the UI for the first feature I wanted to implement. As the UI is one of the hardest things to test this way of working doesn't translate very well to TDD.

I found the atomic object papers on Presenter First very helpful. I still start by envisioning user actions that I want to implement (if you've got usecases that's a great way to start) and using a MVP or MVC-ish model I start with writing a test for the presenter of the first screen. By mocking up the view until the presenter works I can get started really fast this way. http://www.atomicobject.com/pages/Presenter+First here's more information on working this way.

If you're starting a project in a language or framework that's unknown to you or has many unknown you can start out doing a spike first. I often write unit tests for my spikes too but only to run the code I'm spiking. Doing the spike can give you some input on how to start your real project. Don't forget to throw away your spike when you start on your real project

like image 42
Mendelt Avatar answered Sep 29 '22 17:09

Mendelt