Ayende @ Rahien

It's a girl

re: Are you smart enough to do without TDD

Daniel has posted a reply to my post, titling it:  Are you smart enough to do without TDD. I more or less expected to get responses like that, which was why I was hesitant to  post it. Contrary to popular opinion, I don’t really enjoy being controversial.

There are two main points that I object to in his post:

You see, Ayende appears to say that if you're smart enough, you'll just know what code to write, just like that. Ergo, if you don't know, maybe you're not that smart and hence you would need this technique for losers called Test Driven Design/Development.

That is not what I said, please don’t put words in my mouth. What I said was: “The idea behind TDD is to use the tests to drive the design. Well, in this case, I don’t have any design to drive.” Combine this with my concepts & features architecture, where the main tenets is: “A feature creation may not involve any design activity.” and it should be clear why TDD simply doesn’t work for my scenario.

And his attack on Rhino Mocks:

Moq vs Rhino Mocks: he [Ayende, it seems] read the (useless IMO) literature on mocks vs stubs vs fakes, had apparently a clear idea of what to do, and came up with Rhino's awkward, user unfriendly and hard to learn API with a myriad of concepts and options, and a record-replay-driven API (ok, I'm sure it was not his original idea, but certainly it's his impl.) which two years ago seemed to him to stand at the core of mocking. Nowadays not only he learned what I've been saying all along, that "dynamic, strict, partial and stub... No one cares", but also is planning to remove the record / playback API too.

This is just full of misinformation. Let me see how:

  • Rhino Mocks is 5 years old.
  • Rhino Mocks came out for .NET 1.0.
  • Rhino Mocks actually predate most of the mocks vs. stubs debate.

I keep Rhino Mocks updated as new concepts and syntax options comes. Yes, AAA is easier, but AAA relies on having the syntax options that we have in C# 3.0. Rhino Mocks didn’t start from there, it started a lot earlier, and it is a testament to its flexibility that I was able to adapt it to any change along the way.

Oh, and Rhino Mocks was developed with TDD, fully. Still is, for that matter. So I find it annoying that someone attacks it on this grounds without really understanding how it worked.

Comments

Daniel Cazzulino
09/30/2009 07:14 AM by
Daniel Cazzulino

As I said "...if he had sat down with a blank project, two years ago...", so I fail to see how being 5 years old or coming out for .NET 1.0 has anything to do with what I said.

And if Rhino has 5 years, it does NOT predate the debate. Even Fowler's often cited article on the matter ( martinfowler.com/articles/mocksArentStubs.html) is first dated as 08 Jul 04: First published.

"The main tenet is: “A feature creation may not involve any design activity.”

I stand by my idea that all you've done is invent a fancy name for an interation test and trying to use that as an excuse not to write actual unit tests. I say you still need both. Either one is a risk without the other.

Note that I'm defending unit tests, NOT TDD in this particular case where "feature creation" is not a design activity (i.e. you have a whole infrastructure that allows a business app developer to just implement IRule and that's it). You still need unit tests.

Ayende Rahien
09/30/2009 07:55 AM by
Ayende Rahien

Daniel,

Starting from blank slate would mean having to re-do a LOT of stuff. Things like partial mocks, multi mocks, delegate mocks, etc.

That would be truly stupid thing to do. Adding the AAA merely added, not substracted, and we kept all the power in Rhino Mocks.

Interaction tests? That is most certainly not what I am doing there.

And when using my approach, writing a unit test is stupid, it is actually harder to do than a scenario test, and doesn't tell you much about what is going on

Arnis L.
09/30/2009 08:08 AM by
Arnis L.

Just keep Mocks&Stubs separated. That's the thing i dislike about Moq - there's a bunch of mocks in my tests despite that test is supposed to contain 1 mock only.

P.s. Ignore Daniel.

Nick Aceves
09/30/2009 08:30 AM by
Nick Aceves

"Either one is a risk without the other."

Sometimes risks are worth taking. When TDD gets in the way of design flexibility, you have to weigh your development time vs. time spent fixing bugs in the future. Integration tests are the sweet spot in the middle. You test your entire system as a whole, writing fewer, less-brittle tests, but still catching the biggest bugs. When smaller bugs appear, you write regression tests for them. When you are forced to write code that may be especially bug-prone (complex logic, regular expressions, etc), then you write some lower-level (maybe even unit-level) tests for it.

There's always risk. There's a risk a meteor could come through my ceiling and strike me dead, right this instant. But you don't see me adding armor plating to my roof, because in all practicality I don't need it.

Barry Dahlberg
09/30/2009 08:30 AM by
Barry Dahlberg

We wouldn't read you if you weren't so good at being controversial and relevant at the same time...

Bunter
09/30/2009 09:23 AM by
Bunter

Well, that's what you get if you go against religion. TDD is a lot about "it willspeed you up" and "it will life merry and happy", lot of guys have sold this idea for long, most of them have little to no actual measurements to back up their bidding. Note that I don't contradict those claims, just that like always with any other shining sd-methology, evangelists attack and zombies follow. Remember RUP and UML? Like usual, software engineers are passionate about development strategy and pretty crappy when it comes to tactics and actual, verified measurement of their work. U know, this "i'm an artist" "i'm an engineer" thing depending on the suitable context.

Torkel
09/30/2009 12:08 PM by
Torkel

I find the scenario model of doing testing on a higher level that you have talked about very interesting. Not as a complete substitute for TDD (which is not what I understand you propose) but just as another way of doing BDD like integration testing (or what ever you call it, doesn't matter).

But it would be very nice with complete examples that show the scenario runtime, the application, etc, and how this can be applied to an MVC or WPF application.

Frank Quednau
09/30/2009 12:10 PM by
Frank Quednau

Ayende,

I think Daniel meant to say Integration tests (not interaction). I think your scenarios are of an integrative nature.

It is interesting though that people witness your posts as controversial while you are not even really criticizing any of the current practices, merely adding something new to the plate worth thinking about.

People should consider that a design and process evolution cannot be complete after, what, not even a decade of putting those things (testing, mocking, etc.) into practice. Those things are still evolving and the full story is not known yet. It seems we are just now reaching the stage of craftmansship. If history is anything to go by, we haven't reached the age of Engineering yet in software development (oh dear, what have I said?!).

Hence the correct reaction for now in many areas of software development seems to me: Find your masters, see how they do it, compare and use their methods and draw your conclusions. Thank God many of them are willing to put their experiences onto the web.

Mr_Simple
09/30/2009 01:31 PM by
Mr_Simple

@Nick - Integration tests are the sweet spot in the middle. You test your entire system as a whole, writing fewer, less-brittle tests, but still catching the biggest bugs.

Yeah buddy!

www.idesign.net - C# Coding Standard v2.32 - page (8) - item (14)

Assert every assumption. On average, every fifth line is an assertion.


I load my programs with Assert's. Assert arguments, Assert return values. Gives me warm fuzzies everytime I press F5.

I also log everything with SmartInspect. Client has a problem, send me the log. It makes debugging a complete no-brainer. A complete no-brainer. Almost boring.

Between these and unit test as needed, sleep comes easy, software is stable and runs as expected, and client's are happy.

Rocket science isn't always needed to achieve rocket science results.

Scott White
09/30/2009 01:32 PM by
Scott White

I don't see what his issue is with Rhino Mocks. It supports R&P and AAA.

Dan Finch
09/30/2009 03:53 PM by
Dan Finch

This is why I advocate the Do Exactly What You Have To Do Exactly When You Have To Do It methodology (DEWYHTDEWYHTDI), of which I am a licensed Invincible Grand Master. I will teach it to you for one million dollars.

Kelly Stuard
09/30/2009 04:27 PM by
Kelly Stuard

Ayende: "I don’t really enjoy being controversial"

That's too bad, because I think if you did enjoy it the world would be in for a lot of hurt. Shake up the status quo, and all that.

I think most of the readers here are just happy to hear your thoughts.

Awkward Coder
09/30/2009 07:03 PM by
Awkward Coder

I'm clever enough, but I still do TDD for people who aren't...

Chris Missal
10/01/2009 02:50 AM by
Chris Missal

The fact that we're having arguments...err, discussions about TDD and/or mocking/isolation frameworks makes me smile. I don't care who "wins".

As long as people have their preferred framework and are even using one is good enough for me. We'll figure out all the details later, but the positive note is that there even is a discussion about this.

Former cowboy
10/01/2009 01:31 PM by
Former cowboy

It amazes me how so many programmers have a tendency to learn about some methodology or set of rules and stick to it as if they are the ten commandments. They also feel the need to crusade against those who dare to 'disobey' these rules. I battle this everyday at my company and it is exhausting. Ayende you have fearlessly battled the entire internet and that makes you a freakin hero!

Daniel Cazzulino
10/01/2009 01:43 PM by
Daniel Cazzulino

As Frank corrected, I meant to say Integration test, of course, which is what your scenario tests are in reality.

Ayende:

. redo.. Things like partial mocks, multi mocks, delegate mocks, etc.

Precisely the myriad of concepts people have to learn to use the tool and increasing the learning curve. I'm not saying you should not have reused what you had. I'm saying that the public API could use a severe revamp, what you seem to be doing for 4.0, which is a GREAT thing to do. Backs compat for an OSS project that wants to stay at the edge of programming paradigms and styles, should be low pri. (maintained if possible, provide legacy wrappers if possible, etc.)

Just to reiterate: I'm not opposing to have integration tests. I do believe people may use those as an excuse not to do TDD. And you should not encourage that. It's irresponsible.

Sean
10/01/2009 02:41 PM by
Sean

If it wasn't clear from Daniel's post, it certainly is after his comments here—this is just a spring-board for Rhino Mocks bashing. If you don't like it, fine, don't use it. Don't be crappin' on Ayende for not completely refactoring it to suit you though.

Ayende Rahien
10/01/2009 04:04 PM by
Ayende Rahien

Daniel,

Those aren't concepts, those are features. Features that make using Rhino Mocks possible in complex scenarios.

Backward compact is essential for long term projects. When you have 1000s of tests using Rhino Mocks, you really care about this.

Daniel Cazzulino
10/01/2009 04:55 PM by
Daniel Cazzulino

Sean: it's unfortunate that you end up picking on the one thing that is not the key of my post, but whatever.

Ayende: yeah, it's so important that you're explicitly letting everyone know that Rhino 4.0 will break compat in a big way.

Don't be hypocrite. You know there's a limit to back compat. You know how that ends up by just looking at .NET BCL.

Ayende Rahien
10/01/2009 05:00 PM by
Ayende Rahien

Daniel,

Rhino Mocks has 5 years of backward comparability.

One of the most frequent requests that we got for Rhino Mocks 4.0 is backward compact, and we intend to deliver on that.

Feel free to ignore this for Moq 2.0, see what would be the result.

Sean
10/01/2009 07:24 PM by
Sean

You mean your entire first "proof" and the main content of each of your comments here? As others noted on your blog that "one thing" ended up detracting greatly from the "key" of your post. The comments here only add to that, making it look like the entire point was to bash Rhino Mocks, I assume in favour of Moq. That is indeed unfortunate.

James Gregory
10/20/2009 11:47 AM by
James Gregory

Daniel:

And you should not encourage that. It's irresponsible.

We often disapprove when people blindly follow the patterns and practices that Microsoft lays out for us, but it also applies to everyone else who is passionate to share their opinion. Somebody who follows what Ayende says without first thinking and drawing their own conclusions, deserves everything they get. We are not sheep, and individual developers should not feel they're unable to voice their opinions for fear of misleading people.

Feel free to disagree and debate all you like, that's one of the great things about our industry, but it's not your place to embue responsibility where none is appropriate.

Comments have been closed on this topic.