Sunday, January 6, 2008

Increase Automation of Test-Driven Development?

I believe Test-Driven Development can be improved by increased automation, some of the suggested thoughts could perhaps also be adapted to Behavioral-Driven Development (BDD).

Test-Driven Development (TDD) is a manual repeated cycle of writing and running tests, writing the least amount of code to make tests pass, and finally refactoring code (and tests) to make it shine. Writing tests gives the important "side effect" of simultaneously designing the API.

Automation of coding part?
The word automated is sometimes mentioned together with TDD, but that usually refers to automated unit tests (that needs to be manually written) or automated refactoring (that needs to be manually performed by the user e.g. using a refactoring tool/IDE).

Writing the code is done with a greedy approach, i.e. writing just enough to make tests pass, and the coding per TDD cycle is usually only a one-to-at-most-few short methods that is called by the new test, i.e. small increments of code. These small code increments could potentially be automatically induced using machine learning, e.g. using inductive logic programming, program synthesis or genetic programming. There are at least 2 problems with this 1) readability of induced code, 2) scalability. The readability part can be manually handled in the refactoring step of the TDD cycle, and wrt scalability of induction of TDD code increments I believe one can perhaps do smart (automated) things with mocks to prune the search space for the chosen machine learning algorithm.

Towards API Driven Design (ADD?)
One of the things that is hot in software testing research is development of tools that generates unit tests automatically based on code input, e.g. if you have a large chunk of (legacy) code with zero or low test coverage you can use such tools to get high (or even full) test coverage. In their simplest forms such tools just generate tests calling methods to be tested with various permutations of input (e.g. corner/extreme value inputs), this typically leads to enormous amounts of variable quality tests, and there are fortunately tools that are smarter and seems to promise higher quality tests, e.g. DSD-Crasher. I believe such tools can perhaps be used to automatically fill in missing test-cases in TDD, e.g. if you add one test with a set of input values, such tools can generate the corner-variants of the same test. This leads to a more API driven development, since the developer doesn't have to write the API many times (with various inputs), but gets support by the tool to fill in test cases.

Remarks related to recent blogosphere postings about code size
I agree that size is code's worst enemy, but believe it would be slightly better to deal with size if much of the coding and writing tests for it is offloaded to the computer so the coder can focus more on API driven development. I don't believe everybody should be afraid of a little typing if it is to improve readability of code, but they should spare their fingers when the computer is eager to fill in.

1 comment:

Knut Ola said...

Lack of readability of generated code is not a problem as long you stick to TDD. You will not touch the generated code. If you want to change the functionality, you change the test and regenerate the code.

Maybe what you are thinking about is a new paradigm in programming languages where you do not write code, but rather write test code. While you can write test code with the programming languages of today, they are not optimal for the purpose. There are way easier ways of specifying tests in a detailed way that through existing programming languages.