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 --------------------------------------------------------------------- --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
