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

Introduction TDD Python

Introduction TDD Python

Avatar for Ronald Cheung

Ronald Cheung

April 09, 2017
Tweet

More Decks by Ronald Cheung

Other Decks in Programming

Transcript

  1. Why Test Driven Development (TDD) Developer Perspective: - Forces developer

    to start with All Exit Criteria in mind. Then find the way to fulfill the Exit Criteria as efficiently as possible. - Have a design of the roadmap/ structure in terms of functions, procedures - before coding begins - The Unit test validates your design - The Unit test is “Documentation by example” in the sense that: (1) Documents the assumptions made by the developer (2) Is an Up to date , “Live”, and executable specification
  2. Why Test Driven Development (TDD) - Requires more discipline -

    Forces the complex areas to be identified and worked on first Agile Perspective: - Enables rapid change. - Gives confidence to allow rapid changes to code because breaking changes can be immediately detected. ( Regression) - Integration with Continuous Integration Tools
  3. Does it take longer to Deliver with TDD? - Initial

    progress slower compared to traditional development, a period of adjustment required to gain experience - In the long term costs, progress will be more consistent and progress will be faster since changes can be made rapidly with more confidence. - Bugs are detected early on - defects detected later will be exponentially more costly to fix. - Speed of delivery Time TDD Traditional
  4. TDD styles 1. Write the code then write unit tests

    2. Write failing unit tests then code to pass the test.
  5. Nosetests $ pip install nose (tddenv) ronald@ronalddemo01:~/tdd$ ls -lt -rw-rw-r--

    1 ronald ronald 259 Apr 9 10:46 tests.py -rw-rw-r-- 1 ronald ronald 114 Apr 9 10:44 palindrome.py drwxrwxr-x 6 ronald ronald 4096 Apr 9 10:29 tddenv (tddenv) ronald@ronalddemo01:~/tdd$
  6. Write Tests to Fail from palindrome import is_palindrome def test_function_accept_palindrome_noon():

    input = 'noon' assert is_palindrome01(input) == True def test_function_accept_palindrome_world(): input = 'hello world' assert is_palindrome01(input) == False ~ Tests the following Exit Criteria: 1. “Noon” is a valid palindrome 2. “Hello world” is not a valid palindrome Nosetests will automatically discover functions that being with “test*” and run them as unit tests.
  7. Run tests (tddenv) ronald@ronalddemo01:~/tdd$ nosetests FF ============================================================== FAIL: tests.test_function_accept_palindrome_noon ----------------------------------------------------------------------

    Traceback (most recent call last): File "/home/ronald/tdd/tddenv/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) File "/home/ronald/tdd/tests.py", line 5, in test_function_accept_palindrome_noon assert is_palindrome01(input) == True AssertionError ================================================================ FAIL: tests.test_function_accept_palindrome_world ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/ronald/tdd/tddenv/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) File "/home/ronald/tdd/tests.py", line 10, in test_function_accept_palindrome_world assert is_palindrome01(input) == False AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.010s FAILED (failures=2)
  8. Why Test Driven Development (TDD) Note: - There are now

    2 tests to test the positive case of a palindrome and assert a negative case. Does it now mean the code functions 100% - Not necessarily! - Unit tests can be considered a “safety net” but does not replace good design - Just because the test pass, does not necessarily follow the code functions 100% correctly - Value of tests depend on quality of unit tests, and coverage
  9. Other exit criteria / assumptions: Did you consider Unit tests

    for the following? - Ignore leading or trailing spaces? - Case insensitive palindrome? - Ignore spaces within the string? - Test to handle UTF characters?
  10. Coverage (tddenv) ronald@ronalddemo01:~/tdd$ pip install coverage (tddenv) ronald@ronalddemo01:~/tdd$ nosetests --with-coverage

    Name Stmts Miss Cover ----------------------------------- palindrome.py 4 1 75% ---------------------------------------------------------------------- Ran 2 tests in 0.011s OK
  11. Acceptance TDD - The role of Acceptance tests is to

    verify functional Exit Criteria of the user story is fulfilled. - E.g “ Checking accounts have an overdraft limit of $500. As long as there are sufficient funds (e.g. -$500 or greater) within a checking account after a withdrawal has been made the withdrawal will be allowed.” - May also overlap with traditional “regression” testing.
  12. Acceptance Test cycle Write a failing test Make the test

    pass Refactor Write a failing Acceptance test
  13. Further Topics This talk: - Unit Test Framework (Nosetests) Further

    topics: - Automated Build Tool ( BuildBot) - Acceptance Test Framework (Selenium [Web App], SoapUI [Web services/API]) - Continuous Integration ( BuildBot, Jenkins,Tox, Travis-CI )