[TIP] testing-in-python Digest, Vol 80, Issue 19

Christine Jones cjjones at pixar.com
Thu Sep 19 13:46:16 PDT 2013


Ben,
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
> 	http://lists.idyll.org/listinfo/testing-in-python
> 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
> satisfied.
>
> 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)
>>    else:
>>        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.

-- 
Christine
P I X A R




More information about the testing-in-python mailing list