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

Introduction TDD Python

Introduction TDD Python

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 )