Unit Testing decoupled from TDD as well== Adoption

The discussion on the future of unit testing for the masses has shifted from the standard “if they are too stupid to learn it, we don’t want them” to “TDD without good design will make really bad tests”. and this is a good thing. it’s a good thing because it secretly implies that if you could write Good Unit Tests, regardless of design, then teaching design as a separate thing should not pose a problem.

Discussion so far:

But first, let’s make one thing clear:

TDD is NOT Unit Testing.

My previous post was not “TDD decoupled from design==adoption”, it was “Unit testing decoupled from design == adoption

TDD is (technically) about when you write the unit test.

You can still write crappy tests in TDD mode. With good design. Unit Tests deserve a good book about them without TDD in it because the current books about TDD suffer from lack of SRP.

On the other hand you can still write good tests, without TDD. The design might make them a little longer, but if you learn to write unit tests well, this should not pose a problem.

Learn Good Unit Testing regardless of TDD and Design

people can start learning unit testing before learning TDD. they learn the silly stuff (the kind udi looks down upon) in an hour, and then they get to the hard stuff : making the tests readable, maintainable and trust worthy.  these are separate properties that can be learned to be done regardless of design, since test naming convention, refactoring and correctness can be learned in separate.

The only reason it’s really hard to teach in separate today is because as those devs get to test real world code they have to start dealing with real world dependencies and that it the barrier that usually stops most people. having “intermediate” frameworks in place such as JMockit and Typemock Isolator can help in that regard, keeping people focused on the task at hand and deferring the need to learn other types of design for a time that is better. The idea is to let the developer choose when to learn which technique:

  • Learn how to write good unit tests (book)
  • Learn Good Design technique (give me a link to a good starter book!)
  • Learn Test Driven Development (book)

I want a developer to grok each one of those things to a very deep level, but today’s “market” wants them to learn it all in one go. Since each one is its own little art form, are you really surprised to learn that most of the mass population is not there yet?

If people think that the only way to write good unit tests that are not worthless is by doing them TDD style with SOLID design, they are showing several things to me:

  • they don’t get what “good” unit testing is
  • They don’t “get” what value good tests have outside the context of TDD
  • they guide a community who reads them down a path of “all or nothing”. which for most people begets “nothing”.

Field notes:

Udi writes:

“If logic is duplicated, if the code is tightly coupled, if there is no separation of concerns, the unit tests will be useless - even if they “test” the class in isolation.”

That is wrong in many levels. Let’s start with the fact that a unit test can have a specific value in testing a specific class in isolation, even if the bugs in that class are duplicated on other classes. If Udi does not agree on that, I don’t know what else to say about that. I wish  that what he meant was that all these problems were repeating in the tests, since this is usually why people fail when they start out unit testing: they write crappy tests with bugs, code duplication and lack of isolation (this can all be learned). But he’s not.  It feels like a “purist” view that does not reflect the real world. It must be nice living in an echo chamber!

Let’s see udi contradict himself in the same post:

“Managers shouldn’t necessarily sacrifice their projects on this altar of learning. Organizations need to find ways for developers to safely practice these techniques as a part of developing their “human resources”. First of all, this needs to be communicated to everyone - that the organization understands the importance of these techniques, the desires of developers to adopt them, and the projects that need to be delivered.”

“…It’s a gradual process.”

That’s the problem Udi. It’s not possible to do it gradually today, because people keep saying that you can’t do things in little chunks. you have to learn it all together. If we were to help developers learn what good unit testing means they could much more easily learn that stuff, and then learn the other stuff.

Casey writes:

“It is not a technical challenge to write a unit test, any half trained monkey could do it. A few attributes, a couple of classes, a few new() statements, and a few Assert statements. We don't need magic mocking frameworks, we don't need any mocking frameworks for 90% of our tests, we don't need application of 12 GoF principles before we can write a test, honestly.

Testing and writing automated tests is hard because it requires a strong understanding of the user stories that sit behind your code and project, because it requires you to think as a user and not as a developer, and because it requires you to be able to think of multiple conflicting axioms, test cases and class interactions, and how to cover the weaknesses of each individual test with other complementary tests.”

Casey preached about what he sees as the “end game” for unit testing, TDD and Design. where everything is in one great ball of goodness. Or did he?

Let’s separate these points into better chunks:

Design related stuff:

  • to think of multiple… class interactions

Good Test related stuff:

  • Understanding of the user stories
  • Think as a user not a developer
  • think of multiple conflicting axioms (..?) test cases..
  • how to cover the weaknesses of each individual test with other complementation tests.

TDD related stuff

  • none

So, what I gather from casey’s words is that you want your tests to be :

  • testing the right thing
  • be readable and show intent
  • have good coverage
  • test or be aware of class interactions (the design related stuff)

 

except the last point which is where most of today’s mock frameworks force you to redesign, there is nothing here you can’t learn separated from TDD and SOLID techniques. the interaction stuff is where those other isolation frameworks I mentioned come into place.

We need to decouple Good Unit Testing from TDD and SOLID. And it seems that not only “noobs”, as a stupid idiot commented thoughtfully on my last post, can benefit from learning this distinction.

Published Wednesday, October 01, 2008 9:27 AM by RoyOsherove

Comments

Wednesday, October 01, 2008 10:10 AM by Casey

# re: Unit Testing decoupled from TDD as well== Adoption

I think we must be agreeing to disagree here, or we are agreeing to agree and missing it entirely in the translation.

My post was to highlight that there is an art to writing good automated tests that no tool will help you with - I deliberately didn't mention TDD as that is another art in it's own right.

If anything - tools are the problem here - a bit more focus on some really basic principles would pay off long before a few integration tests on badly written code.

When you can write a clean set of unit tests that have real value, you won't need to be writing code that is tightly coupled, nor would you want to ... or ....

Honestly Roy, would you write new code that is tightly coupled knowing you can fall back on tooling, or would you write it by nature in a loosely coupled way?  To me both have the same up front effort, the loosely coupled way pays large dividends later on (like today when we had to consider moving our application search engine to another server, which will be nearly trivial due toit all being loosely coupled already)

Wednesday, October 01, 2008 11:22 AM by AndrewSeven

# re: Unit Testing decoupled from TDD as well== Adoption

I think that you've found the crux of it: a path of “all or nothing”. which for most people begets “nothing”.

Wednesday, October 01, 2008 11:22 AM by Mark Needham

# re: Unit Testing decoupled from TDD as well== Adoption

I like Rebecca Wirfs Brock's 'Object Design' as a book for good object oriented design -> www.amazon.co.uk/.../ref=sr_1_2

Wednesday, October 01, 2008 11:26 AM by Udi Dahan

# re: Unit Testing decoupled from TDD as well== Adoption

Roy,

You're absolutely right. I'm all with you on the teaching aspects. Really.

Many managers, though, couldn't give a rat's ass. And, from the project delivery perspective, they're right. They're concerned about the cost and value of these techniques in the short term.

In order to get adoption up, we need to also address the broader organizational issues.

My main concern about much of the conversation going on in the blogosphere was that it was without organizational context - as if we could really drive adoption without addressing that.

If there is a death-march project with a crappy code base, it probably isn't the best place for developers to start learning / practicing unit testing. I'm fairly sure you'd agree with that. Developers, or consultants, trying to institute unit testing there will be harder pressed to show the value these tests provide the project. Management may see these tests as "useless", possibly discounting the entire practice.

Understanding the criteria by which management assesses these techniques is critical, IMO, to driving their adoption.

Wednesday, October 01, 2008 11:53 AM by Jacob

# re: Unit Testing decoupled from TDD as well== Adoption

Oh man. I hope you're asbestos undies are fully deployed.

Wednesday, October 01, 2008 12:23 PM by Troy DeMonbreun

# re: Unit Testing decoupled from TDD as well== Adoption

One can tell by the vehement responses of many people against this idea that the idea strikes them on some sort of emotional level.

I'm really not sure what the fear is that is causing a reaction that seems out of proportion to the gvien the subject matter.  Sure, I don't want to have to come behind noobs and clean up their code, but why all the emotion?

It's very surprising to see the vehement and sometimes caustic responses to what, in a nutshell, is the idea of breaking things into more granular pieces.  Sure, it's not optimal, but to imply that one who learns to ride a bicycle with training wheels will be unlikely to then learn how to ride a motorcycle seems a bit paranoid.

Risking teaching noobs unit testing without a good understanding of OOD techniques such as SOLID, etc. is not going to place us in a worse situation than we have now where the noobs aren't even creating the first unit test.

Wednesday, October 01, 2008 6:39 PM by Halstein Tonheim

# re: Unit Testing decoupled from TDD as well== Adoption

I agree, Roy!

There has been too much puritanism around the subject of unit testing. Crappy code with tests is better than nothing. If you are going to change the way a team works, making them write tests, without any heavy introduction to OO design or TDD-or-nothing, would be the best entrance to the path leading to better things in my opinion.

If you have code with good test coverage that tests that the behaviour and results are correct you have a solid base for slowly introducing all the difficult OO concepts of loose coupling, high cohesion, open-close etc that we love to throw out there just to see people fade off to their happy place. I think this betters the chance of people learning good design patterns as a way to improve the APPLICATION for clarity, extensibility and reuse rather than learn design only as a means to write testable code. What is a testable design anyway? Making all methods public?

Good design and unit tests are both important. BUT we should start with one step at a time. Let the teams see small improvements in their work instead of an impossible wall of you-have-to-do-all-these-things-perfectly-or-you-won't-be-as-cool-as-the-ones-who-get-it...

Wednesday, October 01, 2008 9:26 PM by BlogCoward

# On TDD

On TDD

# Reflective Perspective - Chris Alcock » The Morning Brew #192

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #192

Thursday, October 02, 2008 4:00 AM by 2008 October 02 - Links for today « My (almost) Daily Links

# 2008 October 02 - Links for today « My (almost) Daily Links

Pingback from  2008 October 02 - Links for today « My (almost) Daily Links

Thursday, October 02, 2008 8:48 AM by Dew Drop - October 2, 2008 | Alvin Ashcraft's Morning Dew

# Dew Drop - October 2, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - October 2, 2008 | Alvin Ashcraft's Morning Dew

Thursday, October 02, 2008 12:35 PM by dotnetchap

# re: Unit Testing decoupled from TDD as well== Adoption

Thank you for this post. It is great have an expert post to point people towards; so far this was my favorite:

www.mtelligent.com/.../the-cargo-cult-of-test-driven-development.html

For the last five years in my Nunit/ CI presentations I have been trying to convince people to ignore techniques self-appointed 'development Gods' insist on, especially TDD. Too many developers new to Automated Developer Testing start off on a pure TDD path, predictably get frustrated and then give up on Automated Dev Testing forever.

My advice to beginners is to only write tests that obviously have much more value than the time it takes to write the test. As they become more experienced they can look at higher amounts of coverage and eventually maybe even use TDD.

Thursday, October 02, 2008 12:36 PM by dotnetchap

# re: Unit Testing decoupled from TDD as well== Adoption

Thank you for this post. It is great have an expert post to point people towards; so far this was my favorite:

www.mtelligent.com/.../the-cargo-cult-of-test-driven-development.html

For the last five years in my Nunit/ CI presentations I have been trying to convince people to ignore techniques self-appointed 'development Gods' insist on, especially TDD. Too many developers new to Automated Developer Testing start off on a pure TDD path, predictably get frustrated and then give up on Automated Dev Testing forever.

My advice to beginners is to only write tests that obviously have much more value than the time it takes to write the test. As they become more experienced they can look at higher amounts of coverage and eventually maybe even use TDD.

Thursday, October 02, 2008 3:00 PM by Candi Suriano

# re: Unit Testing decoupled from TDD as well== Adoption

I've been reading this discussion with a lot of interest. I'm someone who would love to do unit testing but the barrier to entry is much too high. 90% of the code I write interacts with outside resources (database, active directory, files, etc.) I'm told you can't unit test that - those are integration tests.

When I look for information or examples on unit testing, I either have to buy into all of the methodology (TDD, SOLID, etc.)  or I'm told that what I need to test isn't unit testable.

I would love to see a good example of how I could write unit tests for the Active Record pattern. We have 100s of classes that instantiate an object that represents a row in the database with methods to insert, logical delete and update a row. The classes also have a number of shared methods that return a table of rows that match some criteria. How in the heck do I unit test that?  Once we get that data we bind it to a grid. Again, where's the unit test there? It's n-tier. The data comes from sql, via a business tier to the presentation. So if you'd like to make some progress with one company with about 50 developers, show me how to do that, and we'd get 50 people doing unit tests.

I'm tired of seeing unit test examples on how to verify that something calculates price correctly. How do I unit test that my log message made it to the database?

I could even get my management to buy into letting us have time for the learning curve, if I could come up with a plan and some solid examples that our more junior developers can model. But, until I find them, we'll just bumble along without unit tests because what's out there takes too much time to assimilate.

Thursday, October 02, 2008 7:46 PM by John Rusk

# re: Unit Testing decoupled from TDD as well== Adoption

I think we've lost sight of our priorities in the agile movement.  Roy Osherove helps to redress the balance in his recent recent series of posts on unit testing. But my concern isn't just about making the tools approachable. The much bigger issue is...

Friday, October 03, 2008 5:02 PM by AndrewSeven

# re: Unit Testing decoupled from TDD as well== Adoption

I had a little time today, so I downloaded Isolator 5.1.

I've used TDD on previous projects, but on my latest one, there are only UI automation tests.

I looked for something to test in the project and the thing I picked definitely doesn't follow all of SOLID, among other issues, it uses the HttpContext.Current directly.

It took a little time, but I was able to get a test up and running; If I write a few more of these test, I'll be able to refactor the design to something a little more solid.

:D

Friday, October 10, 2008 7:56 PM by Episode 21: Real World Development | Herding Code

# Episode 21: Real World Development | Herding Code

Pingback from  Episode 21: Real World Development | Herding Code

Friday, October 10, 2008 10:47 PM by Community Blogs

# Learning On A Project

There has been a fair amount of activity in the blogsphere to Roy's original post about increasing

# Eli Lopian’s Blog (TypeMock) » Blog Archive » Lowering the friction of Unit testing

Pingback from  Eli Lopian’s Blog (TypeMock)  » Blog Archive   » Lowering the friction of Unit testing