[TIP] Learning testing and TDD: unittest or PyTest or ?

boB Stepp robertvstepp at gmail.com
Sat Sep 24 08:53:27 PDT 2016


This is a spinoff of questions I asked on Python Tutor.  The link to
my original post is:
https://mail.python.org/pipermail/tutor/2016-September/109686.html

In that thread, Ben Finney wrote:

<QUOTE>
boB Stepp <robertvstepp at gmail.com> writes:

> What I struggled with was getting tests to run for ALL of the data.
> Until I found subTest in the docs, the tests would stop with the FIRST
> failure, whereas I wanted to see ALL failures and passes. That is, I
> wanted to exercise all of the data inputs and see the collected
> results.

The ‘testscenarios’ third-party package is designed for this
<URL:https://pypi.python.org/pypi/testscenarios/>.

You define “scenarios” of data to apply to each of the test case
functions in a class; the ‘testscenarios’ magic is then to multiply
those functions, at run time, by each of the scenarios. A separate test
case will be generated for each combination, with its own distinct
result reported in the test run.
</QUOTE>

If I continue my learning via unittest, this looks to provide a route
to doing what I wanted to do as per the above cited thread.

OTOH, Walter Prins wrote in response to my questions:

<QUOTE>
[snip]

And the way to do this when using the unittest framework is as Benn's
[sic] described.

I'd however suggest at this stage to not get stuck in the minutiae of
how to write fully generalized tests, and to simply write separate
test cases (seperate def's) with different data, to keep your focus on
learning TDD rather than learning the ins and outs of unittest, if you
find yourself falling down some kind of test framework learning rabbit
hole.

That said, I would suggest perhaps consider using Py.Test instead of
unittest, which is arguably much "lower friction" with less
overhead/boilerplate/ceremony required.  With Pytest, tests can be
defined via simple functions if you wish, and checks may be performed
with simple asserts if you like.  PyTest will also collect all test
functions automatically wherever they may exist, based on its
conventions.

It is therefore possible to start really simply with any code you
write, and have test functions defined alongside the code you're
writing without any explicit reference/dependency on the test
framework, which allows a very easy way of getting started.  Obviously
you can keep the tests in a separate module if you prefer, and/or make
use of the infrastructure provided by the test framework (base
classes, decorators etc) if you like or need them, but this is not
obligatory and hence makes a very direct style of getting started
possible (hence "low friction")

The kind of parameterization you want can be more compactly and simply
achieved with PyTest attributes, as follows below...
</QUOTE>

I have thought about PyTest off and on and actually had installed it
earlier this week to play around with it.  It does seem much more
intuitive and straightforward than unittest.  OTOH, I don't want to go
an "easy" route and miss out on useful learning opportunities if that
is what unittest will provide me.  But I have been striving while
learning to respect and implement DRY principles and I really don't
want to write repetitive test code, which essentially does exactly the
same thing, just with different inputs.  And I can see myself wanting
to exercise tests with a variety of test data, perhaps stored in
file(s) for any substantial project I envision.  So if I continue in
unittest-land I would have to adopt Ben's suggestion.

So, for now, my emphasis is on "learning".  I am currently trying to
learn multiple things:  Python in general, OOP, TDD, CSc concepts,
using Vim, Git, and any other needed software with their details of
use to support these stated learning objectives.  In light of this,
what would you advise?

TIA!
-- 
boB



More information about the testing-in-python mailing list