-
Notifications
You must be signed in to change notification settings - Fork 262
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
Migrate to pytest #1149
Migrate to pytest #1149
Conversation
for import test, extract a local fixture
Here it is! |
Thanks for working on this. What's the rationale for moving to pytest-style tests? Honestly, I find pytest fixtures a bit confusing. From what I understand, pytest understands unitttest-style tests, so we can just keep using that? Btw, does pytest have native support for MagicMock and patch? |
Ah, we need an explanation/discussion/debate. Good! fixtures are reusable Now, the main disadvantage for me are the following implicit behavior:
Honestly, for now, I took the lazy approach: don't modify every existing tests, since they use a class and MagickMock and patch: as far as I know, nothing like this exist in pytest. They have a module for monkeypatching, but the one from unittest is far more useful in my opinion, so I'll stick to that. Since |
Yeah, I don't like implicit fixtures. If we do move to pytest, we should document/enforce that we only use explicit fixtures (like the code you propose here) I don't understand why you need to wrap some test code with a |
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.
Hey, looks good to me! I'm glad to see the tests are moving a bit. I guess they could be refactored a lot and reworked to be simpler now.
I approve the changes. I've a few comments about the docs, because I feel it would be clearer this way. Happy to go use pytest now rather than the old unittest way.
@@ -144,6 +144,18 @@ If you are introducing a new feature, you need to either add tests to | |||
existing classes, or add a new class (if your new feature is | |||
significantly different from existing code). | |||
|
|||
#### Old tests and new tests |
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.
Nit: you need a newline before the paragraph starts.
possible to pytest fixtures. However, a lot of tests were already written, | ||
and are still using class-based tests, albeit without setUp()/teardown(). | ||
|
||
If you write new tests, please **try to write them with pytest in mind**: |
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.
Seems to be missing a newline here as well.
Historically, tests were written with unittest and Flask-Testing. | ||
Because the latter was dying, we removed it and switch as much as | ||
possible to pytest fixtures. However, a lot of tests were already written, | ||
and are still using class-based tests, albeit without setUp()/teardown(). |
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.
put the method names within backticks for formatting.
and are still using class-based tests, albeit without setUp()/teardown(). | ||
|
||
If you write new tests, please **try to write them with pytest in mind**: | ||
- standalone function (not in class) |
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.
Maybe a sentence would be better, like "tests are done in standalone functions rather than in class and class methods".
|
||
If you write new tests, please **try to write them with pytest in mind**: | ||
- standalone function (not in class) | ||
- plain asserts |
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.
Use plain assert
rather tha this.assertTrue
, for instance.
@@ -144,6 +144,18 @@ If you are introducing a new feature, you need to either add tests to | |||
existing classes, or add a new class (if your new feature is | |||
significantly different from existing code). | |||
|
|||
#### Old tests and new tests | |||
Historically, tests were written with unittest and Flask-Testing. |
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.
Rather than starting by explaining how it was in the past, it might be better to explain how it's supposed to be now, and then explain why we have legacy code around. Maybe something like :
Tests are now using pytest. However, [...].
@@ -119,6 +119,7 @@ def test_invite(self): | |||
resp = self.client.get("/raclette/join/token.invalid", follow_redirects=True) | |||
self.assertIn("Provided token is invalid", resp.data.decode("utf-8")) | |||
|
|||
@pytest.mark.usefixtures("app_ctx") |
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.
Is there a way to avoid repeating this line every so often?
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.
I would recommend having a look at pytest-flask. I think this is not documented, but this allows among other things to access the flask app context directly in the tests (without with app.app_context(): ...
yield | ||
|
||
|
||
@pytest.fixture |
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.
I'm not sure if it's possible with pytest, but any chance this could be in the same file as the tests?
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.
conftest.py
is the place for shared fixtures, but pytest allows to define fixtures in test files 👌
|
||
|
||
class BaseTestCase(TestCase): | ||
@pytest.mark.usefixtures("client", "converter") | ||
class BaseTestCase(unittest.TestCase): |
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.
Inherinting from unittest.TestCase
is not required with pytest.
https://docs.pytest.org/en/7.1.x/getting-started.html#group-multiple-tests-in-a-class
However requires following the class naming convention (start test class names with Test
) and abandon unittest assertions self.assert*
. For this unittest2pytest can be useful.
Any reason why sticking to |
No, there are no reason. If we are to decide to go the pytest way, I believe it's just a migration we have to do, but which is not done yet. @zorun, you seem to be a against using pytest. Would that be a big problem for you? Is it mainly a problem with fixtures? On my side, I don't have a strong opinion about this. I like pytest and have been using it in other projects without trouble. I would feel more confortable with it, but I can also keep things as they currently are. |
I'm not strongly opposed to pytest, I just don't like implicit fixtures. If we can avoid them, then let's move to pytest. The other thing I find really strange is the need for the app_context sometimes, but @azmeuk mentioned that pytest-flask should solve this point. More work for @Glandos I guess :D |
Fix #1148
Well for now, this is just experiment, but showing good signs of success.