Wonderful article. This could provide a blueprint for
lowering barriers to entry and easing the burden on
organizations and leagues of jaded and weary developers.
I'm happy more people are getting on-board with this
mock overloading. We discussed that exact same point at
the first altnetuk conf :)
I use Unit tests to drive out my design and use Rhino
Mocks.
We use contractors a lot and I get a lot of resistance
to writing unit tests.
I generally have to retrofit them after they have left.
I find it frustrating but I do see their argument. They
are there to as they see it "get the job done".
Unit testing in my opinion is just not the norm. and
until we lower the bar then it just will not be
accepted.
I've recently moved to AAA with Rhino.Mocks but I have
found more resistance with the lamda style Stub than
with PlayBack and Record.
I much prefer stubbing via AAA and very rarely use
expectations now.
The syntax is perhaps a bit cryptic for people who might
not have used lamdas or for that matter .NET 3.5 before.
Jeremy:
"To suggest that testability is impossible in your
solution is to admit that maintainability is also
impossible in your solution."
That is precisely the kind of purist view that drives me
crazy.
maintainable!= extensible
and, yest. SOLID has been around for a long time, and
people have not embraced it for a myriad of reasons.
first of which is the high learning curve.
I agree that testability isn't an end goal, but many in
the industry view it as such (you equate it with good
design so achieving ones means the other). I don't view
it as a bar to anything. it is simply a bi product of
following SOLID rules. not the other way around.
Do you need to design for testability in ruby? or
SmallTalk?
can you still get a good design in those languages?
First of all I found your post a very interesting / good
read.
The reason for some good practices and principles not
becoming main stream because of the learning curve, that
doesn’t sound right to me. How can you expect
improvement if you are not willing to invest? If you
know that doing something this and that way is the
proper way of doing it, why than not do it this and that
way, even if it means a personal investment / learning.
That is like saying that you would stick with technology
A because that is what you know and feel comfortable
with, not because it is the best answer to the problem.
There are so many people that just don’t have an
interest in learning new things; I think that is the
reason for things not becoming more accepted. I think
that for those types of people it doesn’t matter how low
the learning curve is, they won’t do it anyway, only if
it is enforced upon them.
The example of the external consultants not willing to
make proper unit tests because they are there to get the
job done, weird, if you specify that the job includes
proper unit testing coverage than that is what they
should do. Anybody can make software, writing good
software that is maintainable and extendable that
requires you to think, using principles like SOLID make
you think about your design. Usually those projects that
have good design and are maintainable and extendable are
also very testable. I am surely not saying that I know
exactly how to do these things, but I am saying that I
am learning and improving.
Don’t you think that principles like SOLID and others
help improve the design to become more maintainable and
extendable? Don't you agree that a design that is
maintainable usually also is extendable, because
maintaining an application very often means extending
it, or at the very least change certain behavior of it?
–Mark
I am simply finding it really difficult to find
developers (full time or contract) with any relevant tdd
experience.
Either people do not see the benefit or are unwillining
To put the effort into learning it.
I simply cannot legislate the time in terms of money in
getting contractors up
To speed with unit testing techniques like mocking.
Jeremy:
I didn't mean to call names. Sorry. But I find that
putting finalistic labels on things to be a bit arrogant
(which I seem to be as well some times)
When you said
"To suggest that testability is impossible in your
solution is to admit that maintainability is also
impossible in your solution."
that is why I said you equate the two. You may not have
meant it but it sure sounds like to you they are equal.
Ruby and smalltalk are "testable by default" because you
can replace anything at runtime without needing to have
a "replceable" design.
So the design and the testability aspects don't matter,
depending on the technology.
;
The fact that we are treating testability as a first
class citizen in .NET irks me because there are
solutions to that.
oh and Jeremy:
sure, people have not problem *hearing* about solid, and
understanding it's always been there, but if everyone
were already practicing it, the issues we have today
with testability wouldn't exist as much as they do.
not would learning how to make code testable, or all the
IoC principles be so hard for so many people.
Nice read. And I agree on the KISS, though I wonder, are
you just swapping out some labels, but still pushing the
same tech? How does that solve the learning curve?
The biggest obstacle to learning is Yet Another Domain
Specific Language.
Personally I've thrown mocks out the window, I'm getting
better mileage out of tailoring stubs with embedded
assertions.
Roy, congratulations on starting walking in right
direction (simplification).
But you need to go much, much further.
Whole mocking concept could be safely thrown away for
most of the real projects.
Only the simplest and the most efficient auto-testing
methods deserve mass use.
It's important to admit, that for most of software
projects even 30% of auto-test coverage is "good enough"
coverage.
I think this is a great debate. For too long now
everyone in the ALT.NET community has been stating and
reiterating that TDD, BDD, whatever is just fantastic
and we should all do it and anybody who is not, is
obviously doing something wrong.
I do practice TDD for the design merits but it has taken
me a long time to get up to speed with it. I made
countless (and still do) mistakes at the start and the
learning curve has been steep.
My first experience was that developers started with the
best intentions but our initial tests were
un-maintainable as they were affectively integration
tests.
Using a mocking framework helped to write maintainable,
fast running tests and I love the test first paradigm.
But I often wonder if I have actually got the return
that my outlay warrants.
I use NHibernate and I rarely mock out ISession,
ISessionFactory or ICriteria.
If I was after high code coverage, I would have to mock
out these for no other reason than to get high code
coverage. I use layering to hide this code behind its
own abstracted dependency. What if I have a WCF or asmx
proxy, then should I stub out each generated method? No.
A side effect of test first is you get unit tests to
test your logic. If you are expecting unit tests to
catch bugs and keep QA to a minimum then you are
approaching the methodology wrong.
I also have a problem with new people coming onto the
project who are inexperienced with TDD. They naturally
write unmaintainable bad tests.
TDD is a massive outlay and we should and I am
questioning its return.
Roy,
Great article. Just this last week I've been trying to
bring some other devs onto a project I've been working
on. There's heavy use of mocking, DI, and IoC and I get
the sense the new guys feel like they're drinking from
the fire hose as you put it.
I train co-op students all the time and they love TDD
and get the concept quickly. With continuous integration
in place with many developers, the tests that fail will
tell the committer that he/she broke some code. Also,
writing the tests first makes you think of a classes
responsibility (SRP) and behaviour.
Fakeing? WTF is that? Mock stays.
Less interaction testing, more state based testing ->
have you tried Mockito for Java? (www.mockito.org)
Interesting but annoying that you didn't run a spelling
check before posting.
Nice article, and judging from the comments you have
created a discussion.
I teach objects and TDD as part of my job (team
lead/coach) and I wonder what some companies and schools
teach when I have to tell someone what the difference is
between passing by reference and passing by value. We
can’t work for the lowest common denominator of the
industry, we must drag the industry kicking and
screaming up a notch.
Now, I also, I am afraid to say, dumb things down. I
never use scary words like “mock” or “encapsulation” or,
God forbid, “polymorphism” Well, not in the beginning at
least. Because, as you said, you don’t want to put
people off. But, I’ll be damned if it’s not my intention
to pull everyone, and the companies I work with, up to
higher levels. And that next level will include
discovering interfaces a la TDD and mocking. So, I think
we need to start slowly, for sure, but we also need to
keep teaching, keep writing, and keep learning. I would
be careful about diluting what developers need to do,
know and learn - i.e. we should not enable bad behavior.