Ben Finney wrote: > [Jonathan, please don't send me copies of messages sent to the > discussion thread. I follow comp.lang.python via a non-mail interface, > and it's irritating to get unwanted copies of messages via email.]
[Thank you for letting me know your preference. For myself, I often appreciate it when people send me a copy directly.] >>The line >> plus(2, '', _ex=TypeError) >>causes something to be recorded, <snip> > That's confusing, then, for two reasons: > > It looks like '_ex' is an argument to the 'plus' function, which > otherwise (probably by design) looks exactly like a call to the 'plus' > function the programmer is testing. Actually, 'plus' above is an instance of a class (which for now we will call PyUnknown) that has a __call__ method. We know this because we imported it from metaclass.py.mymod. It is, if you like, a /test surrogate/ or /instrumented wrapper/ for the function 'plus' in mymod. And as such it has different properties. For example, the '_ex' parameter has a special significance. > Since this is, instead, an > assertion *about* that function, it is misleading to see it as an > argument *to* the function. Although, by design, it looks like an argument to 'plus' in mymod, it is as I said an argument to 'plus' in metatest.py.mymod, which is something completely different, namely a PyUnknown object. We can think of test-first programming as 1. Stating the problem to be solved. 2. Solving that problem. In mathematics, we often use unknowns when stating problems. We can think of a PyUnknown as being analogous, in programming, to the unknowns we use in mathematics. However, if the difference confuses one (and it can in some situations), then instead do from metatest.py.mymod import plus as mt_plus and then the confusing line becomes mt_plus(2, '', _ex=TypeError) which I think you will find much clearer. > It uses the "leading-underscore" convention which means "this is not > part of the public interface, and you'd better know what you're doing > if you use this externally". This convention is exactly that, a convention. Conventions allow us to communicate efficiently, without spelling everything out. Implicit in metatest are some other conventions or the like. Oh, and this use of metatest does confirm to the convention, and extra knowledge is required to use leading underscore parameters. >>Finally, if you can think of a better way of saying, in Python, "The >>function call plus(2, '') raises a TypeError", please let me know, >>and I'll consider using it in the next version of Metatest. > > I would think an explicit function call that says what it's doing > would be better. The unittest module implements this as: > > self.failUnlessRaises(TypeError, plus, 2, '') <snip> > which has the benefit of being explicit about what it's doing. Well, you did not tell me what self is (althout I guessed it is an instance of a subclass of unittest.TestCase). Nor did you tell me that this statement is part of a class method. To my eye, your example puts the focus on failUnlessRaises and on TypeError. I think the metatest way puts an equal focus on calling plus(2, '') and the result of this call. I give a comparison of three ways of writing tests in my slides: http://metatest.sourceforge.net/doc/pyconuk2007/metatest.html#slide13 To summarise: both metatest and unittest require the user to know something. Once that something is known, the choices for the crucial test line are plus(2, '', _ex=TypeError) self.failUnlessRaises(TypeError, plus, 2, '') I hope you know find the first option less confusing. (It certainly is shorter.) -- Jonathan -- http://mail.python.org/mailman/listinfo/python-list