Test Driven Development SN Biggs York Plasma Institute TDD | 7th July 2017 | 1/40
Introduction Image ref: https://usercontent2.hubstatic.com/8530569 f520.jpg TDD | 7th July 2017 | 2/40
Outline Unit Testing Unit Testing is a Safety Net Unit Test Structure: Setup, Exercise, Assert xUnit – The Testing Framework Exercise – Write Some Unit Tests Test Driven Development (TDD) A Different Mindset Test First!? Fail, Pass, Refactor: A Simple Example Exercise – Take TDD for a Test Drive A Word of Warning: Pick the Right Tool for the Right Job Summary and Further Reading TDD | 7th July 2017 | 3/40
Unit Testing is a Safety Net Image ref: http://www.fitnessbin.com/wp-content/uploads/2015/12/Rock-Climbing-4.jpg TDD | 7th July 2017 | 4/40
Unit Testing is a Safety Net Image ref: http://www.jamkey.fr/wp-content/uploads/2015/05/tests-pyramid.png TDD | 7th July 2017 | 5/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Unit Testing is a Safety Net TDD | 7th July 2017 | 6/40
Test Structure: Setup, Exercise, Assert class Calculator(): def add(self, augend, addend): 'Adds the addend to the augend' return augend + addend TDD | 7th July 2017 | 7/40
Test Structure: Setup, Exercise, Assert def testAddBothPositive(self): # Setup a = 3 b = 2 calc = Calculator() # Specify expected result expected = 5 # Exercise system under test actual = calc.add(a, b) # Verify result self.assertEqual(actual, expected) TDD | 7th July 2017 | 8/40
xUnit - The Testing Framework Began as sUnit for the Smalltalk language by Kent Beck in 1998 Since ported to many languages (cUnit, cppUnit, fUnit, pyUnit, etc.) Object-oriented - test classes inherit assertions Provides test suites, test runners, formatted test results, etc. Image ref: https://d21ii91i3y6o6h.cloudfront.net/gallery images/from proof/4404/large/1425068890/xunit-dot-net-small-logo.png TDD | 7th July 2017 | 9/40
xUnit - The Testing Framework import unittest from Calculator import Calculator class testCalculator(unittest.TestCase): def setUp(self): self.calc = Calculator() def testAddBothPositive(self): 'Tests that two positive numbers are added correctly' # Exercise system under test and verify result self.assertEqual(self.calc.add(3, 2), 5) TDD | 7th July 2017 | 10/40
xUnit - The Testing Framework To run the unit tests (from bash): $ python -m unittest module[.class[.test]] [-v] e.g. $ python -m unittest testCalculator.testCalculator.testAddBothPositive or discover tests automatically: $ python -m unittest discover TDD | 7th July 2017 | 11/40
Exercise - Write Some Unit Tests 1 Download my basic calculator class ∗ from here: http://www- users.york.ac.uk/ ∼ snb519/coding-club-tdd-examples/Calculator.py 2 Write a test class, testCalculator.py, that extends unittest.TestCase (see slide 10) 3 Write tests (see slide 8) for adding different combinations of numbers, e.g. both positive, both negative, one of each, floats, etc. 4 Run the tests (see slide 11) to see what the test results look like – try with and without the -v flag, and try running individual tests and test discovery 5 Try changing Calculator.py to see what failing tests look like 6 Extension - can you write any tests that should pass but actually fail, e.g. test that passing in strings is handled correctly ∗ You can also get the slides here: http://www-users.york.ac.uk/ ∼ snb519/coding-club-tdd-examples/slides.pdf TDD | 7th July 2017 | 12/40
A Different Mindset Image ref: http://www.fitnessbin.com/wp-content/uploads/2015/12/Rock-Climbing-4.jpg TDD | 7th July 2017 | 13/40
Test First!? Image ref: https://leantesting-wp.s3.amazonaws.com/resources/wp-content/uploads/2015/02/tdd-circle-of-life.png TDD | 7th July 2017 | 14/40
Test First!? 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 15/40
Test First!? Image ref: https://leantesting-wp.s3.amazonaws.com/resources/wp-content/uploads/2015/02/tdd-circle-of-life.png TDD | 7th July 2017 | 16/40
Fail, Pass, Refactor: A Simple Example 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 17/40
Fail, Pass, Refactor: A Simple Example 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 18/40
Fail, Pass, Refactor: A Simple Example def testSubtractBothPositive(self): 'Tests that two positive numbers are subtracted correctly' # Exercise system under test and verify result self.assertEqual(self.calc.subtract(3, 2), 1) TDD | 7th July 2017 | 19/40
Fail, Pass, Refactor: A Simple Example E =============================================================== ERROR: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly --------------------------------------------------------------- Traceback (most recent call last): File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) AttributeError: Calculator instance has no attribute 'subtract' --------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) TDD | 7th July 2017 | 20/40
Fail, Pass, Refactor: A Simple Example 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 21/40
Fail, Pass, Refactor: A Simple Example def subtract(self): pass TDD | 7th July 2017 | 22/40
Fail, Pass, Refactor: A Simple Example E =============================================================== ERROR: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly --------------------------------------------------------------- Traceback (most recent call last): File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) TypeError: subtract() takes exactly 1 argument (3 given) --------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) TDD | 7th July 2017 | 23/40
Fail, Pass, Refactor: A Simple Example def subtract(self, minuend, subtrahend): pass TDD | 7th July 2017 | 24/40
Fail, Pass, Refactor: A Simple Example F =============================================================== FAIL: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly --------------------------------------------------------------- Traceback (most recent call last): File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) AssertionError: None != 1 --------------------------------------------------------------- Ran 1 test in 0.000s FAILED (failures=1) TDD | 7th July 2017 | 25/40
Fail, Pass, Refactor: A Simple Example 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 26/40
Fail, Pass, Refactor: A Simple Example def subtract(self, minuend, subtrahend): return 1 TDD | 7th July 2017 | 27/40
Fail, Pass, Refactor: A Simple Example . --------------------------------------------------------------- Ran 1 test in 0.000s OK TDD | 7th July 2017 | 28/40
Fail, Pass, Refactor: A Simple Example 1 Identify desired functionality 2 Write failing test 3 Make it compile as quickly as possible 4 Make it pass a quickly as possible 5 Remove duplication while maintaining 100% pass rate 6 Repeat as required TDD | 7th July 2017 | 29/40
Fail, Pass, Refactor: A Simple Example def subtract(self, minuend, subtrahend): return 3 - 2 TDD | 7th July 2017 | 30/40
Fail, Pass, Refactor: A Simple Example . --------------------------------------------------------------- Ran 1 test in 0.000s OK TDD | 7th July 2017 | 31/40
Fail, Pass, Refactor: A Simple Example def subtract(self, minuend, subtrahend): return minuend - 2 TDD | 7th July 2017 | 32/40
Fail, Pass, Refactor: A Simple Example . --------------------------------------------------------------- Ran 1 test in 0.000s OK TDD | 7th July 2017 | 33/40
Fail, Pass, Refactor: A Simple Example def subtract(self, minuend, subtrahend): return minuend - subtrahend TDD | 7th July 2017 | 34/40
Fail, Pass, Refactor: A Simple Example . --------------------------------------------------------------- Ran 1 test in 0.000s OK TDD | 7th July 2017 | 35/40
Recommend
More recommend