# Unit test best-practices in Python

I'm a Java/C coder getting started with some Python for a side-project. I've written some unit tests for a recent side-project I'm working on, but I have a sinking suspicion I'm just writing Java-code, translated into Python.

I've posted a small sample of some unit-tests I wrote. I'd really appreciate any advice in how to make the code more Pythonic (best-practices, conventions, etc).

import unittest
import urllib2
from connectionstate import ConnectionState

class Test(unittest.TestCase):
"""Unit tests for the ConnectionState"""

"""ConnectionState reports a failure when currently disconnected"""

#Set up ConnectionState around mock
always_disconnected = mock_connection_check_func_always_disconnected
connstate_with_mock = ConnectionState(always_disconnected)

actual_state = connstate_with_mock.is_connected()
self.assertEqual(actual_state, False)

def test_connectionstate_detects_good_network_connection(self):
"""ConnectionState should report success when we can connect"""
#Set up ConnectionState around mock
always_connected = mock_connection_check_func_always_connected
connstate_with_mock = ConnectionState(always_connected)

actual_state = connstate_with_mock.is_connected()
self.assertEqual(actual_state, True)

def test_connectionstate_remembers_disconnections(self):
"""If the internet connection drops and then comes back, ConnectionState
can remember that the connection dropped temporarily
"""
#Set up ConnectionState around mock
sometimes_connected = mock_conn_every_other_conn_succeeds
connstate_with_mock = ConnectionState(sometimes_connected)

#Call is_connected a few times so get an unsuccessful connection
for count in range(0, 3):
connstate_with_mock.is_connected()

actual_result = connstate_with_mock.has_connection_dropped()
self.assertEqual(actual_result, True)

def test_connectionstate_doesnt_bring_up_ancient_history(self):
"""has_connection_dropped only reports failures that have happened
since the last call to has_connection_dropped.  Calling
"""
#Set up ConnectionState around mock
sometimes_connected = mock_conn_every_other_conn_succeeds
connstate_with_mock = ConnectionState(sometimes_connected)

#Call is connected a few times so an unsuccessful connection is reported
for count in range(0, 3):
connstate_with_mock.is_connected()

#Call once to clear failures
connstate_with_mock.has_connection_dropped()

actual_result = connstate_with_mock.has_connection_dropped()
self.assertEqual(actual_result, False)

#Begin mock-connection functions
def mock_connection_check_func_always_disconnected(request=None, timeout=1):
raise urllib2.URLError("Unable to connect to network")
def mock_connection_check_func_always_connected(request=None, timeout=1):
pass
def mock_conn_every_other_conn_succeeds(request=None, timeout=1):
#Initialize 'static' call-counter variable
if "call_counter" not in mock_conn_every_other_conn_succeeds.__dict__:
mock_conn_every_other_conn_succeeds.call_counter = 0;

mock_conn_every_other_conn_succeeds.call_counter += 1

if mock_conn_every_other_conn_succeeds.call_counter % 2 == 0:
mock_connection_check_func_always_disconnected(request, timeout)
else:
mock_connection_check_func_always_connected(request, timeout)
#End mock-connection functions

if __name__ == "__main__":
unittest.main()


• If you use assertFalse and assertTrue instead of assertEquals(something, True/False) where appropriate, the output of your unit tests will make more sense when they fail. (http://docs.python.org/2/library/unittest.html#assert-methods)
• The argument order of assertEquals is expected, actual. Again, if you use the correct order the error messages will work as intended.
• A more common style for when you want a block of code to execute a fixed number of times (like in for count in range(0, 3):) is: for _ in xrange(3):. The _ tells the reader that the value is unimportant, and xrange uses less memory since it doesn't create a list.
• count() is compatible with Python 3. For small counts, compatibility might be more important than the memory savings from xrange(). Jan 16 '14 at 18:08
• There is no indication in the docs, or in the error messages, that assertEqual(expected, actual) is the correct signature. Aug 31 '15 at 17:20
• I agree with @K3---rnc Even in the official docs it's the oposite: assertEqual(actual, expected): docs.python.org/3/library/unittest.html#basic-example For me this way makes more sense because in an if condition you also do it that way: if result == 1: Aug 17 '17 at 16:14