Archive

Posts Tagged ‘TDD’

The RGR Prayer

February 26, 2015 5 comments

I recently watched an agile training video in which the sage on the stage made the audience repeat after him three times, the RGR prayer: “red, green, refactor“.

As I watched, I wondered how many of the repeaters were thinking “uh, this may be bullshit” while they uttered those three golden words from the sacred book of agile. It reminded me of those religious ceremonies my parents forced me to attend where the impeccably dressed, pew-dwelling flock, mindlessly stood up and parroted whatever the high priest dictated to them.

RGR

Let’s digress, but please bear with me for a moment and we’ll meet up with the RGR prayer again in short order.

I know it’s not much to go by, but assume that you’re given the following task:

“Given this input, design and build a box that produces this output.”

Your Box

Rising to the challenge, you concoct the following three design candidates upfront (OMG!) so you can trade them off against each other.

ABC

Which design candidate is “better“? The monolith (A), the multi-element network structure (B), or the two element pipeline (B)?

As always, it “depends“. If the functionality required to transform “this input” into “that output” is tiny (e.g. a trivial “Hello World” program) then the monolith is “best” in terms of understandability and latency (time delay from input to output). If the required functionality is large and non-linearly complex, then the multi-component network design is most likely the “best“. Somewhere in between lies the two element pipeline as the “best” design.

Hard core agilista consultants like our RGR priest and those dead set against the “smell” of any formal upfront requirements analysis or design activities would always argue: “all that time you spent upfront drawing pretty pictures and concocting design candidates was wasted labor. If you simply used that precious time to apply the RGR prayer through TDD (Test Driven Development), the best design, which you can’t ever know a-priori, would have emerged – IT ALWAYS DOES.”

TDD Improves

See, I followed through on my commitment to weave our way back to the RGR prayer.

Categories: technical Tags: ,

Beware Of Micro-Fragmentation

January 18, 2015 1 comment

While watching Neal Ford’s terrific “Agile Engineering Practices” video series, I paid close attention to the segment in which he interactively demonstrated the technique of Test Driven Development (TDD). At the end of his well-orchestrated example, which was to design/write/test code that determines whether an integer is a perfect number, Mr. Ford presented the following side-by-side summary comparison of the resulting “traditional” Code Before Test (CBT) and “agile” TDD designs.

Ford TDD Example

As expected from any good agilista soldier, Mr. Ford extolled the virtues of the TDD derived design on the right without mentioning any downside whatsoever. However, right off the bat, I judged (and still do) that the compact, cohesive, code-all-in-close-proximity CBT design on the left is more readable, understandable, and maintainable than the micro-fragmented TDD design on the right. If the atomic code in the CBT isPerfect() method on the left ended up spanning much more space than shown, I may have ended up agreeing with Neal’s final assessment that the TDD result is better – in this specific case. But I (and hopefully you) don’t subscribe to this, typical-of-agile-zealots, 100% true, assertion:

TDD Improves

The downside of TDD (to which there are, amazingly, none according to those who dwell in the TDD cathedral), is eloquently put by Jim Coplien in his classic “Why Most Unit Testing Is Waste” paper:

If you find your testers (or yourself) splitting up functions to support the testing process, you’re destroying your system architecture and code comprehension along with it. Test at a coarser level of granularity. – Jim Coplien

As best I can, I try to avoid being an absolutist. Thus, if you think the TDD generated code structure on the right is “better” than the integrated code on the left, then kudos to you, my friend. The only point I’m trying to make, especially to younger and less experienced software engineers, is this: every decision is a tradeoff. When it comes to your intimate, personal, work habits, don’t blindly accept what any expert says at face value – especially “agile” experts.

TDD DDT

Blind Copy

January 5, 2015 Leave a comment

I just finished watching Simon Brown’s brilliant talk: “Software Architecture vs Code”.

I thought the segment he presented on levels of testing was really, really good. Simon had the nerve to question the dogma of TDD and the dubious value of unit testing the hell out of your code (90%, 100% coverage anyone?). He cited the controversial writings of Jim Coplien and David Heinemeier-Hansson that poke some holes in those revered, extreme practices:

Cope and DHH

Like Cope and DHH, Simon does not advise shit-canning ALL unit testing. He simply suggests rethinking the test pyramid and how one allocates resources to the various levels of testing:

Test Pyramid

Instead of mandating 90 or 100 percent unit test coverage in order to create a high level of (false) confidence in your code base, perhaps you and your org should consider the potential silliness of the current obsession with TDD and writing huge unit test suites. Maybe you’d save some money and deliver your product faster. But then again, maybe not.

Blind Copy

Categories: technical Tags: , , ,

Myopia And Hyperopia

Assume that we’ve just finished designing, testing, and integrating the system below:

SoS

Now let’s zoom in on the “as-built“, four class, design of SS2 (SubSystem 2). Assume its physical source tree is laid out as follows:

source tree

Given this design data after the fact, some questions may come to mind: How did the four class design cluster come into being? Did the design emerge first, the production code second, and the unit tests come third in a neat and orderly fashion?  Did the tests come first and the design emerge second? Who gives a sh-t what the order and linearity of creation was, and perhaps more importantly, why would someone give a sh-t?

It seems that the TDD community thinks the way a design manifests is of supreme concern. You see, some hard core TDD zealots think that designing and writing the test code first ala a strict “red-green-refactor” personal process guarantees a “better” final design than any other way. And damn it, if you don’t do TDD, you’re a second class citizen.

BD00 thinks that as long as refactoring feedback loops exist between the designing-coding-testing efforts, it really doesn’t freakin’ matter which is the cart and which is the horse, nor even which comes first. TDD starts with a local, myopic view and iteratively moves upward towards global abstraction. DDT (Design Driven Test) starts with a global, hyperopic view and iteratively moves downward towards local implementation. A chaotic, hybrid, myopia-hyperopia approach starts anywhere and jumps back and forth as the developer sees fit. It’s all about the freedom to choose what’s best in the moment for you.

DDT TDD

Notice that TDD says nothing about how the purely abstract, higher level, three-subsystem cluster (especially the inter-subsystem interfaces) that comprise the “finished” system should come into being. Perhaps the TDD community can (should?) concoct and mandate a new and hip personal process to cover software system level design?

An Intimate Act Of Communication

May 19, 2014 2 comments

Take a look at these three state machine models for intimately developing a chunk of functionally cohesive software:

TDD DDT

The key distinguishing feature of the two machines on the right from the pure TDD machine on the left is that some level of design is the initial driver, informer, of the subsequent coding/testing development process. Note that all three methods contain feedback transitions triggered by “learning as we go” events.

In my understanding of TDD, no time is “wasted” upfront thinking about, or capturing, design data at any level of granularity. The pithy mandate from the TDD gods is “red-green-refactor” or die. The design bubbles up solely from the testing/coding cycle in a zen-like flow of intelligence.

Personally, I work in accordance with the DDT model. How about you? For newbies who were solely taught, and only know how to do, TDD, have you ever thought about trying the “traditional” DDT way?

BTW, I learned, tried, and then rejected, TDD as my personal process from “Unit Test Frameworks“. Except for the parts on TDD, it’s a terrific book for learning about unit testing.

Since “design” is an intimately personal process, whatever works for you is fine by BD00. But just because it’s “newer” and has a lot of rabid fan-boys promoting it (including some big and famous consultants), don’t auto-assume TDD is da bomb.

Design is an intimate act of communication between the creator and the created. – Unknown

Gatling Gun

Starting from the bottom and progressing upward, check out this rat-tat-tat gatling gun salvo of irrationality emitted by BD00 recently, uh yesterday, on Twitter:

 

Gatling

Sheesh, tis’ a good thing nobody pays attention to what BD00 sez; especially the profit-seeking proponents of the “best practice” du jour.

Categories: miscellaneous Tags: ,

Challenging the Priesthood

May 7, 2014 10 comments

It seems to have taken awhile, but people are finally speaking out strongly against the papal infallibility of the TDD high priesthood. Michał Bartyzel, Andrew Binstock, and Jim Coplien (who actually has been speaking out against it for years) are a few of these blasphemous heretics.

Any of the “driven” techniques can work, but to insinuate that they are the “only way(s)” to build superior products is arrogant, hubristic, and plain stupid. In mentally challenging, knowledge-intensive work, people have, and always will have, different ways of creating beautiful products.

When I speak with adherents of test-driven development (TDD) in particular, there is a seeming non-comprehension that truly excellent, reliable code was ever developed prior to the advent of this one practice. I sense their view that the long history of code that put man on the moon, ran phone switches, airline reservation systems, and electric grids was all the result of luck or unique talents, rather than a function of careful discipline and development rigor. – Andrew Binstock

“…these promises were not supported by unambiguous and verifiable data in early years of TDD. The enthusiastic reaction to TDD came first and then some (selective?) measurements were made to verify its promises. – Michał Bartyzel

“If you find your testers (or yourself) splitting up functions to support the testing process, you’re destroying your system architecture and code comprehension along with it. Test at a coarser level of granularity.” – Jim Coplien

Personally, I start sketching out quite a bit of a design upfront (OMG!!!!!) in bent” UML (OMG, OMG!!!!!) prior to writing a single line of code. I then start writing the code and I subsequently write/run some selective unit tests on that code. In summary, I dynamically build/test the code base toward the coarse, “upfront” design as I go. Of course, according to the high priests of TDD, I’m unprofessional and I obviously produce inferior designs and bug-ridden, unmaintainable code. Gosh, it sux to be me.

Salvation

For more details on how I develop software, check out this four year old post: PAYGO II. And no, I’m not promoting it as  better than your personal process or, gasp, the unassailable holy grail of software development… TDD! No books, magazine articles, conference talks, or two-day certification courses are planned. It’s simply better for me, and perhaps only me.

%d bloggers like this: