Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Good Test, Bad Test

dcrosta
April 11, 2015

Good Test, Bad Test

http://late.am/post/2015/04/20/good-test-bad-test.html

In a highly dynamic language like Python, testing is even more critical than in compiled or more static languages. Like any other code we produce, tests can be either good or bad. This talk explores three myths of testing, and the mistakes and bad habits these fallacies encourage; and shows how to write good tests which help assure proper behavior without impeding development progress.

dcrosta

April 11, 2015
Tweet

More Decks by dcrosta

Other Decks in Programming

Transcript

  1. good test bad test ! ! ! ! ! dan

    crosta http://late.am/ @lazlofruvous magnetic
  2. def test_it_parses_log_lines(self): line = '2015-03-11T20:09:25|GET /foo?bar=baz|...' ! parsed = parse_log_line(line)

    ! self.assertEqual({ "date": datetime(2015, 3, 11, 20, 9, 25), "method": "GET", "path": "/foo", "query": "bar=baz", }, parsed) ! ! ! ! !
  3. def test_it_parses_log_lines(self): line = '2015-03-11T20:09:25|GET /foo?bar=baz|...' ! parsed = parse_log_line(line)

    ! self.assertEqual( datetime(2015, 3, 11, 20, 9, 25), parsed["date"], ) self.assertEqual("GET", parsed["method"]) self.assertEqual("/foo", parsed["path"]) self.assertEqual("bar=baz", parsed["query"]) ! ! ! !
  4. def test_it_parses_get_request_log_lines(self): # ... self.assertEqual("GET", parsed["method"]) self.assertEqual("/foo", parsed["path"]) self.assertEqual("bar=baz", parsed["query"])

    ! def test_it_parses_post_request_log_lines(self): # ... self.assertEqual("POST", parsed["method"]) self.assertEqual("/foo", parsed["path"]) self.assertEqual("bar=baz", parsed["query"]) ! def test_it_parses_log_lines_with_oof_requests(self): # ... self.assertEqual("GET", parsed["method"]) self.assertEqual("/oof", parsed["path"]) self.assertEqual("bar=baz", parsed["query"])
  5. def test_it_parses_request_method(self): # ... self.assertEqual("GET", parsed["method"]) ! def test_it_parses_request_path(self): #

    ... self.assertEqual("/foo", parsed["path"]) ! def test_it_parses_query_string(self): # ... self.assertEqual("bar=baz", parsed["query"]) ! def test_it_gives_none_when_no_query_string(self): # ... self.assertIsNone(parsed["query"]) !
  6. def authenticate(username): """Return a True if the user is authenticated

    """ # ... return True ! ! def login(username): if not authenticate(self.params["username"]): return Response(status=401) ! # ... do more stuff ... ! return Response(status=200) !
  7. def test_login_returns_200_on_success(self): with mock.patch(app, "authenticate") as auth: auth.return_value = True

    ! response = app.login("dcrosta") ! self.assertEqual(200, response.status) ! ! def test_login_returns_401_on_failure(self): with mock.patch(app, "authenticate") as auth: auth.return_value = False ! response = app.login("dcrosta") ! self.assertEqual(401, response.status)
  8. def authenticate(username): """Return a tuple of (authenticated, user_roles) """ #

    ... return (True, ["admin"]) ! ! def login(username): if not authenticate(self.params["username"]): return Response(status=401) ! # ... do more stuff ... ! return Response(status=200) !
  9. class StubDB(object): ! def __init__(self): self.users = {} ! def

    register_user(self, username, roles): self.users[username] = roles ! def authenticate(self, username): if username not in self.users: return (False, []) return (True, self.users[username]) ! ! !
  10. def test_login_returns_200_on_success(self): db = StubDB() db.register_user("dcrosta", ["admin"]) ! app =

    MyApp(db) response = app.login("dcrosta") ! self.assertEqual(200, response.status) ! def test_login_returns_401_on_failure(self): db = StubDB() ! app = MyApp(db) response = app.login("dcrosta") ! self.assertEqual(401, response.status)
  11. good test bad test ! ! ! ! ! dan

    crosta http://late.am/ @lazlofruvous magnetic