Table of Contents
Motivation
I’ve written about Software Testing Concepts in general and also about pytest in particular.
Now I want to introduce you to a nice little add-on which makes your testing -hopefully- easier.
Hamcrest
Hamcrest is around for a couple of years. I’ve used it together with JUnit back in the days. It had a bit of an on-off-relationship with JUnit, because it was first independent, than in 2012 included into JUnit 4 and finally excluded again from JUnit 5.
But nevertheless: the library became so popular that it was ported to Python in 2010.
fun fact: ‘Hamcrest’ is an anagram of ‘matchers’
PyHamcrest
Installation
pip install pyhamcrest
Now we can import the module:
from hamcrest import *
Replace assertEqual with matcher
If you have a test case like this
def test_digit(self):
pattern = Pattern()
pattern.starts_with(DIGIT)
p = re.compile(pattern.pattern)
self.assertEqual(p.findall('1'), ['1'])
you can replace the assertEqual with assert_that and a matcher equal_to
def test_digit(self):
pattern = Pattern()
pattern.starts_with(DIGIT)
p = re.compile(pattern.pattern)
assert_that(p.findall('1'), equal_to(['1']))
This isn’t that impressive, is it?
More Complex Matchers
The fun begins, when we want to compare e.g. lists
def test_compare_list_of_items(self):
actual_list_of_items = ['apple', 'banana', 'cherry']
expected_list_of_items = ['apple']
assert_that(actual_list_of_items, has_items(*expected_list_of_items))
This runs smoothly. If we add beans to the list
expected_list_of_items = ['apple', 'beans']
we get the AssertionError:
> assert_that(actual_list_of_items, has_items(*expected_list_of_items))
E AssertionError:
E Expected: (a sequence containing 'apple' and a sequence containing 'beans')
E but: a sequence containing 'beans' was <['apple', 'banana', 'cherry']>
This output is very readable.