On 9/15/06,
Jeff Brown <[EMAIL PROTECTED]> wrote:
There's perhaps more that's known about an IEnumerator than you give
credit. It has a known abstract state machine. We call MoveNext and if
it returns true then Current should give us something meaningful. If we
call Current before calling MoveNext, after calling Reset, or after
MoveNext returned false it should throw an InvalidOperationException.
etc...
BTW, I was not using pattern in the software design sense. I was using
to describe the structure of inputs and sequence of interactions
required to verify conformance of an object under test with its
specification / contract.
Whenever you write tests for an IEnumerator you will find yourself
repeating the same things over and over again. Basically you run
through the 5 scenarios I outlined below then you tackle checking
implementation specific details. Where I believe the tester abstraction
is most useful is in its ability to verify all of those scenarios
without you needing to know exactly what they are or exactly how to set
them up.
So you can gain a lot by abstracting out the construction of the test
rather than just its particulars. That's all my original example was
about. In my approach the tester knows how to construct interesting
test inputs given an abstract series of operations (via a builder). In
your approach, the tester is largely agnostic of test inputs and of
expected behaviour. So the user of the tester needs to do more work to
provide the necessary information. On the other hand your approach
makes fewer assumptions.
(In mine I was assuming that the enumerator iterated over a
deterministic sequence of arbitrary finite size. I was also assuming
that many enumerator implementations encounter interesting boundary
conditions when they represent empty sequences. This obviously does not
hold true all of the time.)
The latter part of the email is about a form of model based testing. We
describe abstractly how a given implementation should behave under
certain constraints and have the test framework figure out how to
"prove" it to a satisfactory degree of confidence. This is exactly the
kind of thing we humans set about doing all of the time when testing but
we get bored after a while...
It is complex and error prone indeed but I believe it has a certain
potential.
Jeff.
-----Original Message-----
From: [email protected] [mailto:[email protected] ]
On Behalf Of Jay Flowers
Sent: Friday, September 15, 2006 12:26 PM
To: [email protected]
Subject: MbUnit Re: TypeFixture on steroids was RE: MbUnit Re: Research:
Using LSP to ease testing
On 9/15/06, Jeff Brown <[EMAIL PROTECTED]> wrote:
>
> I'm not sure about this one. It looks like the embedding for the test
> fixture needs (the enumeration data) needs to provide a lot of logic.
> There are some particular test patterns I'd like to abstract:
>
> 1. What happens when calling Current before MoveNext.
> 2. What happens when calling Current after MoveNext returns true.
> 3. What happens when calling Current after MoveNext returns false.
> 4. What happens when calling Current after Reset.
> 5. What happens when calling MoveNext after Reset.
It is an example not a complete unit test. The example is to show the
idea. Of course if this where for an actual unit test all those things
would be addressed.
>
> I can easily cook up the pattern the test input must satisfy in some
> kind of Tester class. I can also verify the results quite easily
> because the specification of IEnumerable is known. IMHO pushing
> verification down to a class like IEnumerationData partly defeats the
> purpose of the Tester. In particular, the caller would have to cook
> up several IEnumerationData's with different implementations of
> MakeANewTestSubject to ensure that all of the interesting cases get
> covered. It's also coupled to the particular sequence of requests
> issued by the Tester.
I assume you meant to write IEnumerator not IEnumerable. This is a
pattern cooked up just for that (not really, a pattern is something that
has been created least three times independently, patterns are recorded
not authored). It is not just about the results it is about the setup.
IEnumerator does not expose enough control and information to drive the
test and verify that what was supposed to happen happened. To prevent
the test fixture from coupling to this knowledge IEnumerationData was
created. It has knowledge of the type providing the IEnumerator. This
knowledge allows it control and information for verification.
Delegation of these types of tasks is not a new thing.
It is used with test doubles all the time. A type of test double is a
mock. Test fixtures delegate to test doubles control and verification.
>
> Ideally I want to be able to extend the Tester to cover new scenarios
> without having to modify its inputs in any way.
Why? How could it possibly do anything new and different without new
and different inputs?
>
> It might be helpful to think of a related testing approach. We could
> annotate a test method with the expected input and output domains of a
> given operation. For stateful objects we could annotate the various
> transitions among states. Then we have MbUnit go ahead and cook up
> test input based on the annotations and verify the results.
>
> So an interesting way to write a test fixture would be to describe the
> state machine of the object under test...
This sounds complex and error prone. Have I missed something?
--
Jay Flowers
----------------------------------------------------------------------
http://jayflowers.com
---------------------------------------------------------------------
--
Jay Flowers
----------------------------------------------------------------------
http://jayflowers.com
---------------------------------------------------------------------
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MbUnit.User" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/MbUnitUser
-~----------~----~----~----~------~----~------~--~---
