Skip to content
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

Go all-in on using pytest instead of unittest in docs, examples, etc #1110

Closed
benhoyt opened this issue Jan 17, 2024 · 12 comments
Closed

Go all-in on using pytest instead of unittest in docs, examples, etc #1110

benhoyt opened this issue Jan 17, 2024 · 12 comments
Assignees
Labels
docs Improvements or additions to documentation small item

Comments

@benhoyt
Copy link
Collaborator

benhoyt commented Jan 17, 2024

Pytest really makes writing tests a lot lighter and easier-to-read with plain functions and assert foo == bar rather than self.assertEqual(foo, bar). Exemplify this in our SDK docs, API reference docs, charmcraft init templates examples, and so on.

@benhoyt benhoyt added docs Improvements or additions to documentation small item labels Jan 17, 2024
@Batalex
Copy link

Batalex commented Feb 27, 2024

I chatted with Ben, and I'll get started on this issue!

@Batalex
Copy link

Batalex commented Feb 27, 2024

Progress tracker:

@benhoyt
Copy link
Collaborator Author

benhoyt commented Feb 28, 2024

Cool, looks like a good start. We'll cast our eyes over those PRs. Can you please add a note or link about why #4 is blocked by charmcraft? Or is that just referring to the charmcraft init template PR?

@sed-i
Copy link
Contributor

sed-i commented Feb 28, 2024

I am not too familiar with pytest but I think there's a subtle difference we need to keep in mind:

  • With unittest, by instantiating harness inside setUp, we will always have the same "state", even when we ask the test runner to run one single test method from a test class.
  • With pytest and autouse fixtures this could be a tricky detail. And what would happen if a test file is taking the "rolling changes" approach, and then the user asks the test runner to run only a given test method?

@tonyandrewmeyer
Copy link
Contributor

  • With unittest, by instantiating harness inside setUp, we will always have the same "state", even when we ask the test runner to run one single test method from a test class.
  • With pytest and autouse fixtures this could be a tricky detail.

Creating a Harness object in setUp gives a fresh object for each test, so is the same as scope='function' in pytest. If anyone is creating a Harness in setUpClass that's probably questionable but I would imagine you'd rewrite it using scope=module.

I'm not sure how this ends up being a tricky detail - it's essentially the same behaviour. Am I missing something here?

And what would happen if a test file is taking the "rolling changes" approach, and then the user asks the test runner to run only a given test method?

Can you explain what the "rolling changes" approach is?

@sed-i
Copy link
Contributor

sed-i commented Feb 28, 2024

Right, fixtures have scope. In that case do we want to encourage function scope in the templates?

Module scope is the "rolling changes" approach: in one test function you add a relation, and it is still there in the next test function. Can get messy.

@benhoyt
Copy link
Collaborator Author

benhoyt commented Feb 28, 2024

@sed-i It looks like function scope is the default, right, so as I understand it that's what the suggested templates propose?

@tonyandrewmeyer
Copy link
Contributor

Module scope is the "rolling changes" approach: in one test function you add a relation, and it is still there in the next test function. Can get messy.

How are you doing this with unittest? With setUpClass or setUpModule? It seems like it would be just as messy with those, and some sort of "set up my relations" helper function would be much safer.

@sed-i
Copy link
Contributor

sed-i commented Mar 1, 2024

  • For some reason I though module scope is the default. Function scope as default is great.
  • With unittest I do not use setUpClass or any equivalent of module scope, precisely because it is messier.

I'm very curious to see how utests with pytests could look like. On one hand, it's much easier to use hypothesis with pytest. On the other hand, pytest is notorious for having too much hidden magic.

lengau pushed a commit to canonical/charmcraft that referenced this issue Mar 1, 2024
Related to canonical/operator#1110.

I kept the changes as minimal as possible.

---------

Co-authored-by: Alex Batisse <alex.batisse@canonical.com>
@Batalex
Copy link

Batalex commented Mar 4, 2024

TBH, the hidden magic is a big part of why I like pytest. Though side effects from hidden fixtures can be a pain to debug, I agree.

@benhoyt
Copy link
Collaborator Author

benhoyt commented Mar 5, 2024

@Batalex I'm with @sed-i here. I really like pytest's simple use of assert (and automatic assert introspections for good output), but I can't stand the magic. Reason: automatically wiring things up makes code hard to follow. I've been confused by this many times when looking at codebases -- I once had to debug some pytests with four or five layers of fixtures depending on each other, some of which were in conftest.py, which is imported automagically. Especially with conftest.py and autouse=True, pytests executes code implicitly without any wiring in sight.

On my "articles to write" list I have this suggestion: write about my love-hate relationship with pytest - assert and test finding, yes! Magical fixtures wired up by name, no thanks! conftest.py and autouse=True, double no thanks!

Maybe I'll write that article someday. I wish there was something like pytest but without those magical features. :-)

mattculler pushed a commit to canonical/charmcraft that referenced this issue Mar 6, 2024
Related to canonical/operator#1110.

I kept the changes as minimal as possible.

---------

Co-authored-by: Alex Batisse <alex.batisse@canonical.com>
@tonyandrewmeyer
Copy link
Contributor

Thanks for all the work on this @Batalex !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to documentation small item
Projects
None yet
Development

No branches or pull requests

4 participants