Re: Three Law of TDD - to strictly follow, or not?

"Jeff Langr [email protected] [testdrivendevelopment]" <[email protected]> Tue, 26 Aug 2014 11:31:37 -0600
Newsgroups gmane.comp.programming.test-driven-development
Message-ID <CAO5C3te9fU9x0T6WLDzwSC7hQpFFr4a8_5Ls+DKJH1dhWhx2VA@mail.gmail.com>
Hi Kaleb,

Regarding "an incomplete but green test is at best misleading and at worst
wrong: if a test is green it should be a valid test, and a partial or
incomplete test is not valid."

... If I think about using, say, a tool like Infinitest that is constantly
running tests, it reports green against "incomplete" tests, and I'm ok with
that. So I don't think it's "wrong" per se.

I've both strictly followed the three laws and not. For me, it depends upon
tools and problem at hand, as others have suggested. Mostly, I fix things
that are obvious problems at the earliest possible opportunity rather than
wait, but I'm not dogmatic about it.

Jeff

*Langr Software Solutions, Inc.*

*http://langrsoft.com <http://langrsoft.com/>*
Modern C++ Programming with TDD (http://pragprog.com/book/lotdd)
Agile in a Flash (http://pragprog.com/book/olag)
Agile Java: Crafting Code with Test-Driven Development
  (*http://www.amazon.com/Agile-Java-Crafting-Test-Driven-Development/dp/0131482394
<http://www.amazon.com/Agile-Java-Crafting-Test-Driven-Development/dp/0131482394>*
)

On Tue, Aug 26, 2014 at 9:48 AM, Kaleb Pederson [email protected]
[testdrivendevelopment] <[email protected]> wrote:

>
>
> Over the last three years I've been doing training on and advocating TDD
> where I work and a number of people have been striving to learn and use TDD
> in their daily development :).
>
> --- An experience with coworker 1 ---
>
> One of these coworkers recently published a 6-part series on TDD that
> starts off assuming no prior experience with TDD (
> https://www.simple-talk.com/dotnet/.net-framework/a-tdd-journey-1-trials-and-tribulations/
> ).
>
> In part two, having recently introduced the three laws of TDD, he wrote
> the following (
> https://www.simple-talk.com/dotnet/.net-framework/a-tdd-journey-2--naming-tests-mocking-frameworks-dependency-injection/
> ):
>
> [Test]
>
> public void Execute_delegates_to_IWidgetLoader_to_load_widget_details()
>
> {
>
>     var activator = new WidgetActivator();
>
>  }
>
>
> At this point the test fails because WidgetActivator doesn't exist. He
> then proceeds to introduce a dependency and a constructor parameter before
> making the test pass:
>
> var mockWidgetLoader = new Mock<IWidgetLoader>();
> var activator = new WidgetActivator(mockWidgetLoader.Object);
>
> When a commenter pointed out that he was violating the three laws of TDD
> of he commented:
>
> "When adding a new test, you do not stop as soon as it turns red; rather
> you stop when the test is completely written. Then you labor to make that
> test turn green by modfiying [sic] the class-under-test. Think about it
> this way: if you write a partial test then make it go green, you now have a
> passing test *that is wrong*. A test should be green if and only if it is
> valid."
>
> I disagree with the comment because it allows multiple unnecessary lines
> of code to be written and doesn't provide a progression that guarantees
> that all production code is effectively "tested"/covered. It also makes it
> harder to get feedback from the test about the design of the system. Sure,
> the developer might tweak the test code to improve the API but at that
> point the API design isn't supported by a working implementation so it's
> not necessarily going to reveal design defects as quickly.
>
> Another person pointed out that "an incomplete but green test is at best
> misleading and at worst wrong: if a test is green it should be a valid
> test, and a partial or incomplete test is not valid."
>
> --- An experience with coworker 2 ---
>
> Coworker 2 recently came to me with some questions. He described his
> process wherein he would:
>
> * Create an empty test
> * Add a variable assignment: var instance = new MyClass();
> * Introduce the class
> * Add dependency1 to that class: var instance = new MyClass(dep1);
> * Add that dependency as a constructor parameter
> * Add dependency2 to that class: var instance = new MyClass(dep1, dep2);
> * Call the method to be under test: var result = instance.Execute();
> * Define the method under test
> * Add a parameter to the callsite of the method under test: var result =
> instance.Execute(param1);
> * Add the new parameter to the implementation of the method under test
> * Add another parameter to the callsite of the method under test: var
> result = instance.Execute(p1, p2);
> * ...
>
> The story, in short, is that no matter what he was doing extremely small
> steps -- steps that felt unnaturally small to me. Ultimately he had a
> number of problems which seemed to be because he wasn't letting the tests
> guide the implementation but he felt the implementation went really slowly
> because after writing a fair amount of code and he'd have to come back and
> modify many of his tests when a new parameter to a method needed to be
> added.
>
> I introduced him to ATDD/double-loop TDD in hopes that it'd help him work
> in vertical slices, let the system evolve, and help him discover the
> required parameters/dependencies early in the process.
>
> --- Questions ---
>
> Both of the above experiences and questions go back to understanding the
> three laws of TDD and step size. As I'm entirely self taught, I'd like to
> know your thoughts.
>
> Do you strictly follow the three laws of TDD as literally written?
> What step size do you typically have when going back and forth between
> tests and code?
> How do you decide the appropriate step size?
> When writing a test, do you define a method or constructor with all its
> expected parameters?
> Do you consider, "an incomplete but green test is at best misleading and
> at worst wrong"?
>
> Thank you for the feedback.
>
> --Kaleb
>
>
> 
>