pyassert is an assertion library for the Python programming language.
##Introduction
Assertions are used in automated tests to verify that a given piece of code behaves as expected. pyassert aims to provide assertions with provide
- rich functionality: common assertions should be expressed easily
- good readability: assertions should be easy to read and easy to understand to enhance the overall understandability of the test
- independent of the test framework: pyassert assertions work with every Python test environment.
pyassert is available via the Cheeseshop so you can use easy_install or pip:
$ pip install pyassert
The most important function pyassert provides is assert_that. This function is used to start an assertion. You pass in the actual value and as a result you get an AssertionHandler (although you will never care, most of the time).
The AssertionHandler provides several assertion predicates. These are functions you can use to verify a given state of the actual value.
Some examples:
from pyassert import *
assert_that('spam and eggs').ends_with('eggs')
assert_that(['spam', 'and', 'eggs']).contains(any_of('spam', 'ham'))
The general structure is
assert_that(actual_value).matcher_name(expected_values)
Every assertion will return None if the actual value matches the expectations or raise an AssertionError with a readable message in case the expectations are not met.
###Matchers
The following matcher are provided by pyassert.
is_equal_to
/equals
/is_not_equal_to
- Asserts that two objects are (not) equal (using==
)is_identical_to
/is_not_identical_to
- Asserts that two objects are (not) identical (usingis
)is_none
/is_not_none
- Asserts that an object is (not)None
raises
/does_not_raise
- Asserts that a given callable raises/ does not raise an expected exception
contains
/does_not_contain
- Asserts that the actual string contains an expected stringends_with
/does_not_end_with
- Asserts that the actual string ends with an expected stringis_empty
/is_not_empty
- Asserts that the actual string is emptymatches
/does_not_match
- Asserts that the actual string matches the expected regular expressionstarts_with
/does_not_start_with
- Asserts that actual string starts with the expected string
contains
/does_not_contain
- Asserts that actual list/ tuple contains the expected elements.is_empty
/is_not_empty?
- Asserts that actual list/ tuple is empty
is_true
- Asserts that the actual object isTrue
is_false
- Asserts that the actual object isFalse
is_instance_of
/is_an_instance_of
/is_not_an_instance_of
- Asserts that the actual object is an instance of the expected typeis_a
- Asserts that the actual object is of the actual type
is_less_than
/lt
- Asserts that the actual number is less than the expected numberis_less_or_equal_than
/le
- Asserts that the actual number is less or equal than the expected numberis_greater_than
/gt
- Asserts that the actual number is greater than the expected numberis_greater_or_equal_than
/ge
- Asserts that the actual number is greater or equal than the expected number
is_a_directory
/is_not_a_directory
- Asserts that a given string names an existing directoryis_a_file
/is_not_a_file
- Asserts that a given string names an existing filehas_file_length_of
- Asserts that a given string names an existing file with an expected file length in bytesis_a_empty_file
- Asserts that a given string names an existing empty fileis_a_file_with_content
- Asserts that a given string names an existing file with the expected content
pyassert uses Matchers to match actual values against expected values. A matcher is simply a class extending the pyassert Matcher class which looks like this:
class Matcher (object):
def accepts (self, actual):
"""Returns True if the given actual value is accepted by this matcher."""
return True
def matches (self, actual):
"""Returns True if the given actual value matches this matcher. Returns False otherwise"""
pass
def describe (self, actual):
"""Returns a description which is used in case the actual value did not match this matcher's expectation."""
pass
Once you have created your Matcher you need to register it. The registration is done with a class decorator register_matcher providing the name of the matcher
from pyassert import Matcher, register_matcher
@register_matcher("matches_my_matcher")
class MyMatcher (Matcher):
...
Now your matcher is available using
assert_that(actual).matches_my_matcher(...)
All arguments that are passed to the matches_my_matcher function call are passed to the constructor of MyMatcher that is used by this assertion.
If you have a matcher that should also be available in a negated manner (such as contains
and does_not_contain
) you
can register the matcher twice but set the second one to negated:
from pyassert import Matcher, register_matcher
@register_matcher("matches_my_matcher")
@register_matcher("does_not_match_my_matcher", negated=True)
class MyMatcher (Matcher):
...
If you also want to provide a custom message that describes the failed, negated state, you can additionally override
the describe_negated
method in your matcher class. See this example
@register_matcher("is_empty")
@register_negated_matcher("is_not_empty")
class IsEmptyMatcher(ListOrTupleMatcher, StringMatcher):
def matches(self, actual):
return len(actual) == 0
def describe(self, actual):
return "'%s' is not empty" % actual
def describe_negated(self, actual):
return "'%s' is empty" % actual
- Added
does_not_contain
matcher to ContainsMatcher (Pull-Request by @fraisse, Sylvain Fraïssé) - Enabled flake8 plugin
- Allow any collection in ListOrTupleMatcher (Pull-Request by @charlax, Charles-Axel Dein)
- Added
is_a_file_with_content
matcher - Added
is_a_empty_file
matcher
- Added
raises
/does_not_raise
matcher - Added filesystem matchers
- Using six to provide compatibiliy with Python 3
- Negated matchers
- Added number matchers
- Added
is_instance_of
matcher - Added
is_equal_to
as alias toequals
which is now deprecated - Hosting project as part of the pyclectic organisation
- Added
is_true
matcher - Added
is_false
matcher
- Added
is_none
matcher
- Added
is_a matcher
that assert that actual values are of an expected type - pyassert is now compatible with Python 3 (see Travis Build)