Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

According to the commonly used TDD strategy, to implement something, you write a test that fail the code first, write the simplest code, refactor, and then repeat. I am trying to imagine this scenario with implementing a flexible length list (e.g. List<T> in .net.

Let's say I first test by inserting one item. Probably the simplest way to achieve this is by backing the list with an array with length 1 (which will pass the test). Nothing to refactor here, so I'll go ahead and write another test that insert 2 items. I'll simply change the array length to 2, and the test pass again. Then I write test with 3 items, expand the array, and repeat again. I will end up forever doing this until I'm tired.

Is this an exception to the fail-test-first strategy? Or am I missing something in the above strategy?

PS: The actual implementation backs the list with an array which grows twice as large every time the number of elements exceed the array length.

share|improve this question
In your procedure, you never test that the list is of flexible length, i.e., a test that should fail on fixed length lists. – mouviciel Jan 31 at 13:46
1  
The simplest way to achieve the one-item list is not to back it with an array; it is to back it with the item. – Carl Manaster Jan 31 at 14:56

3 Answers

You can use for in tests. I would create one test which inserts one item. And then another test which inserts a random number of items (where count > reallocation size).

I would however never start with an internal array size of 1. There's no point, it's a list, isn't it?

share|improve this answer
The principle is writing the simplest thing that works, right? – Louis Rhys Jan 31 at 8:38
2  
Are you suggesting using a rand() in a test? As far as I'm concerned this is something to be very wary of: it opens up the possibility of a test that sometimes passes. If you mean using a predefined but randomly-selected value, then fine. :) – Baqueta Jan 31 at 11:36
@Baqueta - not if you have a consistent rand seed ;-) – MadKeithV Jan 31 at 12:38

"Write the most simple thing that could possibly work" is one principle, but it is not the only one, and it isn't always the most important one. "Don't repeat yourself" is arguably more important, and repeating yourself the way you describe is definitely not justified by "most simple". As soon as you notice repeating yourself, you should switch to a solution that can handle more than one list length.

Note that this solution may very well still be a fixed-length array if you know that you will not need more than a given number of elements as per the requirements. Alternatively, it might be a dynamic structure that grows with the demands made on it. But in no case is it useful to climb the latter of integers one by one - not least because you can't possibly reach the top.

share|improve this answer
2  
What do you mean, you can't reach the top? If it's 16-bit signed integers, and each iteration takes 10 seconds, you'll be done in less than a week! – tdammers Jan 31 at 10:22

Ok, so you are doing what you think is the simplest thing that works, but you haven't defined your problem adequately.

Turn the problem around and look at what you have. "Implement a List clone" has many nuances to it which need to be expanded and documented. What is the purpose of this List clone? What number of items is it expected to support?

Generally answers to these and other questions come out at the beginning. For example, ask yourself why are you implementing a List replacement? If it's just a coding exercise, you need to flesh out a scenario a bit. In the real world you might be doing this because the existing List implementation does not exhibit certain characteristics you want. It might be too slow or not sorted or unable to cope with a gazillion items or what ever. That is what you are lacking here.

To restate the problem, how will you know that you are done? What are your acceptance criteria? What does "Working and complete" mean for this problem? TDD may flush out issues like what happens if you try and access an item at position "-3.2", but it actually doesn't have to. What it is supposed to do is make sure your code a) does what it is expected to do and b) continues to do what is expected of it when you refactor or replace it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.