Afficher un message
Vieux 30/06/2008, 13h21   #7
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: c++ class design: where to put debug purpose utility class?

James Kanze wrote:
> On Jun 30, 9:35 am, Ian Collins <ian-n...@hotmail.com> wrote:
>> James Kanze wrote:

>
>>> Which, of course, isn't true, because until you have at
>>> least some idea as to what the class is to do, you can't
>>> write the tests. You start by determining what the class is
>>> to do (in most cases, that means some high level design).
>>> You don't start by just typing in code, whether it is a test
>>> or anything else.

>
>> Here's where we differ. The above assumes you have a design
>> which defines your classes.

>
> The above assumes that you have at least some idea as to what
> the class (or any other bit of code) will do before you start to
> write it. I think we both also more or less agree that unless
> it is written down, you don't really have any idea.


True.

> Where we
> disagree is that you seem to consider the unit tests a form of
> being "written down", whereas I consider them code, just like
> the rest---I don't know how to write a unit test until I have
> some idea what is to be tested, i.e. what the unit shoud do.
> And IMHO, I don't know that until it is written down.
>

Not really, the written down will be some form of requirement, be that a
clause in a traditional requirements specification, or an XP style user
story. Given a requirement, my view of TDD is that it's another form of
functional decomposition. You know what your end gaol is, you know the
steps to take you there and you follow them. The smaller those steps,
the better.

> For small applications, it's not unusual that the "written down"
> part ends up as comments in the header (in Doxygen format, for
> example). For larger applications, there'll almost always be
> some sort of high level functional decomposition before I can
> even think about "units", and that has to be written down.
>

With TDD, the names of the tests replace the comments. The tests are
the detailed design and the examples of how to use the code. The
acceptance tests are the higher level requirements. If these are
written correctly, either by the customer or in a form they can
understand, the paper requirements can be discarded. I have only had
one client bold enough to do this!

>> Often with TDD, you test and to code to a more abstract
>> requirement and the design (classes) follow the tests.

>
> Traditionally, that has been called prototyping, not testing:-).
> It's almost essential for anything which interacts with a human.
> It's of almost no use if you're implementing a protocol defined
> by a standard.
>
> Traditionally, you're supposed to throw the prototype out, once
> you've learned from it. A rule that is often ignored (which may
> account for the poor quality of some of the software out there).
> But I suppose that you could call throwing it out simply an
> intensive refactorizing, and the prototyping "testing".
> Especially since the "throwing out" usually doesn't consist of
> actually deleting the source code from the disk, and that the
> rewrite often involves some copy/pasting:-).
>

Refactoring is part of the process of improving the design. I think you
would enjoy "Refactoring to Patterns" by Joshua Kerievsky.

>> Sometimes there's an agreed interface, or a base class that is
>> being extended, but often the tests are testing an action for
>> a reaction.

>
> In which case, you probably have some idea as to what the action
> or reaction should be. And perhaps even some constraints on it.
> I'd write those out, in plain French (or whatever language I
> happen to be using on the project). Maybe as comments in the
> code; maybe even as comments in the unit tests. But in a human
> language, at a higher level of abstraction than C++.
>

While I'd write them out as plain C++ or what ever language I happen to
be using on the project! In a way, they are in plain English, so long
as the tests are short and have meaningful names. That's why I always
forward declare the tests at the top of a file, even if the language
(such as PHP) does not require this. If the test's name can't express
its intent, the scope of the test is too broad.

>
>> I don't think anyone is suggesting that. What is being
>> suggested is a different way of thinking.

>
> Well, I've said from the start that you can't write any code
> without first thinking. Including a unit test. But I'd like to
> insist on the fact that if you haven't written it out in your
> native language, you haven't really thought it out.
>

To varying degrees of 'it'!

I like to class the design and naming of the tests as an important part
of this thinking process. The name (meaningful) and size (small) of the
tests is extremely important. All to often I see novices write a
monolithic test function with scores of asserts which tell the reader
very little. Break that up into a sequence of well named single
condition tests and the reader can see exactly what the code is supposed
to do. Many small, well named tests is a clear indicator that some who
claims to be doing TDD is. He or she can then tell what they have
broken when they make a change without having to step through the test.

--
Ian Collins.
  Réponse avec citation
 
Page generated in 0,07540 seconds with 9 queries