insomnihack

When sleep eludes, the keyboard beckons

Run Coverage.py under PyCharm

July 18, 2010 Dale Leave a Comment

PyCharm‘s test runner does not currently support running Ned Batchelder’s excellent Python code coverage tool coverage.py. While this may be addressed before final release, you can easily set up a run/debug configuration manually to get the same effect. From within PyCharm, select the Run -> Edition Configurations menu item.

Coverage.py Configuration

Coverage.py Configuration

In the Run/Debug Configurations dialog, click the box with the plus sign in the upper right corner to create a new Python script configuration. Call the configuration whatever you want. I tend to run coverage.py as part of nose, so I enter the path to the nosetests-script.py on my file system in the Script field. Under Windows, this will be in the Scripts sub-directory of your Python installation directory. If you’re on Linux or OSX, you can use the nose/core.py file in your site-packages folder.

In the Script parameters field, I enter the --with-coverage and --cover-package command line parameters. Finally, in the Working directory field, I add the path to the directory containing my unit tests. Running this configuration executes code coverage on my unit test directory, and PyCharm is smart enough to recognize any stack traces that may occur during the run, providing click-able links to the offending lines of code.

Programming PyCharm, Python, tools, unit tests

Python Unit Testing with Mock

January 24, 2010 Dale 4 Comments

In the past, while creating unit tests for C# classes, I’ve frequently used a mock object framework such as Moq to isolate classes under test. When I started working in Python, I initially didn’t think I’d need such a framework to write my tests. Creating a stub with a given set of attributes and methods is easy in language like Python.

However, I soon noticed I was writing a lot of these little stubs, and this was ‘dirtying up’ my nice, readable tests. The next problem I encountered was 3rd party libraries with more complex interfaces, like this Twitter library. It contains a client class that dynamically wraps Twitter’s RESTful API. So instead of calling http://twitter.com/statuses/friends.format, you call Twitter.statuses.friends(). The Twitter client doesn’t have a statuses.friends method defined, it creates the URL dynamically from the dot notation you enter.

Creating fakes to test code using such a class would be tedious. Additionally, I was looking at having to pass in instances of other 3rd party classes I was using. The whole thing was getting dangerously close to the DI/IoC mess we’d left behind when we switched from C#. As Jonathon commented a few weeks back:

In Python, hard is a smell.

Enter Mock. Mock is a mocking and testing library for Python by Michael Foord. Unlike many of the other mocking libraries for Python that use the record/replay pattern, Mock uses an action/assert pattern similar to Moq.

Below is a snippet of code that uses the previously mentioned Twitter RESTful client with the dynamic API methods. I’d like to mock up the actual API calls so that I’m not connecting to Twitter when I run my tests.

[python]
from twitter import Twitter, TwitterError

class TwitterClient(object):

def __init__(self, login, password):
self._twitter = Twitter(login, password)

def all_friends(self):
return self._get_statuses(
lambda crs: self._twitter.statuses.friends(cursor = crs))

def all_followers(self):
return self._get_statuses(
lambda crs: self._twitter.statuses.followers(cursor = crs))

def _get_statuses(self, call):
crs = -1
results = []
while crs != 0:
page = call(crs)
users = page[‘users’]
crs = page[‘next_cursor’]
results.extend(users)
return results
[/python]

Mock makes this easy.

[python]
class TwitterClientTests(unittest.TestCase):

def test_all_friends(self):
"""Verify TwitterClient.all_friends()"""
tc = TwitterClient(‘username’, ‘password’)
tc._twitter = Mock()
tc._twitter.statuses.friends.return_value = \
{‘users’:[{‘a’:1}], ‘next_cursor’:0}
result = tc.all_friends()
tc._twitter.statuses.friends.assert_called_with(cursor = -1)
self.assertEquals([{‘a’:1}], result)
[/python]

After creating my test class, I mock out the actual internal Twitter instance that is created. I then set the return value for the API method that all_friends will pass to _get_statuses. I don’t need to reproduce the full JSON returned from a real Twitter API call, I just need enough to test a single loop through the cursor-based call. Once I’m finished, in addition to validating the results returned using regular TestCase asserts, I can verify that my mock method was called with the correct parameters.

This just scratches the surface of what you can do with Mock. It contains facilities for patching, which is useful if you want to mock objects that get created during a method call (i.e. they aren’t easy-to-get-at class members like self.foo). Check out Mock’s documentation and introduction for more details.

Programming Python, unit tests

Nose – Fix nosetests finding 0 tests

November 26, 2009 Dale 2 Comments

I ran into an odd problem with nosetests not finding my unit test files after a git pull. After a little googling, I found someone who’d had similar issues with the permissions of their test files getting changed. For whatever reason (perhaps pushing from Cygwin on a Windows box?), my git pull had set the execution bit on my test files.

Typically, nosetests ignores executable files unless you pass it the --exe command line option. For now, I ran a chmod -x path/to/test.py to make the file non-executable again. I’m going to have to keep an eye on this to see if it reoccurs.

Programming Python, unit tests

Next Page »

About Me

Hi, my name's Dale, and this is my tech blog. Read More…

Search

Tags

blogging c# database Django documentation Email furniture git hacks htpc IPython Linux mac nas packaging PyCharm Python Roleplaying tools twitter unit tests virtualenv Visual Studio vmware Windows

Copyright © 2025 · Equilibre Theme on Genesis Framework · WordPress · Log in