Python Hamcrest
We can also choose to use the Hamcrest assertion library in our code, either instead of the pyunit assertions or in addition to them. Hamcrest includes some very helpful assertions that are not part of pyunit, and also includes version for many languages, including both Python and Java. Most of the autograders in previous Computational Core courses are written with the Hamcrest assertion library!
Basic Assertions
Hamcrest uses a single basic assertion method called assert_that()
to perform all assertions. It comes in two basic forms:
assert_that(actual, matcher)
- asserts thatactual
passes thematcher
.assert_that(actual, matcher, message)
- asserts thatactual
passes thematcher
. If not, it will printmessage
as part of the failure.
The real power of Hamcrest lies in the use of Matchers, which are used to determine if the actual
value passes a test. If not, then the assert_that
method will fail, just like a pyunit assertion.
For example, to test if an actual value returned by a fictional calculator
object is equal to an expected value, we could use this statement:
assert_that(calculator.add(1, 3), is_(4))
As we can see, reading this statement out loud tells us everything we need to know: “Assert that calculator.add(1, 3)
is 4!”
Here are a few of the most commonly used Hamcrest matchers, as listed in the Hamcrest Tutorial. The full list of matchers can be found in the Matcher Library in the Hamcrest documentation:
is_(expected)
- a shortcut for equality - an example of syntactic sugar as discussed below. Notice the underscore to differentiate it from the Python keywordis
equal_to(expected)
- will call theactual.equals(expected)
method to test equalityinstance_of(type)
- can be used to check if an object is the correct type, helpful for testing inheritancenone()
- check if the value isNone
not_none()
- check if the value is notNone
same_instance(expected)
- checks if two objects are the same instancehas_entry(key, value)
,has_key(key)
,has_value(value)
- matchers for working with mapping types like dictionarieshas_item(item)
- matcher for sequence types like listsclose_to(expected, delta)
- matcher for testing floating-point values within a rangegreater_than(expected)
,greater_than_or_equal_to(expected)
,less_than(expected)
,less_than_or_equal_to(expected)
- numerical matchersequal_to_ignoring_case(expected)
,equal_to_ignoring_whitespace(expected)
,cotnains_string(string)
,ends_with(string)
,starts_with(string)
- string matchersall_of(matcher1, matcher2, ...)
,any_of(matcher1, matcher2, ...)
,is_not(matcher)
- boolean logic operators used to combine multiple matchers
Syntactic Sugar
Hamcrest includes a helpful matcher called is_()
that makes some assertions more easily readable. For example, each of these assertion statements from the Hamcrest Tutorial all test the same thing:
assert_that(theBiscuit, equal_to(myBiscuit))
assert_that(theBiscuit, is_(equal_to(myBiscuit)))
assert_that(theBiscuit, is_(myBiscuit))
By including the is_()
matcher, we can make our assertions more readable. We call this syntactic sugar since it doesn’t add anything new to our language structure, but it can help make it more readable.