[TIP] RFF: Article on python test design pattern - DAI
gary.bernhardt at gmail.com
Tue Dec 8 09:58:54 PST 2009
I liked this article! I'm glad to see discussion of advanced testing,
dependency injection, and *actual* unit testing in the Python world.
Please keep it up! :)
One thing that I'd point out is that you *are* mocking when you do
this; it's just that Python allows you to hand-roll mocks very easily.
This certainly doesn't change your objections to mocking libraries,
but it might be useful to point out so that people realize the
Here's a little critique of the test from the point of view of a
stub/mock library author. :) You write:
rres = RemoteResource('testpath.json', myurlopen)
My main complaint is that the assert isn't the last line; I can't see,
at a glance, what's being tested. In other words, the test doesn't
follow arrange-act-assert. Consistent use of AAA test organization
makes it easier to scan tests quickly, which matters a lot with a
Here's how I'd write it using Dingus, which I'm biased toward because
I wrote it. :)
urlopen = Dingus()
assert urlopen.calls('()', 'http://example.com/testpath.json')
No SUT changes are needed, and it's the same number of lines, but it's
more expressive in my opinion, mostly because it follows the
arrange-act-assert pattern. There's exactly one line per step: arrange
the collaborators, perform the action under test, then assert on the
This has the added benefit of preventing the mistake that Jean-Paul is
worried about: since the assertion is now inside the test itself,
there's no chance of the SUT preventing it from running.
Dingus also has a magical feature that can remove the need for
injection entirely by auto-stubbing the SUT's module namespace.
However, as you can probably imagine, it tends to encourage hard
coupling. If you're interested, I did a short screencast  about it.
Unfortunately, I don't give any warnings about its dangers, because I
hadn't realized them at the time.
I'd recommend taking a look at a lightweight mock/stub library like
Dingus or Michael Foord's Mock, which is the project that Dingus was
originally forked from. They're both very short – Dingus is about 250
lines, including the magical isolation features, and Mock was about
the same length last I checked. They use a bit of Python magic (or a
lot in DingusTestCase's case), but in a consistent and predictable
way. They're both designed to minimize ceremony. These aren't your
father's mock libraries. :)
On Mon, Dec 7, 2009 at 8:07 PM, Aaron Maxwell <amax at redsymbol.net> wrote:
> (that's Request For Feedback)
> Hi everyone,
> Here is a draft article about a useful design pattern for Python code tests:
> I am surely not the first to use this idiom, but I *might* be the first to
> document it this well, and to give it a name. Have you seen this before?
> Constructive feedback is appreciated.
> Thanks in advance for your comments. Either reply here on the list, or by
> email to amax at redsymbol.net.
> Aaron Maxwell
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
More information about the testing-in-python