SlideShare una empresa de Scribd logo
1 de 153
Descargar para leer sin conexión
mage
     Python Testing Fundamentals

            Python Testing Fundamentals
               Saturday, July 28, 2012
                             PyOhio
                 Ohio State University
                      Columbus, OH
                      Chris Calloway
            University of North Carolina
          Department of Marine Sciences

                                           Programming
PyCamp™   Copyright © 2012
              Trizpug                      For The People
mage
     Python Testing Fundamentals




     http://drunkenpython.org/pytestfund.pdf
          http://drunkenpython.org/pyohio.zip
          http://drunkenpython.org/pyohio.tgz




                                          Programming
PyCamp™     Copyright © 2012
                Trizpug                   For The People
About This Tutorial



    •Fundamental
    •Python 3.2.3
    •Assertion
    •Unittest
    •Doctest
                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Why Test?




    “Untested Code is Broken Code”
            - Phillip von Weitershausen




                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
Why Test?




   •Tests help you design good code
   •Test help you find bugs
   •Tests help you document code


                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•Assert statements use the assert keyword
•Assert statements raise AssertionError
•Based on bool test expressions


                                   Programming
PyCamp™    Copyright © 2012
               Trizpug             For The People
Assert Statements



                         keyword


 >>> assert 1 == 1




                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
Assert Statements



 expression


 >>> assert 1 == 1




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements

 >>> assert expression


 is almost the same as:


 >>> if not expression:
 ...      raise AssertionError()
 >>>

                                   Programming
PyCamp™    Copyright © 2012
               Trizpug             For The People
Assert Statements


 >>> assert 1 == 1
 >>> assert 1 == 2
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 AssertionError
 >>>


                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•A second optional expression on the assert
  statement provides a message for the
  AssertionError

•This helps you distinguish one assertion from
  another



                                         Programming
PyCamp™     Copyright © 2012
                Trizpug                  For The People
Assert Statements



   second expression


 >>> assert 1 == 2, "Reality check"




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements


 assert expression1, expression2



 is almost the same as:


 if not expression1:
    raise AssertionError(expression2)


                                   Programming
PyCamp™    Copyright © 2012
               Trizpug             For The People
Assert Statements



 >>> assert 1 == 2, "Reality check"
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 AssertionError: Reality check
 >>>



                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•Assertions may be sprinkled liberally throughout
  your code to check that your code is running as
  expected

•Think of assertions as Python's reality check
•You decide what "reality" is

                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
Assert Statements


 bigbiz.py:

 profit = bottom_line(today)
 assert profit > 0, "Unacceptable!"
 projection = growth(tomorrow)
 assert projection > profit, "UR fired!"




                                      Programming
PyCamp™       Copyright © 2012
                  Trizpug             For The People
Assert Statements




•Assertions usually generate unhandled
  exceptions which halt your program




                                       Programming
PyCamp™    Copyright © 2012
               Trizpug                 For The People
Assert Statements


 bigbiz.py:

 def bottom_line(timestamp):
     """Compute the profit on date."""
                  Text

     return -1e6



                                      Programming
PyCamp™       Copyright © 2012
                  Trizpug             For The People
Assert Statements



 > python bigbiz.py
 Traceback (most recent call last):
  File "bigbiz.py", line 20, in <module>
     assert profit > 0, "Unacceptable!"
 AssertionError: Unacceptable!
 >


                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•By using Python's -i command line switch, you
  may interactively inspect what went wrong where
  the assertion was raised




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Assert Statements



 > python -i bigbiz.py
 Traceback (most recent call last):
   File "bigbiz.py", line 20, in <module>
     assert profit > 0, "Unacceptable!"
 AssertionError: Unacceptable!
 >>> profit
 -1000000.0
 >>>



                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•By using Python's -i command line switch, you
  may use also Python's debugger to see what
  went wrong at the point of assertion




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Assert Statements

 > python -i bigbiz.py
 Traceback (most recent call last):
   File "bigbiz.py", line 20, in <module>
     assert profit > 0, "Unacceptable!"
 AssertionError: Unacceptable!
 >>> import pdb
 >>> pdb.pm()
 > /Users/cbc/pyohio/bigbiz.py(20)<module>()
 -> assert profit > 0, "Unacceptable!"
 (Pdb) profit
 -1000000.0
 (Pdb)

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




•Assertions may be turned off by "optimizing"
  Python with the -O command line switch




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Assert Statements




 > python -O
 >>> assert 1 == 2
 >>>




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements




 > python -O bigbiz.py
 Profit is -1000000.00 USD.
 Projected profit is -2000000.00 USD.
 >




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Assert Statements


•It's a fine line whether assert statements are
  testing or debugging

•Assert statements are slightly more sophisticated
  than using print

•But assert statements form the basis for testing in
  Python

•In Python, a test is an assertion of an expected
  result
                                        Programming
PyCamp™     Copyright © 2012
                Trizpug                 For The People
Unittest Module


•Unittest is "batteries included" in Python
•Unittest helps you separate test code from the
  code under test

•Unittest helps you write tests before code
•Unittest helps you organize and discover all your
  tests

•Unittest hooks into many other Python tools
                                      Programming
PyCamp™     Copyright © 2012
                Trizpug               For The People
Unittest Module

 >>> import unittest
 >>> dir(unittest)
 ['BaseTestSuite', 'FunctionTestCase', 'SkipTest',
 'TestCase', 'TestLoader', 'TestProgram', 'TestResult',
 'TestSuite', 'TextTestResult', 'TextTestRunner',
 '_TextTestResult', '__all__', '__builtins__',
 '__cached__', '__doc__', '__file__', '__name__',
 '__package__', '__path__', '__unittest', 'case',
 'defaultTestLoader', 'expectedFailure', 'findTestCases',
 'getTestCaseNames', 'installHandler', 'loader', 'main',
 'makeSuite', 'registerResult', 'removeHandler',
 'removeResult', 'result', 'runner', 'signals', 'skip',
 'skipIf', 'skipUnless', 'suite', 'util']
 >>>

                                           Programming
PyCamp™     Copyright © 2012
                Trizpug                    For The People
TestCase Class




•unittest.TestCase is a class
•You create TestCase subclasses
•You add methods whose names start with "test"
  to your TestCase subclass



                                    Programming
PyCamp™    Copyright © 2012
               Trizpug              For The People
TestCase Class


•Each test method you supply in your subclass
  executes a TestCase supplied method whose
  name starts with "assert"

•A TestCase provides what is known as a "test
  fixture" in testing parlance

•The unittest module provides many ways to
  run the test methods of your text fixture

                                        Programming
PyCamp™     Copyright © 2012
                Trizpug                 For The People
TestCase Class


 test_operator.py:

 """Demonstrate the unittest module."""

                              Text
 import operator
 import unittest




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
TestCase Class


 test_operator.py:



 class TestOperator(unittest.TestCase):
                              Text
     """Test the operator module."""




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
TestCase Class


 test_operator.py:
 def test_add(self):
     """Test the add function."""
                              Text
     self.assertEqual(operator.add(2, 2),
                                2 + 2)



                                         Programming
PyCamp™    Copyright © 2012
               Trizpug                   For The People
TestCase Class


 test_operator.py:
 def test_sub(self):
     """Test the sub function."""
                              Text
     self.assertEqual(operator.sub(4, 2),
                                4 - 2)



                                         Programming
PyCamp™    Copyright © 2012
               Trizpug                   For The People
TestCase Class


 test_operator.py:
 def test_mul(self):
     """Test the mul function."""
                              Text
     self.assertEqual(operator.mul(2, 2),
                                2 * 2)



                                         Programming
PyCamp™    Copyright © 2012
               Trizpug                   For The People
TestCase Class


 test_operator.py:



 if __name__ == "__main__":
                              Text
     unittest.main()




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
main Class



•unittest.main is also a class
•unittest.main is normally only used within a
  script containing test fixtures

•When unittest.main is instantiated, all of the
  tests in the script's namespace are loaded and
  run


                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
main Class


 > python test_operator.py
 ...
 --------------------------------------
 Ran 3 tests in 0.001s


 OK
 >


                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestLoader Class



•Notice that nowhere does it appear that your
  script has instantiated your TestCase subclass or
  execute any of its methods

•unittest.main instead instantiates a special
  unittest.TestLoader class which has
  methods to search your module for TestCase
  classes and instantiate them


                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
TestRunner Class


•Once the TestLoader instance created by
  unittest.main discovers and instantiates the
  TestCase in your script, unittest.main
  instantiates a special unittest.TestRunner
  class which has methods to run the methods of
  your TestCase instances

•unittest.main takes care of handling
  TestLoaders and TestRunners for you!

                                         Programming
PyCamp™    Copyright © 2012
               Trizpug                   For The People
TestRunner Class


   TestCase                                    unittest.main
    (superclass)                                         (instance)

                                              createTests()


 TestOperator                    discover()    TestLoader
     (subclass)                                       (instance)

                                                                   runTests()


 TestOperator                      run()              TestRunner
     (instance)                                               (instance)




                                                              Programming
PyCamp™       Copyright © 2012
                  Trizpug                                     For The People
main Class


 test_operator.py:



 if __name__ == "__main__":
                              Text
     unittest.main(verbosity=2)




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
main Class

 > python     test_operator.py
 test_add     (__main__.TestOperator)
 Test the     add function. ... ok
 test_mul     (__main__.TestOperator)
 Test the     mul function. ... ok
 test_sub     (__main__.TestOperator)
 Test the     sub function. ... ok
 --------------------------------------
 Ran 3 tests in 0.001s
 OK
 >

                                     Programming
PyCamp™     Copyright © 2012
                Trizpug              For The People
main Class


•Notice that your tests did not run in the same
  order in which they were defined

•unittest.main loads the test methods from
  your TestCase instance's __dict__ attribute

•Dictionaries are unordered
•unittest.main() runs the test methods in your
  Python's built-in order for strings

                                        Programming
PyCamp™      Copyright © 2012
                 Trizpug                For The People
TestCase Class


 test_operator.py:
 def test_add(self):
     """Test the add function."""
                              Text
     self.assertEqual(operator.add(2, 2),
                                2 + 3)



                                         Programming
PyCamp™    Copyright © 2012
               Trizpug                   For The People
TestCase Class

 > python test_operator.py
 F..
 ======================================
 FAIL: test_add (__main__.TestOperator)
 Test the add function.
 --------------------------------------
 Traceback (most recent call last):
   File "test_operator.py", line 13, in test_add
     self.assertEqual(operator.add(2, 2), 2 + 3)
 AssertionError: 4 != 5
 --------------------------------------
 Ran 3 tests in 0.082s
 FAILED (failures=1)
 >

                                      Programming
PyCamp™    Copyright © 2012
               Trizpug                For The People
TestCase Class


 test_operator.py:
 def test_add(self):
     """Test the add function."""
                              Text
     self.assertEqual(operator.add(2, 2),
                                2 + "2")



                                           Programming
PyCamp™    Copyright © 2012
               Trizpug                     For The People
TestCase Class

 > python test_operator.py
 E..
 ================================================
 ERROR: test_add (__main__.TestOperator)
 Test the add function.
 ------------------------------------------------
 Traceback (most recent call last):
   File "test_operator.py", line 13, in test_add
     self.assertEqual(operator.add(2, 2), 2 + "2")
 TypeError: unsupported operand type(s) for +:
 int' and 'str'
 ------------------------------------------------
 Ran 3 tests in 0.001s
 FAILED (errors=1)
 >

                                      Programming
PyCamp™    Copyright © 2012
               Trizpug                For The People
TestResult Class



•Running a test results in one of three outcomes:
   ★   Success (expected result)
   ★   Failure (unexpected result)
   ★   Error (error running the test)

•The outcomes of all tests are accumulated in a
  unittest.TestResult instance

                                        Programming
PyCamp™       Copyright © 2012
                  Trizpug               For The People
TestResult Class



•Most of the time you will not need to create your
  own TestResult instances

•Most of the ways you will run tests will
  instantiate and report a TestResult for you

•But to run a test always requires a TestResult
  instance somewhere


                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
TestResult Class


 > python -m unittest test_operator
 ...
 --------------------------------------
 Ran 3 tests in 0.000s


 OK
 >

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestResult Class

 > python -m unittest 
      test_operator.TestOperator
 ...
 --------------------------------------
 Ran 3 tests in 0.000s


 OK
 >

                                     Programming
PyCamp™     Copyright © 2012
                Trizpug              For The People
TestResult Class

 > python -m unittest 
      test_operator.TestOperator.test_add
 .
 --------------------------------------
 Ran 1 test in 0.000s


 OK
 >

                                     Programming
PyCamp™     Copyright © 2012
                Trizpug              For The People
TestResult Class


 > python -m unittest test_operator.py
 ...
 --------------------------------------
 Ran 3 tests in 0.000s


 OK
 >

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestResult Class

 > python     -m unittest -v test_operator
 test_add     (test_operator.TestOperator)
 Test the     add function. ... ok
 test_mul     (test_operator.TestOperator)
 Test the     mul function. ... ok
 test_sub     (test_operator.TestOperator)
 Test the     sub function. ... ok
 --------------------------------------
 Ran 3 tests in 0.001s
 OK
 >

                                     Programming
PyCamp™     Copyright © 2012
                Trizpug              For The People
TestResult Class

 > python -m unittest -h
 Usage: python -m unittest [options] [tests]

 Options:
   -h, --help       Show this message
   -v, --verbose    Verbose output
   -q, --quiet      Minimal output
   -f, --failfast   Stop on first failure
   -c, --catch      Catch control-C and
                    display results
   -b, --buffer     Buffer stdout and stderr
                    during test runs
 [tests] can be a list of any number of test
 modules, classes and test methods.

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
load_tests Protocol


 > python -m unittest
 .......
 --------------------------------------
 Ran 7 tests in 0.000s


 OK
 >

                                  Programming
PyCamp™    Copyright © 2012
               Trizpug            For The People
load_tests Protocol

 Alternative Usage: python -m unittest 
                    discover [options]

 Options:
   -s directory     Directory to start
                    discovery ('.' default)
   -p pattern       Pattern to match test
                    files
                    ('test*.py' default)
   -t directory     Top level directory of
                    project (default to
                    start directory)
 For test discovery all test modules must be
 importable from the top level directory.

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
TestCase Class


•Notice that TestCase.assertEqual does not
  appear to raise an unhandled AssertionError

•The TestRunner instance handles the
  AssertionError for failing tests and updates the
  TestResult instance

•TestCase.assertEqual is but one of many test
  methods you may use in your tests

                                       Programming
PyCamp™    Copyright © 2012
               Trizpug                 For The People
TestCase Class

                    Method               Tests If
    assertEqual(a, b)           a == b
    assertNotEqual(a, b)        a != b
    assertTrue(x)               bool(x) is True
    assertFalse(x)              bool(x) is False
    assertIs(a, b)              a is b
    assertIsNot(a, b)           a is not b
    assertIsNone(x)             x is None
    assertIsNotNone(x)          x is not None
    assertIn(a, b)              a in b
    assertNotIn(a, b)           a not in b
    assertIsInstance(a, b)      isinstance(a, b)
    assertNotIsInstance(a, b)   not isinstance(a, b)


                                                Programming
PyCamp™     Copyright © 2012
                Trizpug                         For The People
TestCase Class




•You not only need to test if your code produces
  expected results, you also need to test if your
  code handles unexpected results in an expected
  manner!




                                      Programming
PyCamp™    Copyright © 2012
               Trizpug                For The People
TestCase Class


 test_operatorNG.py:
 def test_add_str(self):
    """Test bad args for add."""
                              Text
     with self.assertRaises(TypeError):
          operator.add(2, "2")



                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
TestCase Class


 > python -m unittest test_operatorNG
 ....
 --------------------------------------
 Ran 4 tests in 0.000s


 OK
 >

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestCase Class


                 Method                          Tests If



   assertRaises(exception)               exception raised


                                         exception raised and
   assertRaisesRegex(exception, regex)
                                         message matches regex


   assertWarns(warning)                  warning raised


                                         warning raised and
   assertWarnsRegex(warning, regex)
                                         message matches regex


                                                     Programming
PyCamp™      Copyright © 2012
                 Trizpug                             For The People
TestCase Class

               Method                       Tests If

  assertAlmostEqual(a, b)        round(a-b, 7) == 0
  assertNotAlmostEqual(a, b)     round(a-b, 7) != 0
  assertGreater(a, b)            a > b
  assertGreaterEqual(a, b)       a >= b
  assertLess(a, b)               a < b
  assertLessEqual(a, b)          a <= b
  assertRegex(s, re)             s matches regex
  assertNotRegex(s, re)          s does not match regex
                                 a and b have the same
  assertCountEqual(a, b)         elements in the same
                                 number, regardless of order

                                                   Programming
PyCamp™       Copyright © 2012
                  Trizpug                          For The People
TestCase Class


               Method                        Compares


  assertMultiLineEqual(a, b)     Strings

  assertSequenceEqual(a, b)      Sequences

  assertListEqual(a, b)          Lists

  assertTupleEqual(a, b)         Tuples

  assertSetEqual(a, b)           Sets and Frozensets

  assertDictEqual(a, b)          Dictionaries


                                                  Programming
PyCamp™       Copyright © 2012
                  Trizpug                         For The People
TestCase Class




•Plus many more!

 >>> [attr for attr
 ...   in dir(unittest.TestCase)
 ...   if attr.startswith('assert')]



                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestCase Class


 >>> help(unittest.TestCase.
 ...      assertDictContainsSubset)
 Help on function assertDictContainsSubset in
 module unittest.case:
 assertDictContainsSubset(self, subset,
                              dictionary, msg=None)
 Checks whether dictionary is a superset of
 subset.



                                          Programming
PyCamp™    Copyright © 2012
               Trizpug                    For The People
TestSuite Class


 test_operatorNG2.py:

 """Demonstrate the unittest module."""

                             Text
 import operator
 import unittest




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:



 class TestAdd(unittest.TestCase):
                             Text
     """Test the add function."""




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:
 def test_add_int(self):
    """Test with ints."""
                             Text
    self.assertEqual(operator.add(2, 2),
                               2 + 2)



                                        Programming
PyCamp™   Copyright © 2012
              Trizpug                   For The People
TestSuite Class


 test_operatorNG2.py:
 def test_add_str(self):
    """Test with strs."""
                             Text
    with self.assertRaises(TypeError):
                operator.add(2, "2")



                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:



 class TestSub(unittest.TestCase):
                             Text
     """Test the sub function."""




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:
 def test_sub_int(self):
    """Test with ints."""
                             Text
    self.assertEqual(operator.sub(4, 2),
                               4 - 2)



                                        Programming
PyCamp™   Copyright © 2012
              Trizpug                   For The People
TestSuite Class


 test_operatorNG2.py:
 def test_sub_str(self):
    """Test with strs."""
                              Text
    with self.assertRaises(TypeError):
          operator.sub(4, "2")



                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:



 class TestMul(unittest.TestCase):
                             Text
     """Test the mul function."""




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class


 test_operatorNG2.py:
 def test_mul_int(self):
    """Test with ints."""
                             Text
    self.assertEqual(operator.mul(2, 2),
                               2 * 2)



                                        Programming
PyCamp™   Copyright © 2012
              Trizpug                   For The People
TestSuite Class


 test_operatorNG2.py:
 def test_mul_str(self):
    """Test with strs."""
                             Text
    self.assertEqual(operator.mul(2, "2"),
                               "22")



                                       Programming
PyCamp™   Copyright © 2012
              Trizpug                  For The People
TestSuite Class


 test_operatorNG2.py:
 str_suite = unittest.TestSuite()


                    Text
 str_suite.addTest(TestAdd("test_add_str"))
 str_suite.addTest(TestSub("test_sub_str"))
 str_suite.addTest(TestMul("test_mul_str"))



                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestSuite Class


 test_operatorNG2.py:



 if __name__ == "__main__":
                             Text
    unittest.main()




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestSuite Class



•Objects you have bound in the
  test_operatorNG2 namespace:

  •TestAdd class
  •TestSub class
  •TestMul class
  •str_suite instance
                                    Programming
PyCamp™    Copyright © 2012
               Trizpug              For The People
TestSuite Class



 > python test_operatorNG2.py
 ......
 --------------------------------------
 Ran 6 tests in 0.001s
 OK
 >


                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestSuite Class


 > python -m unittest 
            test_operatorNG2.str_suite
 ...
 --------------------------------------
 Ran 3 tests in 0.000s
 OK
 >

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
TestSuite Class

 > python -m unittest -v 
          test_operatorNG2.str_suite
 test_add_str (test_operatorNG2.TestAdd)
 Test with strs. ... ok
 test_sub_str (test_operatorNG2.TestSub)
 Test with strs. ... ok
 test_mul_str (test_operatorNG2.TestMul)
 Test with strs. ... ok
 --------------------------------------
 Ran 3 tests in 0.001s
 OK
 >

                                   Programming
PyCamp™   Copyright © 2012
              Trizpug              For The People
Organizing Tests

 pyohio-+
        bin/python
        pycamp-+
               __init__.py
               setup.py
               fibonacci.py
               triangle.py
               tests-+
                     __init__.py
                     test_fibonacci.py
                     test_triangular.py

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests


 > python pycamp/fibonacci.py 100
 1 2 3 5 8 13 21 34 55 89
 > python
 >>> from pycamp.fibonacci import fib
 >>> fib(100)
 [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
 >>>

                                    Programming
PyCamp™     Copyright © 2012
                Trizpug             For The People
Organizing Tests

 > python pycamp/triangular.py 100
 1 3 6 10 15 21 28 36 45 55 66 78 91
 > python
 >>> from pycamp.triangular import tri
 >>> tri(100)
 [1, 3, 6, 10, 15, 21, 28, 36, 45, 55,
 66, 78, 91]
 >>>

                                    Programming
PyCamp™     Copyright © 2012
                Trizpug             For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:

 """Tests for the fibonacci module."""

                             Text
 from pycamp import fibonacci
 import unittest




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:



 class TestFibonacci(unittest.TestCase):
                             Text
     """Test fibonacci's functions."""




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
TestCase Class




•TestCase also supplies methods you override
•TestCase.setUp() is called before every test
  method you supply in your subclass

•TestCase.tearDown() is called after every
  test method you supply in your subclass



                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
TestCase Class




•Your TestCase subclasses, along with all the
  test methods you supply, and all the TestCase
  supplied methods you override, possibly all
  bundled up into a TestSuite, are collectively
  known as a "test fixture" in testing parlance



                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:
 def setUp(self):
    """Test fixture build."""
                             Text
     self.lessThan100 = [1, 2, 3, 5, 8,
                                    13, 21, 34, 55,
                                    89, ]

                                            Programming
PyCamp™   Copyright © 2012
              Trizpug                       For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:

 def test_fib_100(self):
    """Test fib for numbers < 100."""
                             Text

    self.assertEqual(fibonacci.fib(100),
                               self.lessThan100)


                                         Programming
PyCamp™   Copyright © 2012
              Trizpug                    For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:

 def test_fib_10(self):
    """Test fib for numbers < 10."""
                             Text

    self.assertEqual(fibonacci.fib(10),
                               self.lessThan100[:5])


                                         Programming
PyCamp™   Copyright © 2012
              Trizpug                    For The People
Organizing Tests


 pycamp/tests/test_fibonacci.py:



 if __name__ == "__main__":
                             Text
    unittest.main()




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Organizing Tests


 pycamp/tests/test_triangular.py:

 """Tests for the triangular module."""

                              Text
 from pycamp import triangular
 import unittest




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Organizing Tests


 pycamp/tests/test_triangular.py:



 class TestTriangular(unittest.TestCase):
                              Text
     """Test triangular's functions."""




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Organizing Tests


 pycamp/tests/test_triangular.py:
 def setUp(self):
     """Test fixture build."""
                              Text
     self.lessThan100 = [1, 3, 6, 10, 15,
                                     21, 28, 36, 45,
                                     55, 66, 78, 91, ]

                                            Programming
PyCamp™    Copyright © 2012
               Trizpug                      For The People
Organizing Tests


 pycamp/tests/test_triangular.py:

 def test_tri_100(self):
     """Test tri for numbers < 100."""
                              Text

     self.assertEqual(triangular.tri(100),
                                self.lessThan100)


                                          Programming
PyCamp™    Copyright © 2012
               Trizpug                    For The People
Organizing Tests


 pycamp/tests/test_triangular.py:

 def test_tri_10(self):
     """Test tri for numbers < 10."""
                              Text

     self.assertEqual(triangular.tri(10),
                                self.lessThan100[:3])


                                          Programming
PyCamp™    Copyright © 2012
               Trizpug                    For The People
Organizing Tests


 pycamp/tests/test_triangular.py:



 if __name__ == "__main__":
                              Text
     unittest.main()




                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Organizing Tests

 > python -m unittest discover 
      -s pycamp -t .
 ....
 --------------------------------------
 Ran 4 tests in 0.001s


 OK
 >

                                    Programming
PyCamp™     Copyright © 2012
                Trizpug             For The People
Organizing Tests


 pycamp/setup.py:

 """Setup for pycamp package."""

                             Text
 from setuptools import setup, 
                                    find_packages




                                            Programming
PyCamp™   Copyright © 2012
              Trizpug                       For The People
Organizing Tests


 pycamp/setup.py:
 setup(
    name="pycamp",
    version="1.0", Text
    packages=find_packages(),
    author="Chris Calloway",
    author_email="cbc@chriscalloway.org",

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests


 pycamp/setup.py:
     description="Testing Fundamentals",
     license="PSF",
                    Text
     keywords="testing pycamp",
     url="http://pycamp.org",
     test_suite="pycamp.tests",
 )

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests


 > python pycamp/setup.py test
 running test
 ..lots of output omitted for brevity..
 --------------------------------------
 Ran 4 tests in 0.001s
 OK
 >

                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests




 > python pycamp/setup.py test




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests




 > python pycamp/setup.py install




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Organizing Tests




 > python pycamp/setup.py register




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Unittest Module


•unittest provides nice separation of tests from
  code

•One person can write tests, while another writes
  code to make tests pass

•unittest provides fine grain control over what
  tests to run when

•unittest conforms to industry standard testing
                                      Programming
PyCamp™     Copyright © 2012
                Trizpug               For The People
Unittest Module


•However, it can be difficult to keep tests and
  code in sync

•Also, writing code to test code can also be more
  difficult than the code under test

•What about testing and debugging the test
  code?

•Reading unittest tests is a poor way to figure
  out how code works
                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
Doctest Module


•Informally, even without written tests, you
  probably already test your code by simply using
  it as it was meant to be used

•You've probably imported your code at a Python
  prompt and inspect how it works manually

•You just don't yet have a way of repeating that
  informal testing in an automated manner

•What you need is the doctest module
                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
Doctest Module

 pyohio-+
        bin/python
        pycampNG-+
               __init__.py
               setup.py
               fibonacci.py
               triangle.py
               tests-+
                     __init__.py
                     test_pycamp.py


                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Doctest Module

 pycampNG/fibonacci.py:

 """A module of functions about non-zero
 Fibonacci numbers.

                             Text
 >>> import fibonacci
 >>>
 """


                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Doctest Module

 pycampNG/fibonacci.py:
 def fib(n):
    """Return the sequence of non-zero
    Fibonacci numbers less than n.
                             Text

    fib(n) -> [0 < fibonacci numbers < n]


    where n in an int.

                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Doctest Module

 pycampNG/fibonacci.py:
    >>> lessThan100 = [1, 2, 3, 5, 8, 13,
    ...                              21, 34, 55, 89]
    >>> fib(100) == lessThan100
                              Text
    True
    >>> fib(10) == lessThan100[:5]
    True
    """

                                             Programming
PyCamp™    Copyright © 2012
               Trizpug                       For The People
Doctest Module

 pycampNG/triangular.py:

 """A module of functions about non-zero
 triangular numbers.

                             Text
 >>> import triangular
 >>>
 """


                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Doctest Module

 pycampNG/triangular.py:
 def tri(n):
    """Return the sequence of non-zero
    triangular numbers less than n.
                             Text

    tri(n) -> [0 < triangular numbers < n]


    where n in an int.

                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Doctest Module

 pycampNG/triangular.py:
    >>> lessThan100 = [1, 3, 6, 10, 15,
                              21, 28, 36, 45,
                              55, 66, 78, 91]
                   Text
    >>> tri(100) == lessThan100
    True
    >>> tri(10) == lessThan100[:3]
    True
    """

                                      Programming
PyCamp™    Copyright © 2012
               Trizpug                For The People
Doctest Module




 > python -m doctest pycampNG/fibonacci.py
 >




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Doctest Module



 > python -m doctest -v        
                   pycampNG/fibonacci.py
 Trying:
      import fibonacci
 Expecting nothing
 ok


                                    Programming
PyCamp™    Copyright © 2012
               Trizpug              For The People
Doctest Module



 Trying:
      lessThan100 = [1, 2, 3, 5, 8, 13,
                              21, 34, 55, 89]
 Expecting nothing
 ok



                                        Programming
PyCamp™    Copyright © 2012
               Trizpug                  For The People
Doctest Module



 Trying:
      fib(100) == lessThan100
 Expecting:
      True
 ok



                                    Programming
PyCamp™      Copyright © 2012
                 Trizpug            For The People
Doctest Module



 Trying:
      fib(10) == lessThan100[:5]
 Expecting:
      True
 ok



                                    Programming
PyCamp™      Copyright © 2012
                 Trizpug            For The People
Doctest Module


 2 items passed all tests:
     1 tests in fibonacci
     3 tests in fibonacci.fib
 4 tests in 2 items.
 4 passed and 0 failed.
 Test passed.
 >

                                 Programming
PyCamp™   Copyright © 2012
              Trizpug            For The People
Doctest Module




 > python -m doctest pycampNG/triangular.py
 >




                                  Programming
PyCamp™   Copyright © 2012
              Trizpug             For The People
Doctest Module

 pycampNG/fibonacci.py:
 if __name__ == '__main__':
    if sys.argv[1].lower() == 'test':
          import doctest
                               Text
          doctest.testmod()
    else:
          print(" ".join([str(x) for x in
                      fib(int(sys.argv[1]))]))

                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
Doctest Module

 pycampNG/triangular.py:
 if __name__ == '__main__':
    if sys.argv[1].lower() == 'test':
          import doctest
                               Text
          doctest.testmod()
    else:
          print(" ".join([str(x) for x in
                      tri(int(sys.argv[1]))]))

                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
Doctest Module




 > python pycampNG/fibonacci.py test
 > python pycampNG/fibonacci.py 100
 1 2 3 5 8 13 21 34 55 89
 >




                                 Programming
PyCamp™   Copyright © 2012
              Trizpug            For The People
Doctest Module




 > python pycampNG/triangular.py test
 > python pycampNG/triangular.py 100
 1 3 6 10 15 21 28 36 45 55 66 78 91
 >




                                 Programming
PyCamp™   Copyright © 2012
              Trizpug            For The People
Doctest Module




•But what about setuptools.setup?
•The test_suite argument of setup triggers
  unittest discovery, not doctest discovery

•What you need is a way to turn doctests into
  unittests



                                     Programming
PyCamp™       Copyright © 2012
                  Trizpug            For The People
Doctest Module




•The doctest.DocTestSuite() function
  searches a module for doctests and converts
  them into a unittest.TestSuite instance

•Now all you need is a way to communicate your
  TestSuite instance(s) to unittest discovery



                                       Programming
PyCamp™     Copyright © 2012
                Trizpug                For The People
load_tests Protocol



 def load_tests(loader,
                              tests,
                              pattern):
     ...
     return tests



                                          Programming
PyCamp™    Copyright © 2012
               Trizpug                    For The People
load_tests Protocol


                                       unittest.TestLoader
 def load_tests(loader,
                              tests,
                              pattern):
     ...
     return tests



                                              Programming
PyCamp™    Copyright © 2012
               Trizpug                        For The People
load_tests Protocol



 def load_tests(loader,
                                       unittest.TestSuite
                              tests,
                              pattern):
     ...
     return tests



                                                Programming
PyCamp™    Copyright © 2012
               Trizpug                          For The People
load_tests Protocol



 def load_tests(loader,
                              tests,
                                       "test*.py"
                              pattern):
     ...
     return tests



                                              Programming
PyCamp™    Copyright © 2012
               Trizpug                        For The People
load_tests Protocol



 def load_tests(loader,
                              tests,
                              pattern):
     ...
     return tests



                                          Programming
PyCamp™    Copyright © 2012
               Trizpug                    For The People
load_tests Protocol

 pycampNG/tests/test_pycamp.py:



 import doctest
                             Text
 from pycampNG import fibonacci
 from pycampNG import triangular




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
load_tests Protocol

 pycampNG/tests/test_pycamp.py:

 def load_tests(loader, tests, pattern):
    tests.addTests(
          doctest.DocTestSuite(fibonacci))
                     Text
    tests.addTests(
          doctest.DocTestSuite(triangular))
    return tests


                                  Programming
PyCamp™    Copyright © 2012
               Trizpug            For The People
load_tests Protocol

 pycampNG/tests/test_pycamp.py:

 def load_tests(loader, tests, pattern):
    tests.addTests(
          doctest.DocTestSuite(fibonacci))
                     Text
    tests.addTests(
          doctest.DocTestSuite(triangular))
    return tests


                                  Programming
PyCamp™    Copyright © 2012
               Trizpug            For The People
load_tests Protocol

 pycampNG/tests/test_pycamp.py:

 def load_tests(loader, tests, pattern):
     tests.addTests(
          doctest.DocTestSuite(fibonacci))
                     Text
     tests.addTests(
          doctest.DocTestSuite(triangular))
    return tests


                                  Programming
PyCamp™    Copyright © 2012
               Trizpug            For The People
load_tests Protocol

 pycampNG/tests/test_pycamp.py:

 def load_tests(loader, tests, pattern):
    tests.addTests(
          doctest.DocTestSuite(fibonacci))
                     Text
    tests.addTests(
          doctest.DocTestSuite(triangular))
    return tests


                                  Programming
PyCamp™    Copyright © 2012
               Trizpug            For The People
load_tests Protocol


 pycamp/setup.py:

 setup(
     name="pycampNG",
                              Text
     ...
     test_suite="pycampNG.tests",
 )


                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
load_tests Protocol


 > python pycampNG/setup.py test
 running test
 ..lots of output omitted for brevity..
 --------------------------------------
 Ran 4 tests in 0.001s
 OK
 >

                                 Programming
PyCamp™   Copyright © 2012
              Trizpug            For The People
Doctest Module




 Together, the doctest.DocTestSuite()
 function and the load_tests protocol from the
 unittest module enable you to use all the tools
 available for unittests with doctests




                                    Programming
PyCamp™   Copyright © 2012
              Trizpug               For The People
Python Testing Tools Taxonomy




                             Programming
PyCamp™   Copyright © 2012
              Trizpug        For The People
Test Driven Development




•Doctests enable you to do Test Driven
  Development (TDD)

•TDD is where you write tests for your code
  before you write code

•Then you write code to make your tests pass

                                     Programming
PyCamp™    Copyright © 2012
               Trizpug               For The People
Test Driven Development



•When all your tests pass, then you have finished
  coding

•You can develop your code incrementally,
  writing one test at a time, then getting that one
  test to pass

•That means you can stop coding at any time
                                         Programming
PyCamp™     Copyright © 2012
                Trizpug                  For The People
Test Driven Development


•If your code needs more features, then what you
  really need is more tests, and code which makes
  those tests pass

•Writing tests lets you see what the API for your
  code is up front, instead of having it designed
  haphazardly

•Writing tests can provide the documentation for
  your code

                                        Programming
PyCamp™       Copyright © 2012
                  Trizpug               For The People
Test Driven Development




                               Programming
PyCamp™    Copyright © 2012
               Trizpug         For The People
Tomorrow 12:15pm in Barbie Tootle




                              Programming
PyCamp™   Copyright © 2012
              Trizpug         For The People
Thank You




                 pycamp@trizpug.org




                                      Programming
PyCamp™   Copyright © 2012
              Trizpug                 For The People

Más contenido relacionado

La actualidad más candente

Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Andrea Francia
 
Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTestRaihan Masud
 
unittest in 5 minutes
unittest in 5 minutesunittest in 5 minutes
unittest in 5 minutesRay Toal
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestSeb Rose
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Hong Le Van
 
Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Timo Stollenwerk
 
Unit Testing RPG with JUnit
Unit Testing RPG with JUnitUnit Testing RPG with JUnit
Unit Testing RPG with JUnitGreg.Helton
 
RPG Program for Unit Testing RPG
RPG Program for Unit Testing RPG RPG Program for Unit Testing RPG
RPG Program for Unit Testing RPG Greg.Helton
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your DatabaseDavid Wheeler
 
Unit testing on embedded target with C++Test
Unit testing on embedded  target with C++TestUnit testing on embedded  target with C++Test
Unit testing on embedded target with C++TestEngineering Software Lab
 
Interpreter RPG to Java
Interpreter RPG to JavaInterpreter RPG to Java
Interpreter RPG to Javafarerobe
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkHumberto Marchezi
 

La actualidad más candente (19)

Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008
 
Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTest
 
unittest in 5 minutes
unittest in 5 minutesunittest in 5 minutes
unittest in 5 minutes
 
Pyunit
PyunitPyunit
Pyunit
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
Python in Test automation
Python in Test automationPython in Test automation
Python in Test automation
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
 
Python testing
Python  testingPython  testing
Python testing
 
Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...
 
Unit Testing RPG with JUnit
Unit Testing RPG with JUnitUnit Testing RPG with JUnit
Unit Testing RPG with JUnit
 
RPG Program for Unit Testing RPG
RPG Program for Unit Testing RPG RPG Program for Unit Testing RPG
RPG Program for Unit Testing RPG
 
Cursus phpunit
Cursus phpunitCursus phpunit
Cursus phpunit
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your Database
 
Unit testing on embedded target with C++Test
Unit testing on embedded  target with C++TestUnit testing on embedded  target with C++Test
Unit testing on embedded target with C++Test
 
Interpreter RPG to Java
Interpreter RPG to JavaInterpreter RPG to Java
Interpreter RPG to Java
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing Framework
 
Python Programming Essentials - M39 - Unit Testing
Python Programming Essentials - M39 - Unit TestingPython Programming Essentials - M39 - Unit Testing
Python Programming Essentials - M39 - Unit Testing
 
Doing the Impossible
Doing the ImpossibleDoing the Impossible
Doing the Impossible
 

Destacado

Automated hardware testing using python
Automated hardware testing using pythonAutomated hardware testing using python
Automated hardware testing using pythonYuvaraja Ravi
 
Automated Python Test Frameworks for Hardware Verification and Validation
Automated Python Test Frameworks for Hardware Verification and ValidationAutomated Python Test Frameworks for Hardware Verification and Validation
Automated Python Test Frameworks for Hardware Verification and ValidationBarbara Jones
 
AUTOMATED TESTING USING PYTHON (ATE)
AUTOMATED TESTING USING PYTHON (ATE)AUTOMATED TESTING USING PYTHON (ATE)
AUTOMATED TESTING USING PYTHON (ATE)Yuvaraja Ravi
 
Automated Regression Testing for Embedded Systems in Action
Automated Regression Testing for Embedded Systems in ActionAutomated Regression Testing for Embedded Systems in Action
Automated Regression Testing for Embedded Systems in ActionAANDTech
 
Mocking in python
Mocking in pythonMocking in python
Mocking in pythonOoblioob
 
Учим автотесты человеческому языку с помощью Allure и PyTest
Учим автотесты человеческому языку с помощью Allure и PyTestУчим автотесты человеческому языку с помощью Allure и PyTest
Учим автотесты человеческому языку с помощью Allure и PyTestRina Uzhevko
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานAjBenny Pong
 
All about unit testing using (power) mock
All about unit testing using (power) mockAll about unit testing using (power) mock
All about unit testing using (power) mockPranalee Rokde
 
Разработка фреймворка на Python для автоматизации тестирования STB боксов
Разработка фреймворка на Python для автоматизации тестирования STB боксовРазработка фреймворка на Python для автоматизации тестирования STB боксов
Разработка фреймворка на Python для автоматизации тестирования STB боксовdelimitry
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytestSuraj Deshmukh
 
Нескучное тестирование с pytest
Нескучное тестирование с pytestНескучное тестирование с pytest
Нескучное тестирование с pytestRoman Imankulov
 
Yuva Home automation project
Yuva Home automation projectYuva Home automation project
Yuva Home automation projectYuvaraja Ravi
 
โครงงานสิ่งประดิษฐ์
โครงงานสิ่งประดิษฐ์โครงงานสิ่งประดิษฐ์
โครงงานสิ่งประดิษฐ์eeii
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานAjBenny Pong
 
Py.test
Py.testPy.test
Py.testsoasme
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานAjBenny Pong
 
Robot Framework Dos And Don'ts
Robot Framework Dos And Don'tsRobot Framework Dos And Don'ts
Robot Framework Dos And Don'tsPekka Klärck
 

Destacado (18)

Automated hardware testing using python
Automated hardware testing using pythonAutomated hardware testing using python
Automated hardware testing using python
 
Automated Python Test Frameworks for Hardware Verification and Validation
Automated Python Test Frameworks for Hardware Verification and ValidationAutomated Python Test Frameworks for Hardware Verification and Validation
Automated Python Test Frameworks for Hardware Verification and Validation
 
AUTOMATED TESTING USING PYTHON (ATE)
AUTOMATED TESTING USING PYTHON (ATE)AUTOMATED TESTING USING PYTHON (ATE)
AUTOMATED TESTING USING PYTHON (ATE)
 
Automated Regression Testing for Embedded Systems in Action
Automated Regression Testing for Embedded Systems in ActionAutomated Regression Testing for Embedded Systems in Action
Automated Regression Testing for Embedded Systems in Action
 
Embedded System Test Automation
Embedded System Test AutomationEmbedded System Test Automation
Embedded System Test Automation
 
Mocking in python
Mocking in pythonMocking in python
Mocking in python
 
Учим автотесты человеческому языку с помощью Allure и PyTest
Учим автотесты человеческому языку с помощью Allure и PyTestУчим автотесты человеческому языку с помощью Allure и PyTest
Учим автотесты человеческому языку с помощью Allure и PyTest
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงาน
 
All about unit testing using (power) mock
All about unit testing using (power) mockAll about unit testing using (power) mock
All about unit testing using (power) mock
 
Разработка фреймворка на Python для автоматизации тестирования STB боксов
Разработка фреймворка на Python для автоматизации тестирования STB боксовРазработка фреймворка на Python для автоматизации тестирования STB боксов
Разработка фреймворка на Python для автоматизации тестирования STB боксов
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Нескучное тестирование с pytest
Нескучное тестирование с pytestНескучное тестирование с pytest
Нескучное тестирование с pytest
 
Yuva Home automation project
Yuva Home automation projectYuva Home automation project
Yuva Home automation project
 
โครงงานสิ่งประดิษฐ์
โครงงานสิ่งประดิษฐ์โครงงานสิ่งประดิษฐ์
โครงงานสิ่งประดิษฐ์
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงาน
 
Py.test
Py.testPy.test
Py.test
 
รูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงานรูปเล่มวิชาโครงงาน
รูปเล่มวิชาโครงงาน
 
Robot Framework Dos And Don'ts
Robot Framework Dos And Don'tsRobot Framework Dos And Don'ts
Robot Framework Dos And Don'ts
 

Similar a Python Testing Fundamentals

Python Debugging Fundamentals
Python Debugging FundamentalsPython Debugging Fundamentals
Python Debugging Fundamentalscbcunc
 
Software development practices in python
Software development practices in pythonSoftware development practices in python
Software development practices in pythonJimmy Lai
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsGraham Dumpleton
 
PyConPL 2017 - with python: security
PyConPL 2017 - with python: securityPyConPL 2017 - with python: security
PyConPL 2017 - with python: securityPiotr Dyba
 
Python testing like a pro by Keith Yang
Python testing like a pro by Keith YangPython testing like a pro by Keith Yang
Python testing like a pro by Keith YangPYCON MY PLT
 
(Micro?)services architecture in practice
(Micro?)services architecture in practice(Micro?)services architecture in practice
(Micro?)services architecture in practiceThe Software House
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011Juan Gomez
 
Testing Sap: Modern Methodology
Testing Sap: Modern MethodologyTesting Sap: Modern Methodology
Testing Sap: Modern MethodologyEthan Jewett
 
Continuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoContinuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoPeter Bittner
 
Cypress Test Techniques-Cucumber BDD Framework,TDD,API Tests
Cypress Test Techniques-Cucumber BDD Framework,TDD,API TestsCypress Test Techniques-Cucumber BDD Framework,TDD,API Tests
Cypress Test Techniques-Cucumber BDD Framework,TDD,API TestsHiraQureshi22
 
The Art Of Debugging
The Art Of DebuggingThe Art Of Debugging
The Art Of Debuggingsvilen.ivanov
 
Prespective analytics with DOcplex and pandas
Prespective analytics with DOcplex and pandasPrespective analytics with DOcplex and pandas
Prespective analytics with DOcplex and pandasPyDataParis
 
DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest Inexture Solutions
 
Continuous Deployment To The Cloud
Continuous Deployment To The CloudContinuous Deployment To The Cloud
Continuous Deployment To The CloudMarcin Grzejszczak
 
Pipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodePipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodeKris Buytaert
 
Continuous Delivery in Practice
Continuous Delivery in PracticeContinuous Delivery in Practice
Continuous Delivery in Practicepatforna
 
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...Marcin Grzejszczak
 

Similar a Python Testing Fundamentals (20)

Python Debugging Fundamentals
Python Debugging FundamentalsPython Debugging Fundamentals
Python Debugging Fundamentals
 
Software development practices in python
Software development practices in pythonSoftware development practices in python
Software development practices in python
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
 
PyConPL 2017 - with python: security
PyConPL 2017 - with python: securityPyConPL 2017 - with python: security
PyConPL 2017 - with python: security
 
Python testing like a pro by Keith Yang
Python testing like a pro by Keith YangPython testing like a pro by Keith Yang
Python testing like a pro by Keith Yang
 
Python and test
Python and testPython and test
Python and test
 
Test
TestTest
Test
 
(Micro?)services architecture in practice
(Micro?)services architecture in practice(Micro?)services architecture in practice
(Micro?)services architecture in practice
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011
 
Testing Sap: Modern Methodology
Testing Sap: Modern MethodologyTesting Sap: Modern Methodology
Testing Sap: Modern Methodology
 
Continuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoContinuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon Otto
 
Cypress Test Techniques-Cucumber BDD Framework,TDD,API Tests
Cypress Test Techniques-Cucumber BDD Framework,TDD,API TestsCypress Test Techniques-Cucumber BDD Framework,TDD,API Tests
Cypress Test Techniques-Cucumber BDD Framework,TDD,API Tests
 
Kku2011
Kku2011Kku2011
Kku2011
 
The Art Of Debugging
The Art Of DebuggingThe Art Of Debugging
The Art Of Debugging
 
Prespective analytics with DOcplex and pandas
Prespective analytics with DOcplex and pandasPrespective analytics with DOcplex and pandas
Prespective analytics with DOcplex and pandas
 
DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest DIY in 5 Minutes: Testing Django App with Pytest
DIY in 5 Minutes: Testing Django App with Pytest
 
Continuous Deployment To The Cloud
Continuous Deployment To The CloudContinuous Deployment To The Cloud
Continuous Deployment To The Cloud
 
Pipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as CodePipeline as code for your infrastructure as Code
Pipeline as code for your infrastructure as Code
 
Continuous Delivery in Practice
Continuous Delivery in PracticeContinuous Delivery in Practice
Continuous Delivery in Practice
 
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...
Continuous Deployment To The Cloud With Spring Cloud Pipelines @WarsawCloudNa...
 

Python Testing Fundamentals

  • 1. mage Python Testing Fundamentals Python Testing Fundamentals Saturday, July 28, 2012 PyOhio Ohio State University Columbus, OH Chris Calloway University of North Carolina Department of Marine Sciences Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 2. mage Python Testing Fundamentals http://drunkenpython.org/pytestfund.pdf http://drunkenpython.org/pyohio.zip http://drunkenpython.org/pyohio.tgz Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 3. About This Tutorial •Fundamental •Python 3.2.3 •Assertion •Unittest •Doctest Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 4. Why Test? “Untested Code is Broken Code” - Phillip von Weitershausen Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 5. Why Test? •Tests help you design good code •Test help you find bugs •Tests help you document code Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 6. Assert Statements •Assert statements use the assert keyword •Assert statements raise AssertionError •Based on bool test expressions Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 7. Assert Statements keyword >>> assert 1 == 1 Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 8. Assert Statements expression >>> assert 1 == 1 Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 9. Assert Statements >>> assert expression is almost the same as: >>> if not expression: ... raise AssertionError() >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 10. Assert Statements >>> assert 1 == 1 >>> assert 1 == 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 11. Assert Statements •A second optional expression on the assert statement provides a message for the AssertionError •This helps you distinguish one assertion from another Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 12. Assert Statements second expression >>> assert 1 == 2, "Reality check" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 13. Assert Statements assert expression1, expression2 is almost the same as: if not expression1: raise AssertionError(expression2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 14. Assert Statements >>> assert 1 == 2, "Reality check" Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError: Reality check >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 15. Assert Statements •Assertions may be sprinkled liberally throughout your code to check that your code is running as expected •Think of assertions as Python's reality check •You decide what "reality" is Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 16. Assert Statements bigbiz.py: profit = bottom_line(today) assert profit > 0, "Unacceptable!" projection = growth(tomorrow) assert projection > profit, "UR fired!" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 17. Assert Statements •Assertions usually generate unhandled exceptions which halt your program Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 18. Assert Statements bigbiz.py: def bottom_line(timestamp): """Compute the profit on date.""" Text return -1e6 Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 19. Assert Statements > python bigbiz.py Traceback (most recent call last): File "bigbiz.py", line 20, in <module> assert profit > 0, "Unacceptable!" AssertionError: Unacceptable! > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 20. Assert Statements •By using Python's -i command line switch, you may interactively inspect what went wrong where the assertion was raised Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 21. Assert Statements > python -i bigbiz.py Traceback (most recent call last): File "bigbiz.py", line 20, in <module> assert profit > 0, "Unacceptable!" AssertionError: Unacceptable! >>> profit -1000000.0 >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 22. Assert Statements •By using Python's -i command line switch, you may use also Python's debugger to see what went wrong at the point of assertion Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 23. Assert Statements > python -i bigbiz.py Traceback (most recent call last): File "bigbiz.py", line 20, in <module> assert profit > 0, "Unacceptable!" AssertionError: Unacceptable! >>> import pdb >>> pdb.pm() > /Users/cbc/pyohio/bigbiz.py(20)<module>() -> assert profit > 0, "Unacceptable!" (Pdb) profit -1000000.0 (Pdb) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 24. Assert Statements •Assertions may be turned off by "optimizing" Python with the -O command line switch Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 25. Assert Statements > python -O >>> assert 1 == 2 >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 26. Assert Statements > python -O bigbiz.py Profit is -1000000.00 USD. Projected profit is -2000000.00 USD. > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 27. Assert Statements •It's a fine line whether assert statements are testing or debugging •Assert statements are slightly more sophisticated than using print •But assert statements form the basis for testing in Python •In Python, a test is an assertion of an expected result Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 28. Unittest Module •Unittest is "batteries included" in Python •Unittest helps you separate test code from the code under test •Unittest helps you write tests before code •Unittest helps you organize and discover all your tests •Unittest hooks into many other Python tools Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 29. Unittest Module >>> import unittest >>> dir(unittest) ['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner', '_TextTestResult', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__unittest', 'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'loader', 'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util'] >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 30. TestCase Class •unittest.TestCase is a class •You create TestCase subclasses •You add methods whose names start with "test" to your TestCase subclass Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 31. TestCase Class •Each test method you supply in your subclass executes a TestCase supplied method whose name starts with "assert" •A TestCase provides what is known as a "test fixture" in testing parlance •The unittest module provides many ways to run the test methods of your text fixture Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 32. TestCase Class test_operator.py: """Demonstrate the unittest module.""" Text import operator import unittest Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 33. TestCase Class test_operator.py: class TestOperator(unittest.TestCase): Text """Test the operator module.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 34. TestCase Class test_operator.py: def test_add(self): """Test the add function.""" Text self.assertEqual(operator.add(2, 2), 2 + 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 35. TestCase Class test_operator.py: def test_sub(self): """Test the sub function.""" Text self.assertEqual(operator.sub(4, 2), 4 - 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 36. TestCase Class test_operator.py: def test_mul(self): """Test the mul function.""" Text self.assertEqual(operator.mul(2, 2), 2 * 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 37. TestCase Class test_operator.py: if __name__ == "__main__": Text unittest.main() Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 38. main Class •unittest.main is also a class •unittest.main is normally only used within a script containing test fixtures •When unittest.main is instantiated, all of the tests in the script's namespace are loaded and run Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 39. main Class > python test_operator.py ... -------------------------------------- Ran 3 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 40. TestLoader Class •Notice that nowhere does it appear that your script has instantiated your TestCase subclass or execute any of its methods •unittest.main instead instantiates a special unittest.TestLoader class which has methods to search your module for TestCase classes and instantiate them Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 41. TestRunner Class •Once the TestLoader instance created by unittest.main discovers and instantiates the TestCase in your script, unittest.main instantiates a special unittest.TestRunner class which has methods to run the methods of your TestCase instances •unittest.main takes care of handling TestLoaders and TestRunners for you! Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 42. TestRunner Class TestCase unittest.main (superclass) (instance) createTests() TestOperator discover() TestLoader (subclass) (instance) runTests() TestOperator run() TestRunner (instance) (instance) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 43. main Class test_operator.py: if __name__ == "__main__": Text unittest.main(verbosity=2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 44. main Class > python test_operator.py test_add (__main__.TestOperator) Test the add function. ... ok test_mul (__main__.TestOperator) Test the mul function. ... ok test_sub (__main__.TestOperator) Test the sub function. ... ok -------------------------------------- Ran 3 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 45. main Class •Notice that your tests did not run in the same order in which they were defined •unittest.main loads the test methods from your TestCase instance's __dict__ attribute •Dictionaries are unordered •unittest.main() runs the test methods in your Python's built-in order for strings Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 46. TestCase Class test_operator.py: def test_add(self): """Test the add function.""" Text self.assertEqual(operator.add(2, 2), 2 + 3) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 47. TestCase Class > python test_operator.py F.. ====================================== FAIL: test_add (__main__.TestOperator) Test the add function. -------------------------------------- Traceback (most recent call last): File "test_operator.py", line 13, in test_add self.assertEqual(operator.add(2, 2), 2 + 3) AssertionError: 4 != 5 -------------------------------------- Ran 3 tests in 0.082s FAILED (failures=1) > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 48. TestCase Class test_operator.py: def test_add(self): """Test the add function.""" Text self.assertEqual(operator.add(2, 2), 2 + "2") Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 49. TestCase Class > python test_operator.py E.. ================================================ ERROR: test_add (__main__.TestOperator) Test the add function. ------------------------------------------------ Traceback (most recent call last): File "test_operator.py", line 13, in test_add self.assertEqual(operator.add(2, 2), 2 + "2") TypeError: unsupported operand type(s) for +: int' and 'str' ------------------------------------------------ Ran 3 tests in 0.001s FAILED (errors=1) > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 50. TestResult Class •Running a test results in one of three outcomes: ★ Success (expected result) ★ Failure (unexpected result) ★ Error (error running the test) •The outcomes of all tests are accumulated in a unittest.TestResult instance Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 51. TestResult Class •Most of the time you will not need to create your own TestResult instances •Most of the ways you will run tests will instantiate and report a TestResult for you •But to run a test always requires a TestResult instance somewhere Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 52. TestResult Class > python -m unittest test_operator ... -------------------------------------- Ran 3 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 53. TestResult Class > python -m unittest test_operator.TestOperator ... -------------------------------------- Ran 3 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 54. TestResult Class > python -m unittest test_operator.TestOperator.test_add . -------------------------------------- Ran 1 test in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 55. TestResult Class > python -m unittest test_operator.py ... -------------------------------------- Ran 3 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 56. TestResult Class > python -m unittest -v test_operator test_add (test_operator.TestOperator) Test the add function. ... ok test_mul (test_operator.TestOperator) Test the mul function. ... ok test_sub (test_operator.TestOperator) Test the sub function. ... ok -------------------------------------- Ran 3 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 57. TestResult Class > python -m unittest -h Usage: python -m unittest [options] [tests] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output -f, --failfast Stop on first failure -c, --catch Catch control-C and display results -b, --buffer Buffer stdout and stderr during test runs [tests] can be a list of any number of test modules, classes and test methods. Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 58. load_tests Protocol > python -m unittest ....... -------------------------------------- Ran 7 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 59. load_tests Protocol Alternative Usage: python -m unittest discover [options] Options: -s directory Directory to start discovery ('.' default) -p pattern Pattern to match test files ('test*.py' default) -t directory Top level directory of project (default to start directory) For test discovery all test modules must be importable from the top level directory. Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 60. TestCase Class •Notice that TestCase.assertEqual does not appear to raise an unhandled AssertionError •The TestRunner instance handles the AssertionError for failing tests and updates the TestResult instance •TestCase.assertEqual is but one of many test methods you may use in your tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 61. TestCase Class Method Tests If assertEqual(a, b) a == b assertNotEqual(a, b) a != b assertTrue(x) bool(x) is True assertFalse(x) bool(x) is False assertIs(a, b) a is b assertIsNot(a, b) a is not b assertIsNone(x) x is None assertIsNotNone(x) x is not None assertIn(a, b) a in b assertNotIn(a, b) a not in b assertIsInstance(a, b) isinstance(a, b) assertNotIsInstance(a, b) not isinstance(a, b) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 62. TestCase Class •You not only need to test if your code produces expected results, you also need to test if your code handles unexpected results in an expected manner! Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 63. TestCase Class test_operatorNG.py: def test_add_str(self): """Test bad args for add.""" Text with self.assertRaises(TypeError): operator.add(2, "2") Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 64. TestCase Class > python -m unittest test_operatorNG .... -------------------------------------- Ran 4 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 65. TestCase Class Method Tests If assertRaises(exception) exception raised exception raised and assertRaisesRegex(exception, regex) message matches regex assertWarns(warning) warning raised warning raised and assertWarnsRegex(warning, regex) message matches regex Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 66. TestCase Class Method Tests If assertAlmostEqual(a, b) round(a-b, 7) == 0 assertNotAlmostEqual(a, b) round(a-b, 7) != 0 assertGreater(a, b) a > b assertGreaterEqual(a, b) a >= b assertLess(a, b) a < b assertLessEqual(a, b) a <= b assertRegex(s, re) s matches regex assertNotRegex(s, re) s does not match regex a and b have the same assertCountEqual(a, b) elements in the same number, regardless of order Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 67. TestCase Class Method Compares assertMultiLineEqual(a, b) Strings assertSequenceEqual(a, b) Sequences assertListEqual(a, b) Lists assertTupleEqual(a, b) Tuples assertSetEqual(a, b) Sets and Frozensets assertDictEqual(a, b) Dictionaries Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 68. TestCase Class •Plus many more! >>> [attr for attr ... in dir(unittest.TestCase) ... if attr.startswith('assert')] Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 69. TestCase Class >>> help(unittest.TestCase. ... assertDictContainsSubset) Help on function assertDictContainsSubset in module unittest.case: assertDictContainsSubset(self, subset, dictionary, msg=None) Checks whether dictionary is a superset of subset. Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 70. TestSuite Class test_operatorNG2.py: """Demonstrate the unittest module.""" Text import operator import unittest Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 71. TestSuite Class test_operatorNG2.py: class TestAdd(unittest.TestCase): Text """Test the add function.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 72. TestSuite Class test_operatorNG2.py: def test_add_int(self): """Test with ints.""" Text self.assertEqual(operator.add(2, 2), 2 + 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 73. TestSuite Class test_operatorNG2.py: def test_add_str(self): """Test with strs.""" Text with self.assertRaises(TypeError): operator.add(2, "2") Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 74. TestSuite Class test_operatorNG2.py: class TestSub(unittest.TestCase): Text """Test the sub function.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 75. TestSuite Class test_operatorNG2.py: def test_sub_int(self): """Test with ints.""" Text self.assertEqual(operator.sub(4, 2), 4 - 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 76. TestSuite Class test_operatorNG2.py: def test_sub_str(self): """Test with strs.""" Text with self.assertRaises(TypeError): operator.sub(4, "2") Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 77. TestSuite Class test_operatorNG2.py: class TestMul(unittest.TestCase): Text """Test the mul function.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 78. TestSuite Class test_operatorNG2.py: def test_mul_int(self): """Test with ints.""" Text self.assertEqual(operator.mul(2, 2), 2 * 2) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 79. TestSuite Class test_operatorNG2.py: def test_mul_str(self): """Test with strs.""" Text self.assertEqual(operator.mul(2, "2"), "22") Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 80. TestSuite Class test_operatorNG2.py: str_suite = unittest.TestSuite() Text str_suite.addTest(TestAdd("test_add_str")) str_suite.addTest(TestSub("test_sub_str")) str_suite.addTest(TestMul("test_mul_str")) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 81. TestSuite Class test_operatorNG2.py: if __name__ == "__main__": Text unittest.main() Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 82. TestSuite Class •Objects you have bound in the test_operatorNG2 namespace: •TestAdd class •TestSub class •TestMul class •str_suite instance Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 83. TestSuite Class > python test_operatorNG2.py ...... -------------------------------------- Ran 6 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 84. TestSuite Class > python -m unittest test_operatorNG2.str_suite ... -------------------------------------- Ran 3 tests in 0.000s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 85. TestSuite Class > python -m unittest -v test_operatorNG2.str_suite test_add_str (test_operatorNG2.TestAdd) Test with strs. ... ok test_sub_str (test_operatorNG2.TestSub) Test with strs. ... ok test_mul_str (test_operatorNG2.TestMul) Test with strs. ... ok -------------------------------------- Ran 3 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 86. Organizing Tests pyohio-+ bin/python pycamp-+ __init__.py setup.py fibonacci.py triangle.py tests-+ __init__.py test_fibonacci.py test_triangular.py Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 87. Organizing Tests > python pycamp/fibonacci.py 100 1 2 3 5 8 13 21 34 55 89 > python >>> from pycamp.fibonacci import fib >>> fib(100) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 88. Organizing Tests > python pycamp/triangular.py 100 1 3 6 10 15 21 28 36 45 55 66 78 91 > python >>> from pycamp.triangular import tri >>> tri(100) [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91] >>> Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 89. Organizing Tests pycamp/tests/test_fibonacci.py: """Tests for the fibonacci module.""" Text from pycamp import fibonacci import unittest Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 90. Organizing Tests pycamp/tests/test_fibonacci.py: class TestFibonacci(unittest.TestCase): Text """Test fibonacci's functions.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 91. TestCase Class •TestCase also supplies methods you override •TestCase.setUp() is called before every test method you supply in your subclass •TestCase.tearDown() is called after every test method you supply in your subclass Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 92. TestCase Class •Your TestCase subclasses, along with all the test methods you supply, and all the TestCase supplied methods you override, possibly all bundled up into a TestSuite, are collectively known as a "test fixture" in testing parlance Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 93. Organizing Tests pycamp/tests/test_fibonacci.py: def setUp(self): """Test fixture build.""" Text self.lessThan100 = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ] Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 94. Organizing Tests pycamp/tests/test_fibonacci.py: def test_fib_100(self): """Test fib for numbers < 100.""" Text self.assertEqual(fibonacci.fib(100), self.lessThan100) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 95. Organizing Tests pycamp/tests/test_fibonacci.py: def test_fib_10(self): """Test fib for numbers < 10.""" Text self.assertEqual(fibonacci.fib(10), self.lessThan100[:5]) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 96. Organizing Tests pycamp/tests/test_fibonacci.py: if __name__ == "__main__": Text unittest.main() Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 97. Organizing Tests pycamp/tests/test_triangular.py: """Tests for the triangular module.""" Text from pycamp import triangular import unittest Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 98. Organizing Tests pycamp/tests/test_triangular.py: class TestTriangular(unittest.TestCase): Text """Test triangular's functions.""" Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 99. Organizing Tests pycamp/tests/test_triangular.py: def setUp(self): """Test fixture build.""" Text self.lessThan100 = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, ] Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 100. Organizing Tests pycamp/tests/test_triangular.py: def test_tri_100(self): """Test tri for numbers < 100.""" Text self.assertEqual(triangular.tri(100), self.lessThan100) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 101. Organizing Tests pycamp/tests/test_triangular.py: def test_tri_10(self): """Test tri for numbers < 10.""" Text self.assertEqual(triangular.tri(10), self.lessThan100[:3]) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 102. Organizing Tests pycamp/tests/test_triangular.py: if __name__ == "__main__": Text unittest.main() Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 103. Organizing Tests > python -m unittest discover -s pycamp -t . .... -------------------------------------- Ran 4 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 104. Organizing Tests pycamp/setup.py: """Setup for pycamp package.""" Text from setuptools import setup, find_packages Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 105. Organizing Tests pycamp/setup.py: setup( name="pycamp", version="1.0", Text packages=find_packages(), author="Chris Calloway", author_email="cbc@chriscalloway.org", Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 106. Organizing Tests pycamp/setup.py: description="Testing Fundamentals", license="PSF", Text keywords="testing pycamp", url="http://pycamp.org", test_suite="pycamp.tests", ) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 107. Organizing Tests > python pycamp/setup.py test running test ..lots of output omitted for brevity.. -------------------------------------- Ran 4 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 108. Organizing Tests > python pycamp/setup.py test Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 109. Organizing Tests > python pycamp/setup.py install Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 110. Organizing Tests > python pycamp/setup.py register Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 111. Unittest Module •unittest provides nice separation of tests from code •One person can write tests, while another writes code to make tests pass •unittest provides fine grain control over what tests to run when •unittest conforms to industry standard testing Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 112. Unittest Module •However, it can be difficult to keep tests and code in sync •Also, writing code to test code can also be more difficult than the code under test •What about testing and debugging the test code? •Reading unittest tests is a poor way to figure out how code works Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 113. Doctest Module •Informally, even without written tests, you probably already test your code by simply using it as it was meant to be used •You've probably imported your code at a Python prompt and inspect how it works manually •You just don't yet have a way of repeating that informal testing in an automated manner •What you need is the doctest module Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 114. Doctest Module pyohio-+ bin/python pycampNG-+ __init__.py setup.py fibonacci.py triangle.py tests-+ __init__.py test_pycamp.py Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 115. Doctest Module pycampNG/fibonacci.py: """A module of functions about non-zero Fibonacci numbers. Text >>> import fibonacci >>> """ Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 116. Doctest Module pycampNG/fibonacci.py: def fib(n): """Return the sequence of non-zero Fibonacci numbers less than n. Text fib(n) -> [0 < fibonacci numbers < n] where n in an int. Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 117. Doctest Module pycampNG/fibonacci.py: >>> lessThan100 = [1, 2, 3, 5, 8, 13, ... 21, 34, 55, 89] >>> fib(100) == lessThan100 Text True >>> fib(10) == lessThan100[:5] True """ Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 118. Doctest Module pycampNG/triangular.py: """A module of functions about non-zero triangular numbers. Text >>> import triangular >>> """ Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 119. Doctest Module pycampNG/triangular.py: def tri(n): """Return the sequence of non-zero triangular numbers less than n. Text tri(n) -> [0 < triangular numbers < n] where n in an int. Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 120. Doctest Module pycampNG/triangular.py: >>> lessThan100 = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91] Text >>> tri(100) == lessThan100 True >>> tri(10) == lessThan100[:3] True """ Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 121. Doctest Module > python -m doctest pycampNG/fibonacci.py > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 122. Doctest Module > python -m doctest -v pycampNG/fibonacci.py Trying: import fibonacci Expecting nothing ok Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 123. Doctest Module Trying: lessThan100 = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] Expecting nothing ok Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 124. Doctest Module Trying: fib(100) == lessThan100 Expecting: True ok Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 125. Doctest Module Trying: fib(10) == lessThan100[:5] Expecting: True ok Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 126. Doctest Module 2 items passed all tests: 1 tests in fibonacci 3 tests in fibonacci.fib 4 tests in 2 items. 4 passed and 0 failed. Test passed. > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 127. Doctest Module > python -m doctest pycampNG/triangular.py > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 128. Doctest Module pycampNG/fibonacci.py: if __name__ == '__main__': if sys.argv[1].lower() == 'test': import doctest Text doctest.testmod() else: print(" ".join([str(x) for x in fib(int(sys.argv[1]))])) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 129. Doctest Module pycampNG/triangular.py: if __name__ == '__main__': if sys.argv[1].lower() == 'test': import doctest Text doctest.testmod() else: print(" ".join([str(x) for x in tri(int(sys.argv[1]))])) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 130. Doctest Module > python pycampNG/fibonacci.py test > python pycampNG/fibonacci.py 100 1 2 3 5 8 13 21 34 55 89 > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 131. Doctest Module > python pycampNG/triangular.py test > python pycampNG/triangular.py 100 1 3 6 10 15 21 28 36 45 55 66 78 91 > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 132. Doctest Module •But what about setuptools.setup? •The test_suite argument of setup triggers unittest discovery, not doctest discovery •What you need is a way to turn doctests into unittests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 133. Doctest Module •The doctest.DocTestSuite() function searches a module for doctests and converts them into a unittest.TestSuite instance •Now all you need is a way to communicate your TestSuite instance(s) to unittest discovery Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 134. load_tests Protocol def load_tests(loader, tests, pattern): ... return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 135. load_tests Protocol unittest.TestLoader def load_tests(loader, tests, pattern): ... return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 136. load_tests Protocol def load_tests(loader, unittest.TestSuite tests, pattern): ... return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 137. load_tests Protocol def load_tests(loader, tests, "test*.py" pattern): ... return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 138. load_tests Protocol def load_tests(loader, tests, pattern): ... return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 139. load_tests Protocol pycampNG/tests/test_pycamp.py: import doctest Text from pycampNG import fibonacci from pycampNG import triangular Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 140. load_tests Protocol pycampNG/tests/test_pycamp.py: def load_tests(loader, tests, pattern): tests.addTests( doctest.DocTestSuite(fibonacci)) Text tests.addTests( doctest.DocTestSuite(triangular)) return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 141. load_tests Protocol pycampNG/tests/test_pycamp.py: def load_tests(loader, tests, pattern): tests.addTests( doctest.DocTestSuite(fibonacci)) Text tests.addTests( doctest.DocTestSuite(triangular)) return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 142. load_tests Protocol pycampNG/tests/test_pycamp.py: def load_tests(loader, tests, pattern): tests.addTests( doctest.DocTestSuite(fibonacci)) Text tests.addTests( doctest.DocTestSuite(triangular)) return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 143. load_tests Protocol pycampNG/tests/test_pycamp.py: def load_tests(loader, tests, pattern): tests.addTests( doctest.DocTestSuite(fibonacci)) Text tests.addTests( doctest.DocTestSuite(triangular)) return tests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 144. load_tests Protocol pycamp/setup.py: setup( name="pycampNG", Text ... test_suite="pycampNG.tests", ) Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 145. load_tests Protocol > python pycampNG/setup.py test running test ..lots of output omitted for brevity.. -------------------------------------- Ran 4 tests in 0.001s OK > Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 146. Doctest Module Together, the doctest.DocTestSuite() function and the load_tests protocol from the unittest module enable you to use all the tools available for unittests with doctests Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 147. Python Testing Tools Taxonomy Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 148. Test Driven Development •Doctests enable you to do Test Driven Development (TDD) •TDD is where you write tests for your code before you write code •Then you write code to make your tests pass Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 149. Test Driven Development •When all your tests pass, then you have finished coding •You can develop your code incrementally, writing one test at a time, then getting that one test to pass •That means you can stop coding at any time Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 150. Test Driven Development •If your code needs more features, then what you really need is more tests, and code which makes those tests pass •Writing tests lets you see what the API for your code is up front, instead of having it designed haphazardly •Writing tests can provide the documentation for your code Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 151. Test Driven Development Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 152. Tomorrow 12:15pm in Barbie Tootle Programming PyCamp™ Copyright © 2012 Trizpug For The People
  • 153. Thank You pycamp@trizpug.org Programming PyCamp™ Copyright © 2012 Trizpug For The People