### 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
+