garybernhardt / expecter Goto Github PK
View Code? Open in Web Editor NEWExpecter Gadget: better expectations (assertions) for Python.
Expecter Gadget: better expectations (assertions) for Python.
I am converting an application to Python 3. This involves adding a lot of
assert isinstance(variable, bytes)
. Sadly, the type is not printed when the assertion fails. Sounds like a perfect match for expecter, you agree? :)
Proposed syntax:
expect(variable).is_instance_of(bytes)
This really sucks for multi-line strings. Example:
>>> expect("foo\nbar") == 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.6/site-packages/expecter-0.2.1-py2.6.egg/expecter.py", line 18, in __eq__
'Expected %s but got %s' % (repr(other), repr(self._actual)))
AssertionError: Expected 0 but got 'foo\nbar'
I like this library and bookmarked it a while ago. I was gonna use it just now but realize the only thing holding me back is that expect
does not enable me to write a message about the assert in question, like assert
does. My question is, two-fold:
I'd love to hear your thought about this.
Imported from BitBucket:
Reported by Kumar McMillan / kumar303, created 2 days ago.
it would be pretty sweet if the expect object supported in() so you could get nice messages for substring expectations. Would need unicode support too (thar be dragons).
eg.
>>> expect('foo') in 'foozilate'
>>> expect('を') in 'ページを閲覧中にクリック一つで使える豊富な開発ツールを'
Gary Bernhardt / garybernhardt
I've thought about the containment issue quite a bit. That syntax won't work because there's not an in, only a contains. In your example, 'foozilate'.contains will be called and there's nowhere to hook an assertion in.
We could define contains to at least make expect() work on the RHS, but that breaks the fundamental rule of Expecter Gadget, which is that you always put the actual value in expect() and it always starts the line. :)
I think my preferred solution is to add predefined, named expectations: maybe "expect('foozliate').to_contain('foo')" and "expect('foo').to_be_in('foozilate')" or something like that. I haven't done it because I haven't found names that seem right yet, though.
Kumar McMillan / kumar303
ohhh, I didn't realize it needs __contains__
on the target. Hmm I also didn't realize the the argument to expect() should be the actual value, that makes sense. I always use this mess of code but it's stupid:
s = 'foozilate'
assert 'foo' in s, ('Unexpected: %r' % s)
So per your comments my vote is for:
expect(user.description).contains('foo')
PS. I forgot about expecter until your tweet! It's nifty.
Since I am assuming you are not planning to support Python versions lower then 2.6 this project should move to nose2 which is based on unittest2.
I can do it if you wish.
I would like to use expecter
along with py.test
(and https://github.com/ropez/pytest-describe), but it seems that py.test
thinks the call to expect()
is part of my code and thus shows me the code around the assert
statement within expector
as "context" for the failure:
___________ describe_template.describe_get_path.returns_default_when_no_style ____________
template = <memegen.domain.template.Template object at 0x102767390>
@patch('os.path.isfile', Mock(return_value=True))
def returns_default_when_no_style(template):
> expect(template.get_path()) == "abc/default2.png"
memegen/test/test_domain_template.py:24:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = expect('abc/default.png'), other = 'abc/default2.png'
def __eq__(self, other):
msg = 'Expected %s but got %s' % (repr(other), repr(self._actual))
if (isinstance(other, basestring) and
isinstance(self._actual, basestring)):
msg += normalized_diff(other, self._actual)
elif len(repr(self._actual)) > 74:
msg += normalized_diff(pprint.pformat(other),
pprint.pformat(self._actual))
> assert self._actual == other, msg
E AssertionError: Expected 'abc/default2.png' but got 'abc/default.png'
E Diff:
E @@ -1 +1 @@
E -abc/default2.png
E +abc/default.png
env/lib/python3.5/site-packages/expecter.py:55: AssertionError
Ideally, this these lines:
self = expect('abc/default.png'), other = 'abc/default2.png'
def __eq__(self, other):
msg = 'Expected %s but got %s' % (repr(other), repr(self._actual))
if (isinstance(other, basestring) and
isinstance(self._actual, basestring)):
msg += normalized_diff(other, self._actual)
elif len(repr(self._actual)) > 74:
msg += normalized_diff(pprint.pformat(other),
pprint.pformat(self._actual))
> assert self._actual == other, msg
would be hidden and/or replaced with introspection into the actual code that caused the failure.
Is there a way to "teach" py.test
that expector.expect()
is also test code (that produces its own assertion information)?
Would allow for this:
@expecter.expectation
def can_meow(o):
assert o == 'thing
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.