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 > > > >