class design: where to put debug purpose utility class?

Discussion in 'C++' started by 1230987za@gmail.com, Jun 27, 2008.

  1. Guest

    Hi,

    Let's say I have the following class:

    class foo {
    public:
    foo();
    void addItem(int item);

    private:
    int* items;
    };

    I want to write a unit test program to test foo::addItem(), to do that
    the test program needs to know the contents of foo::items.

    So I can add one more public function to class foo:
    int* getItems();

    But suppose in my case, the client code of class foo does not need
    getItems() at all, this function serves only for test in this case.

    So I am considering to have a separate class fooTest and this class is
    a friend class of class foo so that it has an API to retrieve all
    private data of foo.

    I believe this works, but I am wondering if there is better solution.
    Basically my goals are:
    1. I do not want the class to be bloated with a lot of API which only
    serve for test purpose
    2. I want the function class to be independent from test class

    Thanks a lot.
    , Jun 27, 2008
    #1
    1. Advertising

  2. Kai-Uwe Bux Guest

    wrote:

    > Hi,
    >
    > Let's say I have the following class:
    >
    > class foo {
    > public:
    > foo();
    > void addItem(int item);
    >
    > private:
    > int* items;
    > };


    I think you oversimplified your example: any implementation off addItem()
    will do since whatever it does, no client will be able to tell as the class
    does not provide any way of using the private data. Without observable
    semantics, neither does the class serve a purpose nor is there anything to
    test.


    > I want to write a unit test program to test foo::addItem(), to do that
    > the test program needs to know the contents of foo::items.
    >
    > So I can add one more public function to class foo:
    > int* getItems();
    >
    > But suppose in my case, the client code of class foo does not need
    > getItems() at all, this function serves only for test in this case.


    Well, client code will have _some_ uses of the class. Such uses should
    provide meaningfull ways of testing the observable behavior of the class,
    i.e., you should be able to write tests that make sure the class keeps its
    contractual obligations. That is where I would start. Otherwise, you end up
    testing implementation details. Since those might change, I don't think
    that client or outside test code have any business knowing about them.


    [snip]


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 27, 2008
    #2
    1. Advertising

  3. Greg Herlihy Guest

    On Jun 26, 7:51 pm, wrote:
    > Let's say I have the following class:
    >
    > class foo {
    > public:
    >     foo();
    >    void addItem(int item);
    >
    > private:
    >    int* items;
    > };
    >
    > I want to write a unit test program to test foo::addItem(), to do that
    > the test program needs to know the contents of foo::items.


    No, the unit test program has to confirm only that addItem() did what
    it was supposed to do (or more formally, that the functions's
    "postcondition" has been fulfilled after the call). Moreover, testing
    addItem()'s postconditions is done solely from a client's point of
    view. A unit test has no special access to the internals of the
    interface being tested - nor does it have any knowledge of the
    inteface's implementation.

    So in this example, a unit test would confirm that addItem() worked by
    calling other -public- routines in foo's interface - that would have
    beeen affected by the addItem() call. For example, if foo had a size()
    method, a unit test would might call size() before calling addItem(),
    save the result, then call adItem() and then call size() again, and
    confirm that the size() of foo has increased by one.

    > So I can add one more public function to class foo:
    >   int* getItems();
    >
    > But suppose in my case, the client code of class foo does not need
    > getItems() at all, this function serves only for test in this case.


    If the client does not need a getItems() method then there is no
    reason to add one to foo's interface. A unit test should test only the
    public routines an interface - and use only the public methods of the
    interface (that is, the one available to all clients) to do so. A unit
    test should not have special knowledge of the internals of the
    interface's implementation.

    After all, if there is no way for the client to tell whether addItem()
    did anything or not, then there would be no reason for the client to
    call addItem() in the first place. Because from the client's point of
    view - whether addItem() is called or not - makes absolutely no
    difference, so why bother calling addItem() at all?

    > So I am considering to have a separate class fooTest and this class is
    > a friend class of class foo so that it has an API to retrieve all
    > private data of foo.


    Giving the test access to foo's private data would make the test
    dependent on those implementation details - exactly what an unit test
    must avoid. For one, if the unit test tests only the public interface,
    then the programmer is free to replace the entire implementation of
    "foo" without breaking (or having to rewrite ) the test. The unit test
    can also confirm that any such refactoring has not changed foo's
    behavior in any way that would affect clients of foo.

    > I believe this works, but I am wondering if there is better solution.
    > Basically my goals are:
    > 1. I do not want the class to be bloated with a lot of API which only
    > serve for test purpose


    There should not be any code added to foo's public API for unit
    testing purposes.

    > 2. I want the function class to be independent from test class


    Yes, the unit test should be completely independent from the interface
    being tested (in other words, the unit test should just be another
    client of foo - and nothing more).

    Greg
    Greg Herlihy, Jun 27, 2008
    #3
  4. Joe Greer Guest

    Greg Herlihy <> wrote in news:317895b6-3422-489c-a280-4c502ab5ec62
    @a9g2000prl.googlegroups.com:

    >
    > There should not be any code added to foo's public API for unit
    > testing purposes.
    >
    >> 2. I want the function class to be independent from test class

    >
    > Yes, the unit test should be completely independent from the interface
    > being tested (in other words, the unit test should just be another
    > client of foo - and nothing more).
    >


    I wouldn't necessarily disagree with this, but I seem to have a lot of classes whose primary goal is a side
    effect. For example a writer to a file. By design, there really isn't any feedback to the client of the
    class, it just works or throws. If I just treat things as a normal user, I have no way of knowing directly
    if the data made it to the file or if there was a error that wasn't reported properly. How do you usually
    test such cases or is that another class of test that isn't called a 'unit test'?

    joe
    Joe Greer, Jun 27, 2008
    #4
  5. SeanW Guest

    On Jun 27, 8:56 am, Joe Greer <> wrote:
    > Greg Herlihy <> wrote in news:317895b6-3422-489c-a280-4c502ab5ec62
    > @a9g2000prl.googlegroups.com:
    >
    >
    >
    > > There should not be any code added to foo's public API for unit
    > > testing purposes.

    >
    > >> 2. I want the function class to be independent from test class

    >
    > > Yes, the unit test should be completely independent from the interface
    > > being tested (in other words, the unit test should just be another
    > > client of foo - and nothing more).

    >
    > I wouldn't necessarily disagree with this, but I seem to have a lot of classes whose primary goal is a side
    > effect. For example a writer to a file. By design, there really isn't any feedback to the client of the
    > class, it just works or throws. If I just treat things as a normal user, I have no way of knowing directly
    > if the data made it to the file or if there was a error that wasn't reported properly. How do you usually
    > test such cases or is that another class of test that isn't called a 'unit test'?


    I would just reach around in that case:

    test_object.append("some.file", "SOME-STRING");
    assert(system("tail -n 1 some.file | grep -q '^SOME-STRING$'") ==
    0);

    Or something along those lines.

    Sean
    SeanW, Jun 27, 2008
    #5
  6. Joe Greer Guest

    SeanW <> wrote in
    news::

    > On Jun 27, 8:56 am, Joe Greer <> wrote:
    >> Greg Herlihy <> wrote in
    >> news:317895b6-3422-489c-a280-4c502ab5ec62
    >> @a9g2000prl.googlegroups.com:
    >>
    >>
    >>
    >> > There should not be any code added to foo's public API for unit
    >> > testing purposes.

    >>
    >> >> 2. I want the function class to be independent from test class

    >>
    >> > Yes, the unit test should be completely independent from the
    >> > interface being tested (in other words, the unit test should just
    >> > be another client of foo - and nothing more).

    >>
    >> I wouldn't necessarily disagree with this, but I seem to have a lot
    >> of classes whose primary goal is a side effect. For example a writer
    >> to a file. By design, there really isn't any feedback to the client
    >> of the class, it just works or throws. If I just treat things as a
    >> normal user, I have no way of knowing directly if the data made it to
    >> the file or if there was a error that wasn't reported properly. How
    >> do you usually test such cases or is that another class of test that
    >> isn't called a 'unit test'?

    >
    > I would just reach around in that case:
    >
    > test_object.append("some.file", "SOME-STRING");
    > assert(system("tail -n 1 some.file | grep -q '^SOME-STRING$'") ==
    > 0);
    >
    > Or something along those lines.


    Yes. but that wouldn't be using my class' public interface. I can see a
    lot of different ways to check it outside the class, but is that still
    within Greg's definition of a unit test?

    joe
    Joe Greer, Jun 27, 2008
    #6
  7. James Kanze Guest

    On Jun 27, 4:15 pm, Joe Greer <> wrote:
    > SeanW <> wrote
    > innews::
    > > On Jun 27, 8:56 am, Joe Greer <> wrote:
    > >> Greg Herlihy <> wrote in
    > >> news:317895b6-3422-489c-a280-4c502ab5ec62
    > >> @a9g2000prl.googlegroups.com:


    > >> > There should not be any code added to foo's public API
    > >> > for unit testing purposes.


    > >> >> 2. I want the function class to be independent from test class


    > >> > Yes, the unit test should be completely independent from the
    > >> > interface being tested (in other words, the unit test should just
    > >> > be another client of foo - and nothing more).


    > >> I wouldn't necessarily disagree with this, but I seem to have a lot
    > >> of classes whose primary goal is a side effect. For example a writer
    > >> to a file. By design, there really isn't any feedback to the client
    > >> of the class, it just works or throws. If I just treat things as a
    > >> normal user, I have no way of knowing directly if the data made it to
    > >> the file or if there was a error that wasn't reported properly. How
    > >> do you usually test such cases or is that another class of test that
    > >> isn't called a 'unit test'?


    > > I would just reach around in that case:


    > > test_object.append("some.file", "SOME-STRING");
    > > assert(system("tail -n 1 some.file | grep -q '^SOME-STRING$'") ==
    > > 0);


    > > Or something along those lines.


    > Yes. but that wouldn't be using my class' public interface. I
    > can see a lot of different ways to check it outside the class,
    > but is that still within Greg's definition of a unit test?


    I don't see why not. The "public" interface of the class is
    what is visible from outside the class. Data written a file is
    (hopefully) visible, and thus part of the public
    interface---part of the post-condition. (I have some cases
    where the "post-condition" is a core dump; I also have unit
    tests which verify this.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 27, 2008
    #7
  8. Joe Greer Guest

    James Kanze <> wrote in
    news::

    >
    > I don't see why not. The "public" interface of the class is
    > what is visible from outside the class. Data written a file is
    > (hopefully) visible, and thus part of the public
    > interface---part of the post-condition. (I have some cases
    > where the "post-condition" is a core dump; I also have unit
    > tests which verify this.)
    >



    Fair enough, This is what I actually assumed, but I just wanted to be clear
    on the definitions in case I was missing something.

    joe
    Joe Greer, Jun 27, 2008
    #8
  9. Greg Herlihy Guest

    On Jun 27, 5:56 am, Joe Greer <> wrote:
    > Greg Herlihy <> wrote in news:317895b6-3422-489c-a280-4c502ab5ec62
    > @a9g2000prl.googlegroups.com:
    >
    > > There should not be any code added to foo's public API for unit
    > > testing purposes.

    >
    > >> 2. I want the function class to be independent from test class

    >
    > > Yes, the unit test should be completely independent from the interface
    > > being tested (in other words, the unit test should just be another
    > > client of foo - and nothing more).

    >
    > I wouldn't necessarily disagree with this, but I seem to have a lot of classes whose primary goal is a side
    > effect.  For example a writer to a file.  By design, there really isn't any feedback to the client of the
    > class, it just works or throws.  If I just treat things as a normal user, I have no way of knowing directly
    > if the data made it to the file or if there was a error that wasn't reported properly.  How do you usually
    > test such cases or is that another class of test that isn't called a 'unit test'?


    Even though the unit test should not call any non-public methods of
    the interface being tested - there is no reason why the unit test
    should not call other functions, functions that do not belong to the
    interface being tested if necessary to verify that a function's
    postconditions have been met.

    So in this example, the "right" way to verify the interface function
    that writes data to a file - would depend (as always) on the exact
    guarantee (in the form of postconditions) that the function called,
    has made to its clients; (assuming of course the client had first met
    all of the function's "preconditions" before the function call).

    Therefore, the question is whether the function called, promises to
    have written certain information to a file by the time the function
    returns. If the function makes such a detailed promise, then the unit
    test should indeed open the file (by using standard I/O routines),
    read the the file's contents, and verify that they match the content
    in the form promised by the interface.

    The more likely scenario, however, is that the function being tested
    makes a less specific promise, perhaps promising only to store the
    user-provided data "in a safe place" (with the implicit promise that
    the data stored could be subsequently retrieved intact by the client).
    In this case, the unit test should not examine the contents of the
    file. In fact, client should not even know that this file exists -
    because the interface never promised that the "safe place" was
    necessarily in a file. Instead, the unit test has to verify only that
    the data has been stored safely enough to be retrievable. So the unit
    test would verify the function's postconditions by attempting to
    retrieve the data (through the interface's public methods) - and once
    the data has been retrieved - comparing it against a copy of the
    original data passed to the function call.

    Essentially, all unit test verifications will fall roughly into one of
    these two categories: either the postconditions will be detailed
    enough to be verifiable by external routines - or nonspecific enough
    that the public interface will have to offer methods that can be used
    for verification. Because, as I noted in my previous post - every time
    that a client calls a function, the client "wants" something to happen
    (otherwise, why bother?). So one of the primary benefits of writing
    unit tests (and the reason why they prove so useful) is that they
    reconcile the client's expectations with the implementation's own
    guarantees. Otherwise, without a clear accounting on each side, it is
    all too easy for the client to make assumptions about an interface
    that its implementation never had any intention of guaranteeing. So,
    by eliminating discrepancies between what a client expects and what an
    implementation delivers - a sizable number of bugs can be avoided.

    Greg
    Greg Herlihy, Jun 28, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RGlmZmlkZW50?=

    "Page" class and utility class

    =?Utf-8?B?RGlmZmlkZW50?=, Jan 11, 2005, in forum: ASP .Net
    Replies:
    5
    Views:
    340
    =?UTF-8?B?IkFuZGVycyBOb3LDpXMgW01DQURdIg==?=
    Jan 11, 2005
  2. Gabriel Rossetti
    Replies:
    3
    Views:
    531
    Jerry Hill
    Apr 25, 2008
  3. Phlip
    Replies:
    2
    Views:
    435
    phlip
    Jul 1, 2008
  4. Phlip
    Replies:
    36
    Views:
    857
    phlip
    Jul 2, 2008
  5. Garg
    Replies:
    0
    Views:
    305
Loading...

Share This Page