• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Writing the first test

 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've read all types of blogs and articles and treatises about the usefulness of Test Driven Development, and I understand the concepts and even the usefulness. But somehow my brain doesn't work like that. I always start out at too high a level and there isn't a simple implementation just to turn the bar green. My problem is always figuring out the first test to write. Maybe I'm just over-thinking it.

Given the following requirements for a system that should take an arithmetic expression String as input, and produce a formatted String result as output:

Input:


Output:


Input:

Output:


My first instinct would be to start with a test like this:

But that seems like pretty high level functionality. Am I writing the wrong test? Or am I expecting my implementation to be too polished too early?
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You *could* have that test first (although I'd consider that more of an integration test), but... wouldn't it make more sense to test the parser first? Or the tokenizer? Or...
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the advice David. I took it and started with test cases that look like this (not xUnit, but hopefully you can get the gist)

Like I said, my problem with TDD (or BDD in this case) is that I think too top-down. I'm trying to train my brain to move in a different direction though.
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm pretty sure I can handle specs. (No sense in declaring "expected", though, and it makes the test harder to read. Plus you don't always use it anyway.)

TDD and BDD are the same: write the most minimal test case that fails, write the code to make it pass. The output of a program is a large-scale behavior, and tests written for it will not pass until the sub-behaviors pass. That you were writing the large-scale behavior test first suggests you either (a) didn't test during development, or (b) expected it to fail for a long time while the actual code was developed.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:I'm pretty sure I can handle specs.


Ah, so you've broken the code! :) Although I should have known better than to question your abilities since you mention you're a 'Polyglottal Developer' right in your signature.

(No sense in declaring "expected", though, and it makes the test harder to read. Plus you don't always use it anyway.)


You're right of course. Point taken.

TDD and BDD are the same: write the most minimal test case that fails, write the code to make it pass. The output of a program is a large-scale behavior, and tests written for it will not pass until the sub-behaviors pass. That you were writing the large-scale behavior test first suggests you either (a) didn't test during development, or (b) expected it to fail for a long time while the actual code was developed.


The answer is (b). The way I decide what low-level behaviors to implement is to start with the high level abstraction, and then break that down into smaller and smaller problems until I get to a problem I can implement. What I like about the top-down approach is that I feel like it keeps me focused. The problem with that approach is that as you pointed out the tests will fail for a long time. (I'm sure there are other problems too, but that is the most obvious one to me).
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, there's nothing intrinsically wrong with long-failing tests--when I'm feeling saucy I'll code high-level behavioral tests up front, and low-level unit tests as required, and eventually the tests collide in the middle, everything goes green, and I go home :)
 
I have always wanted to have a neighbor just like you - Fred Rogers. Tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic