Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When doing BDD, must I first TDD each piece of code needed to make an acceptance test pass?

I've been given a kata to work on over the weekend. Before starting it I really just wanted to gather some thoughts. I'm not looking for the solution, just some ideas on the best approach/practice.

From the conversation I had it would seem that I need to use a BDD --> ATDD (relate to scenarios in gherkin) --> TDD approach. I'm just looking to work out the best approach.

My current thinking is to

1) Create a specflow project and distill the user story into a gherkin.

2) Create the associated acceptance tests in the gherkin (the scenarios) using GWT syntax and thus generate my ATTD style tests in the [binding] class (right click 'generate').

3) Make the gherkin ATDD tests pass.

The conundrum I have is that the tests that link directly to the ATTD tests in my gherkin file don't give me low level enough testing.

So what do I do? do I write my high level ATDD tests and then before making them pass do I dig down deeper and just write pure TDD tests to design my lower level objects?

Yeah, I haven't worked out how to work in a totally BDD manner (pure style) yet so just wondered how I dig down. I appreciate that you should work incrementally and complete one test and pass but I feel I need to start at a high level ATDD test and then go deeper, so the higher level tests wont work until I make my low level code work, but to follow TDD I need to test that low level code and so I have already broken the principle of 1 unit test then pass then refactor.....

Hope someone understands how to tell me 'how' to approach this without actually doing it. But here is the problem as provided to me...(I appreciate if the tester sees this they may fail me for asking here , but its more important that I learn rather than get the job). Yes I know I'm MAD :-)

I'd also love to know if I should have a separate project for my pure TDD tests. What's the best project structure? I'm thinking 1 specflow project and a .test project and a class library and a console app for the runtime.

P.S. anyone that helps me with this has a favour owed to them from me. hug or charity donation. Or just the +1 on here i guess is what you really want :-/

Rock, Paper, Scissors

User Story Front
+--------------------------------------------------+
|                                                  |
|     Title: Waste an Hour Having Fun              |
|                                                  |
| As a frequent games player,                      |
| I'd like to play rock, paper, scissors           |
| so that I can spend an hour of my day having fun |
|                                                  |
| Acceptance Criteria                              |
|  - Can I play Player vs Computer?                |
|  - Can I play Computer vs Computer?              |
|  - Can I play a different game each time?        |
|                                                  |
+--------------------------------------------------+

User Story Back
+--------------------------------------------------+
|                                                  |
| Technical Constraints                            |
|                                                  |
| - Doesn't necessarily need a flashy GUI          |
|   (can be simple)                                |
| - Can use any modern language                    |
|                              |
| - Libs / external modules should only be used    |
|   for tests                                      |
| - Using best in industry practices               |
|                                                  |
+--------------------------------------------------+

Don't know the game? http://en.wikipedia.org/wiki/Rock-paper-scissors

I'd be looking for a scaled down version (think minimum viable product). No database (i.e. session stored), simple interface - 2 or 3 hours' worth of work (tops) would be perfectly reasonable. I'm not looking for a full blown thing, just a small thing well crafted. If this was Java and not .NET, and more back end oriented I would make do with a console app. Looking for unit tests and well factored code in C#. What I'm looking for is coders that happen to use C# ASP.Net MVC.

like image 263
Exitos Avatar asked Nov 13 '22 09:11

Exitos


1 Answers

It's possible to follow TDD strictly while doing BDD, but you don't have to, and I don't.

BDD says write acceptance tests and drive out the details with unit tests. So, after you write an acceptance test for a feature, you can either

  • write all the code needed to make the acceptance test pass (then refactor), or

  • think about what classes and such you'll need to make the acceptance test pass, TDD each of them (i.e. write unit tests for each of them, make those tests pass, and refactor), and then run the acceptance test to make sure it passes (and refactor).

Regardless of which of these two methods one follows, one test-drives requirements which don't merit their own acceptance tests by writing unit tests. However, the first method does NOT require going back and writing unit tests for every class created when implementing the acceptance test.

I use the first method, because

  • it's easier to think about. It doesn't require as much design up front, and it doesn't require context-switching between acceptance and unit tests.

  • it creates only the code needed to make the acceptance test pass. I invariably find that writing unit tests before (or without) acceptance leads to wrong guesses and extra code.

  • it doesn't test any requirements twice. Minimal test suites are faster and easier to maintain.

Advantages of the second method that I can see are

  • it breaks up the work needed to make the acceptance test pass. (But, with the tools I use and applications I work on, I don't usually have a problem just implementing the acceptance test in one go. If I do, I cut corners in the first pass and go back and fill them out in a second pass.)

  • there is always a unit test for every class, so it's easy to find a test to run to make sure you haven't broken a given class when you change it. (But you're going to have to find and run the relevant acceptance test(s) soon enough anyway.)

Regarding project structure, I always find that it's better to keep tests of all kinds in the same project, repository, etc. as the code. Out of sight, out of mind.

like image 107
Dave Schweisguth Avatar answered Nov 17 '22 00:11

Dave Schweisguth