Skip to main content

A library that makes writing pyhamcrest matchers easier and more fun.

Project description

PyHamcrest is a great thing for writing reusable tests, but sometimes writing your own matchers may be a bit of a chore. This project aims at making this task easy, fast and even fun (for want of a better word).

To reiterate the obvious, a test should always do all the checks it has to do, and even if some of them fail, the rest should still be run. That way you will get a better idea of what’s gone wrong with your code, and you will waste less time fixing the first of the checks only to find the the second one is still failing, and that means that you should have fixed the first one in a different way.

So, instead of this:

def test_the_holy_grail():
    the_holy_grail = seek_the_holy_grail()
    assert_that(the_holy_grail.is_holy(), is_(True))
    assert_that(the_holy_grail.depth, greater_than(5))
    assert_that(the_holy_grail.width, greater_than(6))
    assert_that(the_holy_grail.height, greater_than(7))

this should be written:

def test_the_holy_grail():
    the_holy_grail = seek_the_holy_grail()
    assert_that(
        the_holy_grail,
        is_holy()\
            .with_depth(greater_than(5)).\
            .with_width(greater_than(6)).\
            .with_height(greater_than(7))
    )

The second one, however, requires writing your own matchers. With this toolbox, it is easy.

All you have to do is to write your is_holy matcher that inherits from the MultisegmentMatcher as the backbone. Then you write individual matchers for each of the holy grail properties enhancing them with the MatcherPluginMixin, and you register them with the is_holy matcher.

So, this is your is_holy matcher:

class IsHolyMatcher(MultisegmentMatcher):
    def __init__(self):
        super().__init__()

def is_holy():
    return IsHolyMatcher()

And that’s it. You don’t have to override the usual matcher methods. Everything will be done by the parent class. However, it doesn’t do any matching yet, so we need to write the plugins. Let’s start with the actual holyness:

.. code:: python
class HolynessMatcher(BaseMatcher, MatcherPluginMixin):
def __init__(is_holy=True):

super().__init__() self.is_holy = is_holy

def component_matches(self, item):

# the item will be a grail return self.is_holy == item.is_holy()

def describe_to(self, description):
description.append_text(

“A grail which is {}holy”.format(”” if self.is_holy else “not “))

def describe_component_mismatch(self, item, mismatch_description):
mismatch_description.append_text(

“The grail was {}holy”.format(”” if item.is_holy() else “not “))

And then you register it with the main matcher:

.. code:: python
class IsHolyMatcher(MultisegmentMatcher):
def __init__(self, is_holy):

super().__init__() self.register(HolynessMatcher(is_holy))

def holy(is_holy):

return IsHolyMatcher(is_holy)

Of course, you could write that HolynessMatcher logic in your IsHolyMatcher, but if we have the power of plugins, then why not use it?

For now, we only have this bit: assert_that(the_grail, is_holy()), and not the .with_width(...) stuff. So let’s write it. I won’t go through the process of writing the plugin for the width as it is rather straightforward, but here’s how you register it with the main matcher:

.. code:: python
class IsHolyMatcher(MultisegmentMatcher):
def __init__(self, is_holy):

super().__init__() self.register(HolynessMatcher(is_holy))

def with_width(self, value):

self.register(GrailWidthMatcher(value)) return self

def holy(is_holy):

return IsHolyMatcher(is_holy)

Now you can do the is_holy().with_width(greater_than(5)) stuff. Note that you have to return ``self`` from the plugin registering methods, as (a) you might want to chain them, and (b) the result of the chain still needs to be a matcher.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyhamcrest_toolbox-0.0.1.tar.gz (3.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyhamcrest_toolbox-0.0.1-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file pyhamcrest_toolbox-0.0.1.tar.gz.

File metadata

  • Download URL: pyhamcrest_toolbox-0.0.1.tar.gz
  • Upload date:
  • Size: 3.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.0

File hashes

Hashes for pyhamcrest_toolbox-0.0.1.tar.gz
Algorithm Hash digest
SHA256 350d5e5f1fc966c36860311b78b66fb217989a67ea5b0c1cdd7ad7bfe682f049
MD5 613487481732193ffa5985a67bfe7afd
BLAKE2b-256 d53df4f55b4cb2b2e3403ce9369de6a5a8bd5c11af277d3133d942e650d7147c

See more details on using hashes here.

File details

Details for the file pyhamcrest_toolbox-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: pyhamcrest_toolbox-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 5.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.0

File hashes

Hashes for pyhamcrest_toolbox-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1722d086fa57c7ddd121e15a308d16131d3b4f22ca80b6fd1d009a3efe988e9f
MD5 c492fb4ffaf918edb7b29dba9f994839
BLAKE2b-256 c13c1bec2ac856f179e2ce514ebfaf18fa831d6012112f55cf9529e3ac7c7cc7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page