[TIP] testing-in-python Digest, Vol 80, Issue 19
cjjones at pixar.com
Thu Sep 19 13:46:16 PDT 2013
Some of this I am already doing, some of it I did a certain way because
I was experimenting trying to see if it made a difference, some of it I
did not know so thank you very much. My comments and a couple of follow
up questions are inline.
On 09/18/2013 08:47 PM, testing-in-python-request at lists.idyll.org wrote:
> Send testing-in-python mailing list submissions to
> testing-in-python at lists.idyll.org
> To subscribe or unsubscribe via the World Wide Web, visit
> or, via email, send a message with subject or body 'help' to
> testing-in-python-request at lists.idyll.org
> You can reach the person managing the list at
> testing-in-python-owner at lists.idyll.org
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of testing-in-python digest..."
> Today's Topics:
> 1. Re: mock object not being used? (Ben Finney)
> 2. Fwd: mock object not being used? (Christine Jones)
> Message: 1
> Date: Thu, 19 Sep 2013 13:34:51 +1000
> From: Ben Finney <ben+python at benfinney.id.au>
> Subject: Re: [TIP] mock object not being used?
> To: testing-in-python at lists.idyll.org
> Message-ID: <7wa9j9xz50.fsf at benfinney.id.au>
> Content-Type: text/plain; charset=utf-8
> Christine Jones <cjjones at pixar.com> writes:
> I have some comments on your style that will hopefully make your code
> more maintainable.
>> # READ - GET signups - 200 (assumes > 0 signups)
>> def test_signups_get(self):
> Each test case (that is, each function in a unit test) should be named
> for the single assertion it is making about the code. That way, the name
> of the failed test says exactly what expected behaviour was not
> Yes, this entails that *separate assertions need to be in separate test
> cases* (i.e. in separate ?test_foo? functions), to ensure that they can
> pass or fail independently. You may already be doing this; if not, early
> is better to learn than later.
> In this case, you're asserting that the result contains ?cjjones? in the
> data. To name the test case, we need to describe what the semantic
> meaning of this behaviour is. Perhaps ?The data should contain the first
> player's username?::
> def test_data_contains_username_of_first_player(self):
> """ The data should contain the first player's username. """
> (I like to write the docstring as an admonition; that way, it makes
> sense when it appears in the test report, regardless of whether the test
> passes or fails.)
I am only asserting once per test so won't have to change anything there
to put this naming convention in place. I like the idea.
>> today = datetime.datetime.now()
>> from lunchlottoweb import models
> Don't import like this inside a function. Instead, import the necessary
> modules at the top of your unit test module.
I saw this in a mock tutorial and tried it. I do generally import at the
top and will stick to that. Thanks for the correction.
>> with patch.object(models, "LottoPlayer") as MockLottoPlayer:
>> players = [NonCallableMock(employeelogin='cjjones', employeedept='systems', signupdate=today, lottowinner=False),
>> NonCallableMock(employeelogin='dlovrn', employeedept='systems', signupdate=today, lottowinner=False)]
> If you want to make use of these instances for numerous test cases ?
> which I advise ? then use the ?setUp? method of the TestCase classes to
> set a test data attribute on each test case.
That makes sense if I want to use the same instance for all my
functions, but one of my test cases is to test when there are no
players, i.e. players is empty. Can I still do it this way and override
the players value set in the setup method with a function-specific
players value? I wasn't creating the patch in the TestCase setup model
because I thought it would lock me into using the same players values in
all my functions.
>> MockLottoPlayer.all = players
>> request = MagicMock(name='signups_multiple_exist')
>> r = self.app.get('/signups')
>> assert 'cjjones' in r.data
>> My function:
>> # admin page: today's signups
>> @app.route('/signups', methods=['GET'])
>> def signups():
>> today = date.today()
>> players = LottoPlayer.query.filter(cast(LottoPlayer.signupdate, Date) == today).distinct(LottoPlayer.employeelogin).all()
>> player_count = players.__len__()
>> if player_count > 1:
> There's no need to call this magic method directly. Instead, use the
> built-in ?len? function::
> if len(players) > 1:
Thanks for this will fix.
>> return render_template("signups_today.html", signups=players)
>> return render_template("signups_today.html")
A general question about this code. I am trying to test both conditions
and whether using mock or not, am only able to test one at a time. I am
using two separate tests, one for each branch of the logic. Any idea why
I am not able to do this? I must be overlooking something obvious.
Thanks again for all the feedback here.
P I X A R
More information about the testing-in-python