12
\$\begingroup\$

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"""

  def test_connectionstate_reports_bad_network_connection(self):
    """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()
\$\endgroup\$
6
\$\begingroup\$

I have a few nitpicks:

  • 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.
\$\endgroup\$
3
  • 2
    \$\begingroup\$ count() is compatible with Python 3. For small counts, compatibility might be more important than the memory savings from xrange(). \$\endgroup\$ Jan 16 '14 at 18:08
  • 6
    \$\begingroup\$ There is no indication in the docs, or in the error messages, that assertEqual(expected, actual) is the correct signature. \$\endgroup\$
    – K3---rnc
    Aug 31 '15 at 17:20
  • \$\begingroup\$ 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: \$\endgroup\$
    – Menda
    Aug 17 '17 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.