Re: Three Law of TDD - to strictly follow, or not?
"Tim Ottinger [email protected] [testdrivendevelopment]" <[email protected]> Tue, 26 Aug 2014 10:51:43 -0500
| Newsgroups | gmane.comp.programming.test-driven-development |
|---|---|
| Message-ID | <CAN2NSt=au8wkQsBLObqJ2+W+XW6LCw=DTRROnVfCbfbK0WD_kQ@mail.gmail.com> |
The official rules say to write a test, but only enough of a test to get a failure --- which means "not the whole test." But as to the title question: sometimes you should follow the rules strictly. Other times you might try not. http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd On Tue, Aug 26, 2014 at 10: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 > > > > -- Tim Ottinger, Anzeneer, Industrial Logic ------------------------------------- http://www.industriallogic.com/ http://agileinaflash.com/ http://agileotter.blogspot.com/