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

TDD in Python

suci
June 16, 2017

TDD in Python

suci

June 16, 2017
Tweet

More Decks by suci

Other Decks in Programming

Transcript

  1. Agenda More info on how to use this template at

    www.slidescarnival.com/help-use-presentation-template Testing ◦ ◦ ◦ ◦ Unit Test ◦ ◦ ◦ ◦ TDD ◦ ◦
  2. Why Software Testing 1. Deliver the best application we can.

    2. Lots of different devices, browsers, and operating systems 3. User really will do that – no matter how silly it seems. 4. One person to hundreds of people, even more, are using it. 5. To ensure that what we create does what it’s supposed to do. http://www.te52.com/testtalk/2014/08/07/5-reasons-we-need-software-testing/ Precision and Accuracy, Validation, Reliability, and Quality Delivery of high quality product or software application to customers
  3. Test Principles Principles are just for reference. I will not

    use them in practise. http://istqbexamcertification.com/what-are-the-principles-of-testing/ http://www.guru99.com/software-testing-seven-principles.html
  4. Testing levels Unit testing Integration testing System testing Operational acceptance

    testing Developers White box Testers (QA, users) Black box
  5. Write test program to test 1. Instant Feedback ◦ (

    Time (testing) << Time(debugging) ) 2. Regression Testing and Refactoring 3. API design 4. (Unit) test is Document
  6. What Is Unit test? • Smallest testable part of an

    application like functions, classes, procedures, interfaces. • Breaking your program into pieces, and subjecting each piece to a series of tests • should be done by the developers. http://istqbexamcertification.com/what-is-unit-testing/ Unit test is good, because • Issues are found at early stage • Unit testing helps in maintaining and changing the code • Reducing the cost of bug fixes. • Simplifying the debugging process
  7. Assert Telling the program to test that condition, and trigger

    an error if the condition is false. if not condition: raise AssertionError() >>> assert True >>> assert False Traceback (most recent call last) : File "<stdin>", line 1, in <module> AssertionError Assert = https://docs.python.org/3/reference/simple_stmts.html#assert
  8. class Calculator: def mod(self, dividend, divisor): remainder = dividend %

    divisor quotient = (dividend - remainder) / divisor return quotient, remainder if __name__ == '__main__': cal = Calculator() assert cal.mod(5, 3) == (1, 2) # 5 / 3 = 1 ... 2 assert cal.mod(8, 4) == (1, 0) # 8 / 4 = 2 ... 0 Assert example https://imsardine.wordpress.com/tech/unit-testing-in-python/ Traceback (most recent call last) : File "/Users/shuhsi/github/TDD-kata/test_calc.py ", line 11, in <module> assert cal.mod(8, 4) == (1, 0) # 8 / 4 = 2 ... 0 AssertionError
  9. https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks xUnit Framework • Architecture for unit testing frameworks that

    are code-driven • By Kent Beck • Prescribes testing the fundamental units of software –examples: functions, methods, classes • Distinguishes between failures and errors in a unit of software Each Test case has four-phase: • Setup • Exercise • Verify (assertion) • Teardown (cleanup)
  10. Python Example https://docs.python.org/3/library/unittest.html import unittest class TestStringMethods (unittest.TestCase): def test_upper(self):

    self.assertEqual ('foo'.upper(), 'FOO') def test_isupper (self): self.assertTrue('FOO'.isupper()) self.assertFalse ('Foo'.isupper()) def test_split(self): s = 'hello world ' self.assertEqual (s.split(), ['hello', 'world']) # check that s.split fails when the separator is not a string with self.assertRaises (TypeError) : s. split(2) if __name__ == '__main__': unittest. main()
  11. import unittest class Calculator: def mod(self, dividend, divisor): remainder =

    dividend % divisor quotient = (dividend - remainder) / divisor return quotient, remainder class CalculatorTest (unittest.TestCase): def test_mod_with_remainder (self): cal = Calculator() self.assertEqual (cal.mod(5, 3), (1, 2)) def test_mod_without_remainder (self): cal = Calculator() self.assertEqual (cal.mod(8, 4), (1, 0)) def test_mod_divide_by_zero (self): cal = Calculator() assertRaises (ZeroDivisionError, cal.mod, 7, 1) if __name__ == '__main__': unittest. main() Subclass of unittest Prefix: test assertEqual Import unitest Run all test cases Raise error
  12. ====================================================================== ERROR: test_mod_divide_by_zero (__main__.CalculatorTest) ---------------------------------------------------------------------- Traceback (most recent call last):

    File "/Users/shuhsi/github/TDD-kata/test_calc.py", line 22, in test_mod_divide_by_zero assertRaises(ZeroDivisionError, cal.mod, 7, 1) NameError: global name 'assertRaises' is not defined ====================================================================== FAIL: test_mod_without_remainder (__main__.CalculatorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shuhsi/github/TDD-kata/test_calc.py", line 18, in test_mod_without_remainder self.assertEqual(cal.mod(8, 4), (1, 0)) AssertionError: Tuples differ: (2, 0) != (1, 0) First differing element 0: 2 1 - (2, 0) ? ^ + (1, 0) ? ^ ---------------------------------------------------------------------- Ran 3 tests in 0.009s FAILED (failures=1, errors=1) Show difference error
  13. TDD

  14. What Is TDD? • Test-driven development • A methodology of

    Implementing Software that relies on the repetition of a very short development cycle TDD is not • a developing Tool • a silver bullet for problems! • the ONLY way to write good software! ◦ But, if followed, will help you write solid software!
  15. TDD cycles http://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html 1. Create a unit tests that fails

    2. Write production code that makes that test pass 3. Clean up the mess you just made
  16. "Write a program that prints the numbers from 1 to

    100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz” FizzBuzz Problem http://codingdojo.org/kata/FizzBuzz/ Sample output
  17. import unittest from fizzbuzz import FizzBuzz class TestFizzBuzz(unittest.TestCase): def test_0_raise_value_error

    (self): with self.assertRaises(ValueError): FizzBuzz(0) Write a production code (will pass a test) class FizzBuzz(object): pass
  18. import unittest from fizzbuzz import FizzBuzz class TestFizzBuzz(unittest.TestCase): def test_0_raise_value_error

    (self): with self.assertRaises(ValueError): FizzBuzz(0) def test_1_does_mot -raise_value_error (self): assert FizzBuzz(1).number == 1 (iteration 2) Write a test (will fail)
  19. (iteration 2)Write a production code (will pass a test) class

    FizzBuzz(object): def __init__(self, number): if number == 0: raise ValueError() self.number =1
  20. What TDD can help you? https://www.madetech.com/blog/9-benefits-of-test-driven-development 1. Acceptance Criteria 2.

    Focus 3. Interfaces 4. Tidier Code 5. Dependencies 6. Safer Refactoring 7. Fewer Bugs 8. Increasing Returns 9. Living Documentation
  21. FURTHER READING: Uncle Bob Martin ◦ Clean code ◦ http://blog.8thlight.com/uncle-bob/archive.html

    Kent Beck ◦ Extreme Programming Explained ◦ Test Driven Development: By Example Is TDD Dead? Test-Driven Development with Python Essential TDD (Test-Driven Development) for Pythoners, Pycontw 2016 RSpec & TDD Tutorial by ihower