-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use py.test for tests #384
Conversation
@@ -44,13 +44,13 @@ before_install: | |||
install: | |||
- pip install -U setuptools pip | |||
- pip install unittest2 mock pycurl flake8 tox-travis coveralls | |||
- pip install pycurl flake8 coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tox-travis
was useless as we don't use tox to run tests on Travis.
pytest
and any additional test modules will be installed when running python setup.py install
, so no need to install them manually before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to see this cleaned out.
@@ -102,6 +102,10 @@ def __init__(self, timeout=80, session=None, **kwargs): | |||
self._timeout = timeout | |||
self._session = session or requests.Session() | |||
|
|||
def __del__(self): | |||
if self._session: | |||
self._session.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under Python 3, requests will sometimes return ResourceWarning
s after execution (cf. psf/requests#1882). There are some tests where we explicitly catch and count warnings (to check that we're raising DeprecationWarning
s) and this bug/feature was interfering with the tests.
It's apparently not great practice to close resources in destructors, but it does fix the tests and I suppose it's better than doing nothing at all.
This should not be related to pytest though and I'm not entirely sure why we never ran into this issue before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure either, but certainly a problem :$ This looks strictly better than what we had before. Unfortunately the "real" solution is probably to implement our own close
method for users to call into manually.
tox.ini
Outdated
# is not agnostic when asserting that a method was called with positional vs. | ||
# keyword arguments. | ||
# Once we drop support for Python 3.3, we can safely remove this line. | ||
mock_use_standalone_module = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, pytest-mock will use the mock
module that comes with the stdlib in Python 3. However, as the comment explains, in 3.3 the assert_called_with
method is not agnostic when checking for positional vs. keyword arguments, which was causing our assert_requested
method to fail for some tests depending on how api_requestor.request
was called.
To fix this, I added the mock
pypi module to setup.py for Python<=3.3 and the configuration line above.
I'd rather drop support for 3.3 entirely though and get rid of this workaround.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation and leaving the comment in here (the code).
This is great OB. Such a huge amount of work too! LGTM. Two questions:
|
Yep! Here's how it looks like:
For our custom
Before the error message, pytest also outputs the body of the method where the failed assertion happened. Unfortunately, for our |
I've updated the README as well. |
Thanks Olivier! Explanations sounds reasonable to me. I just restarted one of the Travis jobs from what looked like an intermittent failure, but I'd say this is good to come in if you want to strip the WIP tag and merge it. |
Actually, there's a small issue with the PR in its current state. CI tests work because Travis environments for 2.6 and 3.3 come pre-installed with a pytest version that is still compatible with these Python versions, so running However, when using a clean environment, We could fix this with a bit of code in |
Actually, after writing the above I think that freezing pytest to 3.2.5 is actually a decent short-term fix. It would let us merge this PR and work on dropping support for deprecating versions separately. I'll amend the commit with this fix and remove the WIP tag. |
😠 Okay, this is more complex than I expected. Something must be different in the way pytest instantiates and deletes object in 3.2.5, because now tests on Python 3.4 are failing because of the Going to dig a bit more. Re-tagging as WIP for now. |
667948d
to
a1026ad
Compare
Alright, I've updated the merge target to |
r? @brandur-stripe
cc @stripe/api-libraries
Apologies for yet another big PR 😭 (although the overall line count is negative, which is always nice)
This PR replaces the unittest2 test framework with pytest, which is more modern and the current state of the art in Python.
Some advantages of using pytest:
assert
keyword (no more non-PEP8-compliantself.assertSomething
methods)Although many lines of code were changed, most modifications are fairly simple:
SomethingTests
classes toTestSomething
. This is necessary so that pytest can discover tests automatically, and has the nice side-effect of making the test class name better match the file nameself.assertSomething
calls to regularasserts
request_mock
instance used for stripe-mock tests is now a pytest fixture, and is injected as such into every test method that uses itmock
is no longer used directly, but rather through thepytest-mock
plugin which adds amocker
fixturetests/helper.py
was moved totests/conftest.py
(this is where pytest expects to find global fixtures)Some of the tests (notably
test_api_requestor.py
andtest_http_client.py
) required some deeper changes. In particular, any helper method that manipulates fixtures needs to be converted to a fixture itself, with the fixture method returning the "regular" helper method (e.g. here). There might be a better way to handle this, maybe by using pytest's parametrization feature.Although all tests are passing and I believe that the PR could be merged as-is, I've tagged it as WIP as I wonder if we should wait to drop support for Python 2.6 and 3.3 beforehand, as the latest versions of pytest and its plugins no longer support those Python versions.