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. TDD in Python
    Shuhsi Lin
    2017/6/16

    View Slide

  2. Agenda
    More info on how to use this template at
    www.slidescarnival.com/help-use-presentation-template
    Testing




    Unit Test




    TDD


    View Slide

  3. Hello!

    View Slide

  4. Testing
    Software Testing

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. Testing methods and Types



    View Slide

  8. Testing levels
    Unit testing
    Integration testing
    System testing
    Operational acceptance
    testing
    Developers
    White box
    Testers (QA, users)
    Black box

    View Slide


  9. Developers

    View Slide

  10. Write test program to test

    View Slide

  11. 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

    View Slide

  12. Unit Test

    View Slide

  13. 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

    View Slide

  14. 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 "", line 1, in
    AssertionError
    Assert =
    https://docs.python.org/3/reference/simple_stmts.html#assert

    View Slide

  15. 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
    assert cal.mod(8, 4) == (1, 0) # 8 / 4 = 2 ... 0
    AssertionError

    View Slide

  16. 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)

    View Slide

  17. View Slide

  18. 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()

    View Slide

  19. 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

    View Slide

  20. ======================================================================
    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

    View Slide

  21. TDD

    View Slide

  22. 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!

    View Slide

  23. 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

    View Slide

  24. Let’s Try it

    View Slide

  25. "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

    View Slide

  26. import unittest
    class TestFizzBuzz(unittest.TestCase):
    def test_0_raise_value_error (self):
    with self.assertRaises(ValueError):
    FizzBuzz(0)
    Write a test (will fail)
    Not exist yet
    fizzbuzz_test.py

    View Slide

  27. 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

    View Slide

  28. class FizzBuzz(object):
    pass
    Refactor
    class FizzBuzz(object):
    def __init__(self, number):
    raise ValueError()

    View Slide

  29. 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)

    View Slide

  30. (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

    View Slide

  31. https://youtu.be/JJk_HK2ZWGg

    View Slide

  32. 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

    View Slide

  33. Testing/coding is so hard!! How to do it?
    https://www.youtube.com/watch?v=KijjEG_DQ34

    View Slide

  34. Code Kata and Dojo
    http://blog.agilepartner.net/code-kata-improve-your-coding-skills/

    View Slide

  35. http://codingdojo.org/dojo/
    http://www.skfscotland.co.uk/katas/kushanku_kata.gif

    View Slide

  36. More about
    testing and xDD





    View Slide

  37. 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

    View Slide

  38. Thanks!

    View Slide