[pytest-dev] document outlining added values
Craig de Stigter
craig.ds at gmail.com
Tue Dec 4 15:37:27 EST 2018
Wow, I sure wish I'd found that earlier. I swear I'd been looking for this
for years before I started writing my own :) That said, I've learned an
awful lot by writing my own; I wouldn't have been able to do the GDAL
conversion without writing that first.
Sivan, I'm sorry for misinterpreting your original post and (inadvertently)
derailing your thread :) I'll try to answer the original question.
We converted our unittest/django test suite to pytest style over the last
few years (recently very quickly as a result of this conversion script).
Here's a list of advantages we've seen. Some of these are to do with the
pytest *runner* and some are to do with the particular style of pytest
tests themselves.
Syntactical advantages:
- assertion syntax is more pythonic (less camelCase)
- assertion syntax is less verbose, and equally if not more readable
- assertion *messages* are rarely required with pytest, because it
prints the sub-expressions of the expressions used in the assert statement.
Function-based test advantages:
- With a large enough test suite, each test case class becomes a woolly
maze of multiple inheritance with mixins. We found this more confusing than
the explicit dependency injection that pytest's fixtures offer
- Having all functions in TestCase class objects makes it annoying to
run a *particular* test; you have to type the classname as well as the
module and test function name
Performance:
- Not *exactly* related but: Django's XML/JSON fixture files are
terribly slow to load (or at least, were when I last checked, probably
about django 1.8). XML was better than JSON but neither approach the speed
you can get by creating objects manually via the ORM. Moving to pytest was
a good opportunity to move these fixture files into pytest fixtures using
the Django ORM. (Note: there are other ways to avoid this - you could use
factory_boy or something and avoid django fixture files)
Customisation:
- We've found it much easier to extend the functionality of our test
suite. For example, recently we added a new version to our API (all
`/api/v1/endpoint/` things can be accessed via `/api/v2/endpoint/` too
now). We trivially parametrized our test-client fixture, to run all API
tests against both endpoints, and transparently rewrite the version numbers
in the URLs. This wouldn't have been easily possible with a standard django
test suite.
- Pytest makes it easy to run fixtures with different scopes, whereas
unittest-based testing assumes all setup happens for a particular class or
function. In particular, session-scope fixtures allow us to do setup once
for the whole test run.
- It's easy to setup things *by default*. For example, we wanted to
*remove* access to our storage volume during tests by default, so that
we could verify that nothing touched it that didn't *need* to. This was
easy with pytest - we just created an autouse fixture that runs before each
test and ensures the storage volume is unavailable. The fixture is removed
during `pytest_collection_modifyitems` if a particular marker is present to
say a test needs storage access.
- It's easy to customise what tests will be run, either with custom
command-line flags, environment variables, or whatever you want. Just add a
pytest_collection_modifyitems hook and tweak the list. You can skip tests,
reorder tests, add fixtures, add markers... whatever you want. I don't know
if this is even possible with the django test runner without heavy patching.
I hope that's helpful. Switching to pytest has been a real breath of fresh
air and has greatly accelerated our *desire* to write tests, which I think
is important. It makes testing less of a drag, and maybe even fun :)
Craig de Stigter
Platform Engineer @ https://koordinates.com
On Wed, 5 Dec 2018 at 01:12 Florian Bruhin <me at the-compiler.org> wrote:
> On Tue, Dec 04, 2018 at 12:54:50AM +0000, Craig de Stigter wrote:
> > > gradually porting all tests
> >
> > Mostly-automated conversion is possible, so it doesn't have to be a
> gradual
> > process.
> >
> > I wrote a script which converts xunit-style assertions into pytest ones:
> > https://github.com/craigds/decrapify/blob/master/pytestify.py
>
> Yet another one? ;-)
>
> https://github.com/pytest-dev/unittest2pytest
> https://github.com/dropbox/dbx-unittest2pytest
>
> Florian
>
> --
> https://www.qutebrowser.org | me at the-compiler.org (Mail/XMPP)
> GPG: 916E B0C8 FD55 A072 | https://the-compiler.org/pubkey.asc
> I love long mails! | https://email.is-not-s.ms/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pytest-dev/attachments/20181205/a08c85a4/attachment.html>
More information about the pytest-dev
mailing list