White-box Unit Testing - in whidbey

James Newkirk shows how to write a white-box test in Whidbey He shows how to test the value in a private field and invoke a private method. While you can (not so) easily do that today in NUnit, he demonstrates the PrivateObject class that lets you easily invoke private methods and look at private fields.

Could this “PrivateObject“ class be used for evil? Yes it could be used for evil - I imagine - but no more evil than that of reflection.

James has some great holy war type feedback about Should I or Shouldn't I white-box test. Those who say no probably haven't fought with unit testing a singleton class where we have to test it under multiple configurations that *normally* get set during the initial (private) constructor and/or the private methods called by the constructor. So yes, I can see a use. Is this an excuse? I haven't really thought of another technique....but to quote Michaelangelo, “I am still learning...” (via a silly set of fridge magnets I saw at Chapters today). The silly part of course is how one can learn from (and quote) a famous historical figure through something as silly as a fridge magnet.

Comments

  • Barry Gervin June 12, 2004 11:53 AM

    Where does he show us? Can you include a link?

  • Barry Gervin June 14, 2004 9:40 PM

    White-box regression testing...

    quite simply - it's just wrong. You as the developer of a library provide to your customer (anyone using it) a set of unit tests and an interface, and say to them that the unit tests prove that this interface works. That's the whole point.

    a) you should be able to test your private implementation entirely through your public interface (otherwise it shouldn't be there!)

    b) adding any tests beyond the public interface adds artifical constraints to your system, which are not necessary and can only hurt you.

  • Barry Gervin June 15, 2004 9:16 AM

    Ok smarty - help me out here. I have what I think is a need for a whitbox test - but tell me how to do it through the public API.

    I have a singleton class. It has a private constructor. The private constructor is called once and only once by the getter on the public static "Instance" property. The constructor in turn calls a private Initialize method that loads up its configuration from an XML configuration file. But it has several possible configurations - so I need to run the 10 tests or so that I have under each of the N configurations. What I *think* I should do is after switching the configuration data to the next configuration, call the private Initialize function to re-establish the objects internal state. Without the ability to call the private member, I'd no way to reset the singleton - which I don't normally need to do during a production execution of it. I'd rather not change the public API just to make it easier to test....although I've been guilty of doing that (something test first coding sometimes leads you do that - sometimes without realizing it).

  • Barry Gervin June 25, 2004 11:17 PM

    Barry,
    I had a similar situation recently. I had an abstract base class that provided some logging functionality, and in the constructor, it "registered" itself with a singleton so only one instance of that class would be active at a time. I thought about "white-box" testing, but decided against it. I that as far as the unit tests were concerned, the internal state of that singleton dind't matter; I could have these other classes register themselves automatically with random names, and it wouldn't matter. These registrations would never occur in a live system; however, these unit tests succeeded in testing the public interface and all of its preconditions/postconditions.

    As to your follow-up comment on how to test for multiple configurations? I would suggest that your current implementation would not have evolved the way it did if you had written the tests first. As for testing your particular scenario, I would suggest that you move all of the configuration load/validation code into some sort separate testable class, then have the singleton defer to this separate class. That way you can test multiple configurations through unit tests, but also test the singleton without having to muck around with its internal state.

    Does that make sense?

  • TrackBack June 25, 2004 11:28 PM

  • Barry Gervin February 4, 2005 1:20 AM

    Barry,
    I think once you are convinced, like me, that even a private method/field needs to be tested, you can actually do it in 2 other ways-
    1. Preproc directives
    2. partial types in C# 2.0 .
    For me, reflection has worked nicely, but I wanted to get into something more elegant.
    Ranjan

New Comments to this post are disabled