Re: First class developer: who ?
On Sun, 14 Mar 2010, Patricia Shanahan wrote:
BGB / cr88192 wrote:
...
often, if there is no good way to test or use a piece of code, well then
this is a bit of an issue...
The conditions that trigger a piece of code in operation may be
difficult to cause in system test,
If it's difficult to cause with a system test, then it's possible, and
that's something that can and should be tested - corner cases are
something you should pay particular attention to, because they usually
won't be caught by informal testing.
If it's impossible to cause with a system test, then why is the code
there?
At work, for various bad reasons, we write only system tests. We do
test-first development, and have almost all the system's code covered by
tests. The only bits that aren't covered are where deficiencies in our
test tools stop us getting at them (eg something on a web interface that
involves very complex javascript that's out of our control, where our
ancient version of HtmlUnit can't handle it). I've yet to write anything
that could not in principle be tested by a system test.
Hence, i do wonder if the orthodoxy that unit tests should be the
foundation of developer testing is right. Their advantage is that when
they fail, they give you a much more precise indication of what's gone
wrong. Their disadvantage is that they don't test interactions between
components (or if they do, they become less unitish, they lose some of the
aforementioned precision), and don't provide the lovely whole-system
reassurance that system tests do, the kind of reassurance that means you
can point your product owner at the Hudson chart and say "look, it all
works!".
I appreciate that TDD orthodoxy says that you should also have functional
system-level tests, to provide that kind of verification. But if you have
those at a comprehensive level of density, why do you also need unit
tests?
but the code itself can be unit tested.
I find it helps to write unit tests and detailed specification, usually
Javadoc comments, in parallel. Sometimes a small change in an interface
that does not harm code I'm going to write using it makes the
implementing classes much easier to test.
I think you're saying you write the tests and the spec at the same time
rather than writing the spec first. I come from the opposite direction -
we only write javadoc on interfaces we're exposing to some third party (eg
in a library we're releasing), and then we only write it right before
releasing it. It's very much a case of the spec being a description of
what we've built, rather than a true specification. We adhere to Extreme
orthodoxy in considering the tests the true spec. Er, even though we write
system rather than unit tests.
Actually, in the case i'm thinking of, the library has no direct tests.
Rather, we have a simple application built on top of the library,
essentially the thinnest possible wrapper round its functionality, and
then we have system tests for that application. So the application is sort
of simultaneously a test framework, a reference application and a living
specification. This may seem like a wildly marginal way to do testing and
documentation, and it probably is, but it seems to work okay. It really
forces us to test the library in practical, functional terms - it makes us
expose functionality in a way that actually makes sense to an application
developer.
Anyway, what i am working my way round to is an observation that for us,
writing documentation earlier, as you do, would probably be a good thing.
Back when i was a scientist, i would toil away in the stygian darkness of
the microscope room for months on end, doing what i thought was solid
work, and then invariably find that when i sat down to prepare a
presentation, poster, paper, thesis chapter, etc, that my data was shot
full of holes - controls i didn't do, possibilities i didn't investigate,
variables i didn't measure, related work i hadn't taken into account, and
so on. The act of bringing the data together in writing forced out all the
flaws, and gave me a stack of (mostly small) things to go back to the
bench and do.
Recently, as i've been javadocking some interfaces, i've found something
similar - we have something that works, and that makes sense to us
(including when writing the reference app), but when you have to explain,
say, what that parameter does in an @param line, you suddenly realise that
it's really being used to mean two quite different things, and should
really be two parameters, or that it should be a different type, on
another method, a field, or whatever. The act of explaining it to someone
- even the imaginary audience of the javadoc - makes you think about it in
a deeper way, or a different way at least. A way where you have to explain
what it does without being able to talk about how it does it. Interface
not implementation, with a bit of the Cardboard Programmer effect thrown
in.
So, er, yeah. There you have it. Rock on Dr S.
tom
--
Death to all vowels! The Ministry of Truth says vowels are plus
undoublethink. Vowels are a Eurasian plot! Big Brother, leading us proles
to victory!