← Back to team overview

launchpad-dev team mailing list archive

The start of the Matchers invasion

 

Hi,

testtools and assertThat have been available for a while now, but I
just landed what I think are the first uses of them in the launchpad
tree.

For those that know what they are:

lp.testing.matchers has a couple of basic matchers, please use and
extend. I would suggest lp.<app>.testing.matchers or similar for domain
specific ones so that the file doesn't grow too large.

You will find tests in lp.testing.tests.test_matchers, please also
add tests there (or in equivalent places in your app) for matchers that
you add.

The current users of the matchers are in lp.testing.tests.test_factory.

For those that aren't familiar with matchers:

testtools (which the Launchpad TestCase classes are derived from)
provides the basic infrastructure for matchers.

http://bazaar.launchpad.net/~testtools-dev/testtools/trunk/annotate/head:/MANUAL#L114

The use for them is

  self.assertThat(something, SomeMatcher())

such as

  self.assertThat(an_object, Provides(IAnInterface))

The matchers that you pass have a small interface, in
testtools.matchers, where they define __str__ to explain what they will
match, and match(matchee) to do the matching. Their constructors can
take whatever they like, which will normally be parameters to influence
the expected value.

If the value passed to match() matches, then None is returned, otherwise
an instance of a Mismatch is returned. These have an even simpler
interface, just defining describe() to explain what went wrong.

assertThat() deals with these objects for you, so you just pass in the
value and the matcher, and it will do the check and then print out an
explanation if needed.

Yes, these are fairly similar to custom assertion methods, and while
they may seem a little more heavyweight, they do have some advantages:

  * They can be composed in a more pleasant fashion.
  * They can be used outside of testing.
  * They are easier to test.
  * They can provide better failure messages.
  * They are outside the TestCase class, so you don't have to load your
    base TestCase class, or have many different ones and then have
    difficulty when you want to combine two or more.


There's no requirement to use them, but they are there if you want to
make use of them, see above for where to find the existing ones and to
add more.

Thanks,

James





Follow ups