From: Ben Waugh Date: Thu, 11 Apr 2013 22:01:10 +0000 (+0100) Subject: Merge branch 'patch-1' of git://github.com/BernhardKonrad/boot-camps into BernhardKon... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8c62a70408e42726b22ffc3c15648e97183c72a4;p=swc-testing-nose.git Merge branch 'patch-1' of git://github.com/BernhardKonrad/boot-camps into BernhardKonrad-patch-1 Conflicts: testing/cheat-sheet.md --- 8c62a70408e42726b22ffc3c15648e97183c72a4 diff --cc testing/cheat-sheet.md index 7df9783,990a047..0d6eac8 --- a/testing/cheat-sheet.md +++ b/testing/cheat-sheet.md @@@ -50,76 -63,48 +59,109 @@@ There are some additional rules, and yo ### Other assertions -TODO: finish this +Nose provides a range of assertions that can be used when a test is not just checking a simple equality, e.g. + * assertTrue, assertFalse + * assertIn, assertNotIn + * assertIs, assertIsNot + * assertRaises + * (what else?) + + from nose.tools import assert_items_equal + + from mycode import find_factors + + def test_6(): + observed = find_factors(6) + expected = [2, 3] + assert_items_equal(observed, expected) # order of factors is not guaranteed + ### Floating point tests -* assert_almost_equal... +When comparing floating-point numbers for equality, allow some tolerance for small differences due to +the way values are represented and rounded. + * assertGreater, assertLess + from nose.tools import assert_almost_equal + + from mycode import hypotenuse + + def test_hypotenuse_345(): + observed = hypotenuse(3.0, 4.0) + expected = 5.0 + assert_almost_equal(observed, expected) + +### Testing exceptions + +Testing that a method raises the appropriate exception when the input is invalid: + + from nose.tools import raises + + from mystatscode import mean + + @raises(TypeError) + def test_not_a_list(): + observed = mean(1) + ### Fixtures -(todo) +A *fixture* is what the test function uses as input, e.g. values, objects and arrays. + +To set up a fixture once before any tests are run, define a method called `setup` in the same files +as the test functions. This can assign values to global variables for use in the test functions. + + long_list = None + + def setup(): + long_list = [0] + # append more values to long_list... + +If the global variables assigned in `setup` might be modified by some of the test functions, the set-up +step must be executed once before each test function is called: + + from nose.tools import with_setup + + from mycode import mean, clear + + long_list = None + + def setup_each(): + long_list = [0] + # append more values to long_list... + + @with_setup(setup_each) + def test_mean_long_list(): + observed = mean(long_list) + expected = 0.0 + assert_equal(observed, expected) + + @with_setup(setup_each) + def test_clear_long_list(): + clear(long_list) + assert_equal(len(long_list), 0) ++ + + + Test-driven deveopment + ---------------------- + + ***Red.*** Write test function that checks one new functionality you want to add to your code. -- tests have to fail. + + ***Green.*** Write minimal code that implements desired features until all tests pass. + + ***Refactor.*** Improve code wrt. readability and speed. Constantly check that tests still pass. + + ***Commit.*** Commit working code to version control. + + Repeat. + + + General advice + -------------- + + * Perfect test-case coverage is impossible. + * Try to test distinct functionalities. + * If you find a bug yet undiscovered by previous test, make it a new test case. + + -TODO: - -* setup... -* per-test fixtures with @with_setup decorator +