Test Driven Development
SN Biggs
York Plasma Institute TDD|7th July 2017|1/40
Test Driven Development SN Biggs York Plasma Institute TDD | 7th - - PowerPoint PPT Presentation
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
SN Biggs
York Plasma Institute TDD|7th July 2017|1/40
Image ref: https://usercontent2.hubstatic.com/8530569 f520.jpg TDD|7th July 2017|2/40
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
Image ref: http://www.fitnessbin.com/wp-content/uploads/2015/12/Rock-Climbing-4.jpg TDD|7th July 2017|4/40
Image ref: http://www.jamkey.fr/wp-content/uploads/2015/05/tests-pyramid.png TDD|7th July 2017|5/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
TDD|7th July 2017|6/40
class Calculator(): def add(self, augend, addend): 'Adds the addend to the augend' return augend + addend
TDD|7th July 2017|7/40
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
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
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
To run the unit tests (from bash): $ python -m unittest module[.class[.test]] [-v] e.g. $ python -m unittest testCalculator.testCalculator.testAddBothPositive
$ python -m unittest discover
TDD|7th July 2017|11/40
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
Image ref: http://www.fitnessbin.com/wp-content/uploads/2015/12/Rock-Climbing-4.jpg TDD|7th July 2017|13/40
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
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
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
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
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
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
E =============================================================== ERROR: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly
File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) AttributeError: Calculator instance has no attribute 'subtract'
FAILED (errors=1)
TDD|7th July 2017|20/40
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
def subtract(self): pass
TDD|7th July 2017|22/40
E =============================================================== ERROR: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly
File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) TypeError: subtract() takes exactly 1 argument (3 given)
FAILED (errors=1)
TDD|7th July 2017|23/40
def subtract(self, minuend, subtrahend): pass
TDD|7th July 2017|24/40
F =============================================================== FAIL: testSubtractBothPositive (testCalculator.testCalculator) Tests that two positive numbers are subtracted correctly
File "testCalculator.py", line 40, in testSubtractBothPositiv self.assertEqual(self.calc.subtract(3, 2), 1) AssertionError: None != 1
FAILED (failures=1)
TDD|7th July 2017|25/40
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
def subtract(self, minuend, subtrahend): return 1
TDD|7th July 2017|27/40
.
OK
TDD|7th July 2017|28/40
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
def subtract(self, minuend, subtrahend): return 3 - 2
TDD|7th July 2017|30/40
.
OK
TDD|7th July 2017|31/40
def subtract(self, minuend, subtrahend): return minuend - 2
TDD|7th July 2017|32/40
.
OK
TDD|7th July 2017|33/40
def subtract(self, minuend, subtrahend): return minuend - subtrahend
TDD|7th July 2017|34/40
.
OK
TDD|7th July 2017|35/40
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|36/40
1 Using Calculator.py and testCalculator.py that you have already developed,
test and implement calc.multiply(multiplicand, multiplier) and calc.divide(divend, divisor) using TDD
2 Implement some extra features using TDD, e.g.
handling two numbers passed in as strings element-wise array operations (see numpy.testing.assert array equals) raising exceptions for invalid inputs (see unittest.TestCase.assertRaises) printing to screen when an optional argument is given (redirect sys.stdout) calculations on a custom class yet to be defined (pass in a mock subclass)
TDD|7th July 2017|37/40
Pick the right tool for the right job!
TDD|7th July 2017|38/40
Unit Testing
Unit Testing is a Safety Net Unit Test Structure: Setup, Exercise, Assert xUnit is The Testing Framework
Test Driven Development (TDD)
A Different Mindset Test First! Fail, Pass, Refactor
Pick the Right Tool for the Right Job
TDD|7th July 2017|39/40
Beck, K 2003 “Test-driven Development: By Example” Addison-Wesley, Kent Beck signature book. Feathers, M 2004 “Working Effectively with Legacy Code” Pearson Education, Robert C. Martin Series. Martin, RC 2008 “Clean Code: A Handbook of Agile Software Craftsmanship” Pearson Education. Hunt, A and Thomas, D 1999 “The Pragmatic Programmer: From Journeyman to Master” Pearson Education.
Image ref: http://d.gr-assets.com/books/1372039943l/387190.jpg TDD|7th July 2017|40/40