Igor's Blog

"... no matter what they tell you, it's always a people problem!"

Sunday, April 17, 2005

Test Driven Development TDD

Impact of Test Driven Development together with test automation on the software design.


by Igor Stoyanov.

I have already mentioned test driven development (TDD) in previous post on this blog. This is often also referred to as test first development.I am TDD practitioner myself, and recommend it highly. Although, some of the other XP techniques can be strongly debatable, I believe that TDD development and continues integrations are mandatory methodologies for the success of a software project today. From being the poor cousin of development, the unit testing - has become welcomed as the heart of the software development.

TDD brings many benefits. For example:

There are plenty that can be added to this topic. Good resources on this topic is this excellent blog: Exploration Through Example, the book “Test-Driven Development – A Practical Guide” by David Astels as well as very good and important book "J2EE Development withoug EJB" by Rod Johnson.


It is not the most intuitive thing to test something that doesn’t exist. In order to become comfortable with TDD you should start practicing with full believe and fully apply this methodology. Very soon, the benefit would be very obvious. It is simple concept, but I need some working example in order to fully realize the power of TDD approach.


I will briefly summarize the most important steps in TDD development and demonstrate a very simple example.


The most important characteristic in TDD are:


Before a demonstration of TDD with a simple test case, I want to mention here that in order for TDD to have the desired effect, developers should create pure unit test. The most popular and sufficient Java framework is JUnit. The design and the decision for technologies that will be used should be strongly impact by the fact whether it is easily testable and in some cases, if it is testable at all. I want to add immediately here that no test can prove full coverage and suffice by itself for good testing approach to a particular application. A TDD development implies that developers are mainly involved in unit testing, also known as white testing. Continues integration testing and rigorous functional testing are invaluable testing approaches but they should not be primarily responsibility of developers.


As a practitioner of TDD I wouldn’t choice working with EJB technology if I have other valuable alternatives. EJB are managed during runtime by EJB container. Its development is not only very complex but it very hard, and in some cases (Entity Beans) it is almost impossible to test, not to mention that TDD is unthinkable. Attempts are made to solve this problem with EJB mocks, which is not very successful and using in container testing frameworks as Cactus. Although, using Cactus is irreplaceable for integration in container testing of EJB, it can not be used for pure unit testing. As I mentioned before, unit testing should provide very fast feedback to a developer in order to be useful. Using cactus as unit testing implies that for testing of even single method, we should wait for deployment and very complex initializing operations of the targeted container before we have a feedback. Not to mention the complexity of setting up Cactus framework on the firs place.

Luckily, lightweight containers come to rescue. Using these lightweight containers involves primarily the use of POJO objects that are the easiest to test and can lead to the best OO design of a given software project. The most popular ones are Spring framework and Pico container. I will talk much more about these containers a little later on.


TDD demonstration:

Requirements:

Business functionality: Withdrawal

Can anticipate: - Refusing access to data storage

- Insufficient Funds in the account

Prerequisites: - There is an existing account (I am really hoping for. J.)

- The account can accept deposits.

- The account knows the current balance.

Targeted test code:

public class BankAccountTest extends TestCase {
private BankAccount account;

protected void setUp() throws Exception {
account = new BankAccount();
}

public void testValidWithdrawalSuccedsWithinLimit() throws DataAccessException,
InsuffiecientFundsException {
account.setBalance(45.0);
account.withdrawal(20.0);
assertEquals(25.0, account.getBalance());
}

public void testNotValidWithdrawalFailOutsideLimit() throws DataAccessException{
try {
account.setBalance(45.0);
account.withdrawal(46.0);
fail("Bank should have rethrown InsufficientFundsExcepiton");
}catch(InsuffiecientFundsException ex) {
assertEquals("Correctly calcualted amount fo unapproved overdraft",1.0, ex.getShorfail());
}
}
}

|| Igor, Sunday, April 17, 2005

0 Comments:

Add a comment