Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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()
share|improve this question
add comment

1 Answer

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.
share|improve this answer
    
count() is compatible with Python 3. For small counts, compatibility might be more important than the memory savings from xrange(). –  200_success Jan 16 at 18:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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