Expects¶
Expects is an expressive and extensible TDD/BDD assertion library for Python. Expects can be extended by defining new matchers.
Usage¶
Just import the expect callable and the built-in matchers and start writing test assertions.
from expects import *
expect([]).to(be_empty)
expect(False).not_to(be_true)
expect({
'name': 'Jack',
'email': 'jack@example.com'
}).to(have_key('name', match('\w+')))
expect(str).to(have_property('split') & be_callable)
expect(lambda: foo).to(raise_error(NameError))
expect('Foo').to(equal('Bar') | equal('Foo'))
Contents¶
Installation¶
PyPI¶
You can install the last stable release of Expects from PyPI using pip or easy_install:
$ pip install expects
Matchers¶
equal¶
expect(1).to(equal(1))
expect(1).not_to(equal(2))
expect(1).to(equal(2))
Failure
Expected 1 to equal 2
expect(1).not_to(equal(1))
Failure
Expected 1 not to equal 1
be¶
class Foo(object):
pass
value = Foo()
expect(value).to(be(value))
expect(1).not_to(be(2))
expect(1).to(be(2))
Failure
Expected 1 to be 2
expect(value).not_to(be(value))
Failure
Expected <Foo object at 0x7ff289cb4310> not to be <Foo object at 0x7ff289cb4310>
be_true¶
expect(True).to(be_true)
expect(False).not_to(be_true)
expect(False).to(be_true)
Failure
Expected False to be True
expect(True).not_to(be_true)
Failure
Expected True not to be True
be_false¶
expect(False).to(be_false)
expect(True).not_to(be_false)
expect(True).to(be_false)
Failure
Expected True to be False
expect(False).not_to(be_false)
Failure
Expected False not to be False
be_none¶
expect(None).to(be_none)
expect('foo').not_to(be_none)
expect(True).to(be_none)
Failure
Expected True to be None
expect(None).not_to(be_none)
Failure
Expected None not to be None
be_a / be_an¶
class Foo(object):
pass
class Bar(object):
pass
class Object(object):
pass
expect(Foo()).to(be_a(Foo))
expect(Foo()).not_to(be_a(Bar))
expect(Foo()).to(be_an(object))
expect(Foo()).not_to(be_an(Object))
expect(Foo()).to(be_a(Bar))
Failure
Expected <Foo object at 0x7ff289cb4310> to be a Bar
expect(Foo()).to_not(be_a(Foo))
Failure
Expected <Foo object at 0x7ff289cb4310> not to be a Foo
expect(Foo()).to(be_an(Object))
Failure
Expected <Foo object at 0x7ff289cb4310> to be an Object
expect(Foo()).not_to(be_an(object))
Failure
Expected <Foo object at 0x7ff289cb4310> not to be an object
be_empty¶
expect('').to(be_empty)
expect(iter('')).to(be_empty)
expect('foo').not_to(be_empty)
expect('foo').to(be_empty)
Failure
Expected 'foo' to be empty
expect(iter('foo')).to(be_empty)
Failure
Expected <str_iterator object at 0x7fd4832d6950> to be empty
expect('').to_not(be_empty)
Failure
Expected '' not to be empty
be_above¶
expect(5).to(be_above(4))
expect(1).not_to(be_above(4))
expect(1).to(be_above(4))
Failure
Expected 1 to be above 4
expect(5).not_to(be_above(4))
Failure
Expected 5 not to be above 4
be_below¶
expect(1).to(be_below(4))
expect(4).not_to(be_below(1))
expect(4).to(be_below(1))
Failure
Expected 4 to be below 1
expect(1).not_to(be_below(4))
Failure
Expected 1 not to be below 4
be_above_or_equal¶
expect(5).to(be_above_or_equal(4))
expect(5).to(be_above_or_equal(5))
expect(1).to_not(be_above_or_equal(4))
expect(1).to(be_above_or_equal(4))
Failure
Expected 1 to be above or equal 4
expect(5).not_to(be_above_or_equal(4))
Failure
Expected 5 not to be above or equal 4
expect(5).not_to(be_above_or_equal(5))
Failure
Expected 5 not to be above or equal 5
be_below_or_equal¶
expect(1).to(be_below_or_equal(4))
expect(5).to(be_below_or_equal(5))
expect(4).not_to(be_below_or_equal(1))
expect(4).to(be_below_or_equal(1))
Failure
Expected 4 to be below or equal 1
expect(1).not_to(be_below_or_equal(4))
Failure
Expected 1 not to be below or equal 4
expect(5).not_to(be_below_or_equal(5))
Failure
Expected 5 not to be below or equal 5
be_within¶
expect(5).to(be_within(4, 7))
expect(5.5).to(be_within(4, 7))
expect(1).not_to(be_within(4, 7))
expect(1).to(be_within(4, 7))
Failure
Expected 1 to be within 4, 7
expect(5).not_to(be_within(4, 7))
Failure
Expected 5 not to be within 4, 7
be_callable¶
expect(lambda: None).to(be_callable)
expect('foo').to(be_callable)
Failure
Expected 'foo' to be callable
have_len / have_length¶
expect('foo').to(have_len(3))
expect('foo').to(have_len(be_above_or_equal(3)))
expect(iter('foo')).to(have_length(3))
expect('foo').not_to(have_len(2))
expect('foo').to(have_length(2))
Failure
Expected 'foo' to have length 2
expect('foo').to(have_len(be_bellow(2)))
Failure
Expected 'foo' to have len be bellow 2
expect(iter('foo')).to(have_len(2))
Failure
Expected <str_iterator object at 0x7fd4832d6950> to have len 2
expect('foo').not_to(have_len(3))
Failure
Expected 'foo' not to have len 3
have_property¶
class Foo(object):
def __init__(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
expect(Foo(bar=0, baz=1)).to(have_property('bar'))
expect(Foo(bar=0, baz=1)).to(have_property('bar', 0))
expect(Foo(bar=0, baz=1)).not_to(have_property('foo'))
expect(Foo(bar=0, baz=1)).not_to(have_property('foo', 0))
expect(Foo(bar=0, baz=1)).not_to(have_property('bar', 1))
expect(Foo(bar=0, baz=1)).to(have_property('bar', be_below(1)))
expect(Foo(bar=0, baz=1)).to(have_property('bar', not_(be_above(1))))
expect(Foo(bar=0, baz=1)).to(have_property('foo'))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'foo'
expect(Foo(bar=0, baz=1)).to(have_property('foo', 0))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'foo' equal 0
expect(Foo(bar=0, baz=1)).to(have_property('bar', 1))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'bar' equal 1
expect(Foo(bar=0, baz=1)).to(have_property('bar', None))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'bar' equal None
expect(Foo(bar=0, baz=1)).not_to(have_property('bar'))
Failure
Expected <Foo object at 0x7ff289cb4310> not to have property 'bar'
expect(Foo(bar=0, baz=1)).not_to(have_property('bar', 0))
Failure
Expected <Foo object at 0x7ff289cb4310> not to have property 'bar' equal 0
expect(Foo(bar=0, baz=1)).to(have_property('bar', be_above(1)))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'bar' be above 1
expect(Foo(bar=0, baz=1)).to(have_property('bar', not_(be_below(1))))
Failure
Expected <Foo object at 0x7ff289cb4310> to have property 'bar' not be below 1
have_properties¶
class Foo(object):
def __init__(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
expect(Foo(bar=0, baz=1)).to(have_properties('bar', 'baz'))
expect(Foo(bar=0, baz=1)).to(have_properties(bar=0, baz=1))
expect(Foo(bar=0, baz=1)).to(have_properties('bar', baz=1))
expect(Foo(bar=0, baz=1)).to(have_properties({'bar': 0, 'baz': 1}))
expect(Foo(bar=0, baz=1)).to(have_properties(bar=be_an(int)))
expect(Foo(bar=0, baz=1)).to_not(have_properties('foo', 'foobar'))
expect(Foo(bar=0, baz=1)).to_not(have_properties(foo=0, foobar=1))
expect(Foo(bar=0, baz=1)).not_to(have_properties(foo=0, bar=1))
expect(Foo(bar=0, baz=1)).not_to(have_properties({'foo': 0, 'foobar': 1}))
expect(Foo(bar=0, baz=1)).not_to(have_properties({'foo': 0, 'bar': 1}))
expect(Foo(bar=0, baz=1)).not_to(have_properties('foo', 'bar'))
expect(Foo(bar=0, baz=1)).to(have_properties('bar', 'foo'))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'bar' and 'foo'
expect(Foo(bar=0, baz=1)).to(have_properties(bar=0, foo=1))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'bar' equal 0 and 'foo' equal 1
expect(Foo(bar=0, baz=1)).to(have_properties(bar=1, baz=1))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'bar' equal 1 and 'baz' equal 1
expect(Foo(bar=0, baz=1)).to(have_properties('foo', bar=0))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'foo' and 'bar' equal 0
expect(Foo(bar=0, baz=1)).to(have_properties('baz', bar=1))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'baz' and 'bar' equal 1
expect(Foo(bar=0, baz=1)).to(have_properties({'bar': 1, 'baz': 1}))
Failure
Expected <Foo object at 0x7ff289cb4310> to have properties 'bar' equal 1 and 'baz' equal 1
expect(Foo(bar=0, baz=1)).not_to(have_properties('bar', 'baz'))
Failure
Expected <Foo object at 0x7ff289cb4310> not to have properties 'bar' and 'baz'
expect(Foo(bar=0, baz=1)).not_to(have_properties(bar=0, baz=1))
Failure
Expected <Foo object at 0x7ff289cb4310> not to have properties 'bar' equal 0 and 'baz' equal 1
expect(Foo(bar=0, baz=1)).to(have_properties(bar=be_a(str)))
Failure
Expected <Foo object at 0x7ff289cb4310> not to have properties 'bar' be a str
have_key¶
expect({'bar': 0, 'baz': 1}).to(have_key('bar'))
expect({'bar': 0, 'baz': 1}).to(have_key('bar', 0))
expect({'bar': 0, 'baz': 1}).not_to(have_key('foo'))
expect({'bar': 0, 'baz': 1}).not_to(have_key('foo', 0))
expect({'bar': 0, 'baz': 1}).to_not(have_key('bar', 1))
expect({'bar': 0, 'baz': 1}).to(have_key('bar', be_below(1)))
expect({'bar': 0, 'baz': 1}).to(have_key('foo'))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'foo'
expect({'bar': 0, 'baz': 1}).to(have_key('foo', 0))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'foo' equal 0
expect({'bar': 0, 'baz': 1}).to(have_key('bar', 1))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'bar' equal 1
expect({'bar': 0, 'baz': 1}).to(have_key('bar', None))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'bar' equal None
expect('My foo string').to(have_key('foo', 0))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'foo' equal 0 but is not a dict
expect({'bar': 0, 'baz': 1}).not_to(have_key('bar'))
Failure
Expected {'bar': 0, 'baz': 1} not to have key 'bar'
expect({'bar': 0, 'baz': 1}).not_to(have_key('bar', 0))
Failure
Expected {'bar': 0, 'baz': 1} not to have key 'bar' equal 0
expect('My foo string').not_to(have_key('foo', 0))
Failure
Expected {'bar': 0, 'baz': 1} not to have key 'foo' equal 0 but is not a dict
expect({'bar': 0, 'baz': 1}).to(have_key('bar', be_above(1)))
Failure
Expected {'bar': 0, 'baz': 1} to have key 'bar' be above 1
have_keys¶
expect({'bar': 0, 'baz': 1}).to(have_keys('bar', 'baz'))
expect({'bar': 0, 'baz': 1}).to(have_keys(bar=0, baz=1))
expect({'bar': 0, 'baz': 1}).to(have_keys('bar', baz=1))
expect({'bar': 0, 'baz': 1}).to(have_keys({'bar': 0, 'baz': 1}))
expect({'bar': 0, 'baz': 1}).not_to(have_keys('foo', 'foobar'))
expect({'bar': 0, 'baz': 1}).not_to(have_keys(foo=0, foobar=1))
expect({'bar': 0, 'baz': 1}).not_to(have_keys(foo=0, bar=1))
expect({'bar': 0, 'baz': 1}).not_to(have_keys({'foo': 0, 'foobar': 1}))
expect({'bar': 0, 'baz': 1}).not_to(have_keys('foo', 'bar'))
expect({'bar': 0, 'baz': 1}).to(have_keys('bar', 'foo'))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'bar' and 'foo'
expect({'bar': 0, 'baz': 1}).to(have_keys(bar=0, foo=1))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'bar' equal 0 and 'foo' equal 1
expect({'bar': 0, 'baz': 1}).to(have_keys(bar=1, baz=1))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'bar' equal 1 and 'baz' equal 1
expect({'bar': 0, 'baz': 1}).to(have_keys('foo', 'fuu', bar=0))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'foo', 'fuu' and 'bar' equal 0
expect({'bar': 0, 'baz': 1}).to(have_keys('baz', bar=1))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'baz' and 'bar' equal 1
expect({'bar': 0, 'baz': 1}).to(have_keys({'bar': 1, 'baz': 1}))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'bar' equal 1 and 'baz' equal 1
expect('My foo string').to(have_keys({'bar': 1, 'baz': 1}))
Failure
Expected {'bar': 0, 'baz': 1} to have keys 'bar' equal 1 and 'baz' equal 1 but is not a dict
expect({'bar': 0, 'baz': 1}).not_to(have_keys('bar', 'baz'))
Failure
Expected {'bar': 0, 'baz': 1} not to have keys 'bar' and 'baz'
expect({'bar': 0, 'baz': 1}).not_to(have_keys(bar=0, baz=1))
Failure
Expected {'bar': 0, 'baz': 1} not to have keys 'bar' equal 0 and 'baz' equal 1
expect('My foo string').not_to(have_keys({'bar': 1, 'baz': 1}))
Failure
Expected {'bar': 0, 'baz': 1} not to have keys 'bar' equal 1 and 'baz' equal 1 but is not a dict
contain¶
expect(['bar', 'baz']).to(contain('bar'))
expect(['bar', 'baz']).to(contain('bar', 'baz'))
expect(['bar', 'baz']).to(contain('baz', 'bar'))
expect([{'foo': 1}, 'bar']).to(contain({'foo': 1}))
expect(iter(['bar', 'baz'])).to(contain('bar'))
expect(iter(['bar', 'baz'])).to(contain('bar', 'baz'))
expect('My foo string').to(contain('foo'))
expect('My foo string').to(contain('foo', 'string'))
expect(['bar', 'baz']).not_to(contain('foo'))
expect(['bar', 'baz']).not_to(contain('foo', 'foobar'))
expect(['bar', 'baz']).not_to(contain('bar', 'foo'))
expect(['bar', 'baz']).to(contain(be_a(str)))
expect(['bar', 'baz']).to(contain('bar', 'foo'))
Failure
Expected ['bar', 'baz'] to contain 'bar' and 'foo'
expect(iter(['bar', 'baz'])).to(contain('bar', 'foo'))
Failure
Expected ['bar', 'baz'] to contain 'bar' and 'foo'
expect(object()).to(contain('bar'))
Failure
Expected <object object at 0x7f5004aa1070> to contain 'bar' but is not a valid sequence type
expect(['bar', 'baz']).not_to(contain('bar'))
Failure
Expected ['bar', 'baz'] not to contain 'bar'
expect(['bar', 'baz']).not_to(contain('bar', 'baz'))
Failure
Expected ['bar', 'baz'] not to contain 'bar' and 'baz'
expect(object()).not_to(contain('bar'))
Failure
Expected <object object at 0x7f5004aa1070> not to contain 'bar' but is not a valid sequence type
expect(['bar', 'baz']).to(contain(be_an(int), have_len(5)))
Failure
Expected ['bar', 'baz'] to contain be an int and have len 5
contain_exactly¶
expect(['bar']).to(contain_exactly('bar'))
expect(['bar', 'baz']).to(contain_exactly('bar', 'baz'))
expect('My foo string').to(contain_exactly('My foo string'))
expect('My foo string').to(contain_exactly('My foo', ' string'))
expect(['bar', 'baz']).to(contain_exactly(equal('bar'), equal('baz')))
expect(['bar', 'baz']).to(contain_exactly('foo'))
Failure
Expected ['bar', 'baz'] to contain exactly 'foo'
expect(['bar', 'baz']).to(contain_exactly('foo', 'fuu'))
Failure
Expected ['bar', 'baz'] to contain exactly 'foo' and 'fuu'
expect(['bar', 'baz']).to(contain_exactly('baz', 'bar'))
Failure
Expected ['bar', 'baz'] to contain exactly 'baz' and 'bar'
expect(['bar', 'baz']).to(contain_exactly('bar'))
Failure
Expected ['bar', 'baz'] to contain exactly 'bar'
expect(['bar', 'baz', 'foo']).to(contain_exactly('bar', 'baz'))
Failure
Expected ['bar', 'baz', 'foo'] to contain exactly 'bar' and 'baz'
expect(['bar', 'baz', 'foo', 'fuu']).to(contain_exactly('bar', 'baz', 'foo'))
Failure
Expected ['bar', 'baz', 'foo', 'fuu'] to contain exactly 'bar', 'baz' and 'foo'
expect('My foo string').to(contain_exactly('foo'))
Failure
Expected 'My foo string' to contain exactly 'foo'
expect(object()).to(contain_exactly('bar'))
Failure
Expected <object object at 0x7f5004aa1070> to contain exactly 'bar' but is not a valid sequence type
expect(['bar', 'baz']).to(contain_exactly(equal('baz'), equal('baz')))
Failure
Expected ['bar', 'baz'] to contain exactly equal 'bar' and equal 'baz'
contain_only¶
expect(['bar']).to(contain_only('bar'))
expect(['bar', 'baz']).to(contain_only(['baz', 'bar']))
expect(iter(['bar', 'baz'])).to(contain_only('bar', 'baz'))
expect('My foo string').to(contain_only('My foo string'))
expect('My foo string').to(contain_only('My foo', ' string'))
expect(['bar', 'baz']).to(contain_only(equal('bar'), equal('baz')))
expect(['bar', 'baz']).to(contain_only('foo'))
Failure
Expected ['bar', 'baz'] to contain only 'foo'
expect(['bar', 'baz', 'foo']).to(contain_only('bar', 'baz'))
Failure
Expected ['bar', 'baz', 'foo'] to contain only 'bar' and 'baz'
expect('My foo string').to(contain_only('foo'))
Failure
Expected 'My foo string' to contain only 'foo'
expect(object()).to(contain_only('bar'))
Failure
Expected <object object at 0x7f5004aa1070> to contain only 'bar' but is not a valid sequence type
expect(['bar', 'baz']).to(contain_only(equal('baz'), equal('foo')))
Failure
Expected ['bar', 'baz'] to contain only equal 'baz' and equal 'foo'
start_with¶
expect('My foo string').to(start_with('My foo'))
expect('My foo string').not_to(start_with('tring'))
expect([1, 2, 3]).to(start_with(1))
expect([1, 2, 3]).to(start_with(1, 2))
expect(OrderedDict([('bar', 0), ('baz', 1)])).to(start_with('bar', 'baz'))
expect(iter([1, 2, 3])).to(start_with(1, 2))
expect([1, 2, 3]).not_to(start_with(2, 3))
expect([1, 2, 3]).not_to(start_with(1, 1))
expect('My foo string').to(start_with('tring'))
Failure
Expected 'My foo string' to start with 'tring'
expect([1, 2, 3]).to(start_with(2))
Failure
Expected [1, 2, 3] to start with 2
expect([1, 2, 3]).to(start_with(2, 3))
Failure
Expected [1, 2, 3] to start with 2 and 3
expect([1, 2, 3]).to(start_with(1, 1))
Failure
Expected [1, 2, 3] to start with 1 and 1
expect({'bar': 0, 'baz': 1}).to(start_with('bar', 'baz'))
Failure
Expected {'bar': 0, 'baz': 1} to start with 'bar' and 'baz' but it does not have ordered keys
end_with¶
expect('My foo string').to(end_with('tring'))
expect('My foo string').not_to(end_with('My foo'))
expect([1, 2, 3]).to(end_with(3))
expect([1, 2, 3]).to(end_with(2, 3))
expect(OrderedDict([('bar', 0), ('baz', 1)])).to(end_with('bar, 'baz'))
expect([1, 2, 3]).to_not(end_with(1, 2))
expect([1, 2, 3]).to_not(end_with(3, 3))
expect('My foo string').to(end_with('My fo'))
Failure
Expected 'My foo string' to end with 'My fo'
expect([1, 2, 3]).to(end_with(3, 3))
Failure
Expected [1, 2, 3] to end with 3 and 3
expect({'bar': 0, 'baz': 1}).to(end_with('baz', 'bar'))
Failure
Expected {'bar': 0, 'baz': 1} to end with 'baz' and 'bar' but it does not have ordered keys
match¶
expect('My foo string').to(match(r'My \w+ string'))
expect('My foo string').to(match(r'\w+ string'))
expect('My foo string').to(match(r'my [A-Z]+ strinG', re.I))
expect('My foo string').not_to(match(r'My \W+ string'))
expect('My foo string').not_to(match(r'My \W+ string', re.I))
expect('My foo string').to(match(pattern))
Failure
Expected 'My foo string' to match r'My \\W+ string'
expect('My foo string').not_to(match(r'My \w+ string'))
Failure
Expected 'My foo string' not to match r'My \\w+ string'
raise_error¶
def callback():
raise AttributeError('error message')
expect(callback).to(raise_error)
expect(callback).to(raise_error(AttributeError))
expect(callback).to(raise_error(AttributeError, 'error message'))
expect(callback).to(raise_error(AttributeError, match(r'error \w+')))
def callback():
raise AttributeError(2)
expect(callback).to(raise_error(AttributeError, 2))
def callback():
raise KeyError()
expect(callback).to(raise_error(AttributeError))
Failure
Expected <function callback at 0x7fe70cb103b0> to raise AttributeError but KeyError raised
expect(lambda: None).to(raise_error(AttributeError))
Failure
Expected <function <lambda> at 0x7f3e670863b0> to raise AttributeError but not raised
def callback():
raise AttributeError('bar')
expect(callback).to(raise_error(AttributeError, 'foo'))
Failure
Expected <function callback at 0x7fe70cb103b0> to raise AttributeError with message 'foo' but message was 'bar'
Aliases¶
The aliases module contains a set of matcher aliases
that are commonly used when composing matchers and are not meant
to be imported every time.
To use the aliases just import them:
from expects import *
from expects.aliases import *
expect([1, 2]).to(contain_exactly(an(int), 2))
The same code without using the an alias for the be_an matcher:
from expects import *
expect([1, 2]).to(contain_exactly(be_an(int), 2))
Custom Matchers¶
Introduction¶
Expects can be extended by defining new matchers.
The matchers module contains the bases for building
custom matchers.
Tutorial¶
The easiest way to define a new matcher is to extend the
Matcher class and override the Matcher._match()
method.
For example, to define a matcher to check if a request object contains a given header takes <10 lines of code:
from expects.matchers import Matcher
class have_header(Matcher):
def __init__(self, expected):
self._expected = expected
def _match(self, request):
if self._expected in request.headers:
return True, ['header found']
return True, ['header not found']
An then you only need to import the new defined matcher and write your expectation:
from expects import expect
from my_custom_matchers import have_header
expect(my_request).to(have_header('Content-Type'))
Advanced¶
For more complex matchers you can override the Matcher
methods in order to achieve the needed behavior.
-
class
expects.matchers.Matcher¶ The
Matcherclass is the base class for all Expects matchers.It defines a set of methods to ease writting new matchers.
-
_failure_message(subject, reasons)¶ This method will be called from an expectation only when the expectation is going to fail. It should return a string with the failure message.
By default returns a failure message with the following format:
expected: {subject} to {description} but: {reasons}
With the passed subject repr, this matcher repr as description and the passed reasons from the matcher result.
Parameters: - subject (a string) – The target value of the expectation.
- reasons (list of strings) – A list of reasons that caused this matcher to fail.
Return type: a string
-
_failure_message_negated(subject, reasons)¶ Like the
_failure_message()method but will be called when a negated expectation is going to fail. It should return a string with the failure message for the negated expectation.By default returns a failure message with the following format:
expected: {subject} to {description} but: {reasons}
Parameters: - subject (a string) – The target value of the expectation.
- reasons (list of strings) – A list of reasons that caused this matcher to fail.
Return type: a string
-
_match(subject)¶ This method will be called when the matcher is used in an expectation. It should be overwritten to implement the matcher logic. If not raises
NotImplementedError.Receives the expectation subject as the unique positional argument and should return a
tuplewith theboolresult of the matcher and alistof reasons for this result.If the matcher matches the subject then the boolean result should be
True. The reasons should be a list with 0 or more strings.Parameters: subject – The target value of the expectation. Return type: tuple (bool, [str])
-
_match_negated(subject)¶ Like
_match()but will be called when used in a negated expectation. It can be used to implement a custom logic for negated expectations.By default returns the result of negating
self._match(subject).Parameters: subject – The target value of the expectation. Return type: tuple (bool, [str])
-
-
class
expects.matchers._And(op1, op2)¶ -
_match(subject)¶ This method will be called when the matcher is used in an expectation. It should be overwritten to implement the matcher logic. If not raises
NotImplementedError.Receives the expectation subject as the unique positional argument and should return a
tuplewith theboolresult of the matcher and alistof reasons for this result.If the matcher matches the subject then the boolean result should be
True. The reasons should be a list with 0 or more strings.Parameters: subject – The target value of the expectation. Return type: tuple (bool, [str])
-
-
class
expects.matchers._Or(op1, op2)¶ -
_match(subject)¶ This method will be called when the matcher is used in an expectation. It should be overwritten to implement the matcher logic. If not raises
NotImplementedError.Receives the expectation subject as the unique positional argument and should return a
tuplewith theboolresult of the matcher and alistof reasons for this result.If the matcher matches the subject then the boolean result should be
True. The reasons should be a list with 0 or more strings.Parameters: subject – The target value of the expectation. Return type: tuple (bool, [str])
-
Testing¶
The testing module provides helpers to ease the testing
of your custom matchers.
3rd Party Matchers¶
- Tornado Expects
- Matchers for Tornado request and response objects.
- Doublex Expects
- Matchers for Doublex test doubles assertions.
- Server Expects
- Serverspec-like Expects matchers library.
Changes¶
0.9.0 (2018-10-25)¶
Highlights¶
- Fix Python 3.7 collections ABC classes deprecation warning. See GH-55 <https://github.com/jaimegildesagredo/expects/pull/55>.
- Hide
expectsinternals from pytest tracebacks. See GH-51 <https://github.com/jaimegildesagredo/expects/pull/51>.
Backwards-incompatible¶
- Dropped Python 2.6 support.
0.8.0 (2016-05-15)¶
Changes since last stable release:
Highlights¶
New failure messages for matchers. Now its easier to see the reason that caused the assertion failure. For example:
>>> expect([1, {'foo': 1}]).to(contain(have_key('foo', 2))) AssertionError: expected: [1, {'foo': 1}] to contain have key 'foo' equal 2 but: item have key 'foo' equal 2 not found
Bug fixes¶
- Now the failure message for
have_key/have_keysis fixed when composed with another matcher. See GH-29. - Allow
contain,contain_exactlyandcontain_onlymatchers to work with dict views (e.g.dict.keys()). See GH-42. - Allow
contain,contain_exactlyandcontain_onlymatchers to work with sets. See GH-38. - Show traceback in
raise_errorwhen another exception is raised. See GH-41. - The
equalmatcher now uses__ne__for negated assertions. See GH-40. - The
not_matcher now uses the inner matcher_match_negatedmethod to perform a negated assertion. - Python 2.6 support.
Backwards-incompatible¶
Although your assertions should still be working (if are broken, just report an issue), the custom matchers api has been changed. To see an example of how to migrate your custom matchers to the new api you can see the doublex-expects migration.
The
Matcher._matchmethod now should return a tuple ofboolrepresenting the result of the matcher and alistof reasons that explain this result:def _match(self, subject): if subject: return True, ['a reason'] return False, ['another reason']
The
Matcher._descriptionmethod was removed. Now, with the change announced above, a matcher description won’t need the subject to describe itself, so the__repr__magic method will be used instead to describe matchers.The
Matcher._match_valuemethod was removed. With the new api it made much less sense so it was removed and theexpects.matchers.default_matcherwrapper function was added:>>> default_matcher(1)._match(2) False, ['was 1']
0.8.0rc5 (2016-05-07)¶
0.8.0rc4 (2015-10-14)¶
0.8.0rc3 (2015-10-07)¶
0.8.0rc1 (2015-07-17)¶
Highlights¶
New failure messages for matchers. Now its easier to see the reason that caused the assertion failure. For example:
>>> expect([1, {'foo': 1}]).to(contain(have_key('foo', 2))) AssertionError: expected: [1, {'foo': 1}] to contain have key 'foo' equal 2 but: item have key 'foo' equal 2 not found
Bug fixes¶
- Now the failure message for
have_key/have_keysis fixed when composed with another matcher. See GH-29.
Backwards-incompatible¶
Although your assertions should still be working (if are broken, just report an issue), the custom matchers api has been changed. To see an example of how to migrate your custom matchers to the new api you can see the doublex-expects migration.
The
Matcher._matchmethod now should return a tuple ofboolrepresenting the result of the matcher and alistof reasons that explain this result:def _match(self, subject): if subject: return True, ['a reason'] return False, ['another reason']
The
Matcher._descriptionmethod was removed. Now, with the change announced above, a matcher description won’t need the subject to describe itself, so the__repr__magic method will be used instead to describe matchers.The
Matcher._match_valuemethod was removed. With the new api it made much less sense so it was removed and theexpects.matchers.default_matcherwrapper function was added:>>> default_matcher(1)._match(2) False, ['was 1']
0.7.0 (2015-06-26)¶
0.7.1 (2015-06-09)¶
0.7.0 (2015-03-01)¶
Highlights¶
Added
have_lenas an alias tohave_length.The
have_lenandhave_lengthmatchers can receive another matcher as expected value:expect('foo').to(have_len(be_above(2)))
The
containandcontain_exactlymatchers now can receive another matchers as arguments:expect(['foo', 'bar']).to(contain(be_a(str))) expect(['foo', 'bar']).to(contain_exactly(be_a(str), match('\w+')))
Improved
be_aandbe_anfailure messages.Added the
contain_onlymatcher:expect([1, 2]).to(contain_only(2, 1))
Added the
to_notalias fornot_toto negate assertions:expect(True).to_not(be_false)
Added the aliases module with matcher aliases useful to compose matchers:
from expects import * from expects.aliases import * expect([1, 2]).to(contain_exactly(an(int), 2))
Backwards-incompatible¶
The
failurecontext manager now uses theend_withmatcher as default matcher for failure message instead of the previously usedcontainmatcher. Example:>>> from expects.testing import failure >>> with failure('foo'): ... raise AssertionError('A foo message') AssertionError: Expected message 'A foo message' to end with 'foo' >>> with failure('message'): ... raise AssertionError('A foo message')
0.6.2 (2014-12-10)¶
Bug fixes¶
- Fixed
contain_exactlyto work with iterable objects. Regression introduced in v0.6.1.
0.6.1 (2014-11-30)¶
0.6.0 (2014-11-24)¶
Highlights¶
Now the
raise_errormatcher can be used without specifying an exception class for writing less strict assertions:expect(lambda: foo).to(raise_error)
Implemented the
Matcher._match_valuemethod to help develop custom matchers that receive another matchers. See the docs for more info.The
specsanddocsdirectories are now distributed with the source tarball. See GH-20.
0.5.0 (2014-09-20)¶
Highlights¶
Now the
&and|operators can be used to write simpler assertions:expect('Foo').to(have_length(3) & start_with('F')) expect('Foo').to(equal('Foo') | equal('Bar'))
The
testing.failurecontext manager can be used even without calling it with the failure message as argument:with failure: expect('foo').to(be_empty)
Also can receive matchers as argument:
with failure(end_with('empty')): expect('foo').to(be_empty)
Note
See also backwards-incompatible changes for testing.failure.
- Added the
be_callablematcher. - Published a list of 3rd Party Matchers libraries.
Bug fixes¶
- The
be_withinmatcher now supports float values. - In some places
byteswere not being treated as a string type in python 3.
Backwards-incompatible¶
- The
matchmatcher now passes if matches a part of the subject string instead of all of it. Previously used there.match()and now usesre.search(). If your tests depended on this you can migrate them by adding a'^'and'$'at the beginning and end of your regular expression. - The
testing.failurecontext manager not longer tries to match regular expressions. Instead you can pass thematchmatcher with your regexp.
0.4.2 (2014-08-16)¶
Highlights¶
- Added the
not_matcher to negate another matcher when composing matchers.
0.4.1 (2014-08-16)¶
Bug fixes¶
- Now
from expects import *only imports theexpectcallable and built in matchers.
0.4.0 (2014-08-15)¶
Warnings¶
This release does not maintain backwards compatibility with the previous version because a new syntax was implemented based on matchers. Matchers have been implemented maintaining compatibility with its equivalent assertions (and those that break compatibility are listed below). For most users upgrade to this version will only involve a migration to the new syntax.
Highlights¶
- Improved failure message for
have_keysandhave_propertiesmatchers. - The
raise_errormatcher now can receive any other matcher as the second argument.
Bug fixes¶
- The
have_keyandhave_keysalways fail if the subject is not a dict. - Fixed
containmatcher behavior when negated. See this commit.
Backwards-incompatible¶
- The
end_withmatcher should receive args in the right order and not reversed. See this commit. - The
to.haveandto.have.onlyassertions have been remamed tocontainandcontain_exactlymatchers. - Assertion chaining has been replaced by matcher composition in all places where was possible in the previous version.
- The
testing.failurecontext manager now only receives a string matching the failure message.
0.3.0 (2014-06-29)¶
Highlights¶
- The start_with and end_with assertions now support lists, iterators and ordered dicts. GH-16.
0.2.3 (2014-06-04)¶
Highlights¶
- Added the start_with and end_with assertions. GH-14.
0.2.2 (2014-05-20)¶
0.2.1 (2014-03-22)¶
Highlights¶
- Added a testing module with the failure contextmanager.
- Added a matchers module and the key matcher.
Bug fixes¶
- to.have and to.only.have now work properly when actual is a string.
0.2.0 (2014-02-05)¶
Highlights¶
- Added initial plugins support. See plugins docs for more info.
- The
keyandpropertyexpectations now return a newExpectsobject that can be used to chain expectations. - Now every expectation part can be prefixed with
not_in order to negate an expectation. Ex:expect('foo').not_to.be.emptyis the same thanexpect('foo').to.not_be.empty. - Added the
only.haveexpectation to test that the subject only has the given items.
Backwards-incompatible¶
- The
greater_than,greater_or_equal_to,less_thanandless_or_equal_toexpectations are renamed toabove,above_or_equal,belowandbelow_or_equal.