Description

In this collection, We will cover these two: unittest - part of the Python library, similar to JUnit 3

DocTest - test by example, part of the Python library

And Other testing frameworks: Py.Test - very simple "assert" syntax.

– can also run unittest style tests

Mock objects - create "fake" external components

Study Set Content:
1- Page
background image

 

 

Unit Testing in Python

James Brucker

2- Page
background image

Python Testing Frameworks

We will cover these two:

unittest

 - part of the Python library, similar to JUnit 3

DocTest

 - test by example, part of the Python library

Other testing frameworks:

Py.Test

 - very simple "assert" syntax.

can also run unittest style tests

Mock objects

 - create "fake" external components

https://wiki.python.org/moin/PythonTestingToolsTaxonomy

3- Page
background image

unittest example

import unittest

class 

TestBuiltins

(

unittest.TestCase

):

    

"""Test some python built-in methods"""

    def 

test

_len

(self):

        self.

assertEqual

(5, len("hello"))

        self.

assertEqual

(3, len(['a','b','c']))

        

# edge case

        self.

assertEqual

(0, len(""))

    def 

test

_str_upper

(self):

        self.

assertTrue

( "ABC".isupper() )

        self.

assertFalse

( "ABc".isupper() )

        s = ""  

# edge case

        

self.assertFalse( s.isupper() )

class extends 

TestCase

4- Page
background image

Run tests from the command line

cmd>

 python -m unittest test_module

cmd>

 python -m unittest module.TestClass

cmd>

 python -m unittest tests/test_module.py

Run all tests or just specific test.  Three ways:

5- Page
background image

Other Ways to Run Tests

import unittest

class 

TestBuiltins

(

unittest.TestCase

):

    

"""Test some python built-in method"""

    def 

test_len

(self):

        self.assertEqual(5, len("hello"))
        self.assertEqual(3, len(['a','b','c']))

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

1. Let the IDE run them for you.
2. Use a test script or build tool.
3. Add a "main" script to end of your Test class...

6- Page
background image

Exercise: Try it Yourself

Test math.sqrt() and math.pow().

import unittest
import math

class 

MathTest

(

unittest.TestCase

):

    def 

test_sqrt

(self):

        self.assertEqual(5, math.sqrt(25))
        self.assertEqual(0, math.sqrt(0)) 

#edge case

    def 

test_pow

(self):

       

 #

TODO

 Write some tests of 

math.pow(x,n)

7- Page
background image

Exercise: Run Your Tests

Run on the command line:

cmd>

  python -m unittest test_math

..
----------------------------------------------------
Ran 2 tests in 0.001s

Run with verbose (-v) output

cmd>

  python -m unittest -v test_math.py

test_sqrt (test_math.MathTest) ... ok
test_pow (test_math.MathTest) ... ok
----------------------------------------------------
Ran 2 tests in 0.001s

8- Page
background image

Write two 

Failing

 Tests

import unittest
import math

class 

MathTest

(

unittest.TestCase

):

    

# This answer is WRONG. Test should fail.

    def 

test_wrong_sqrt

(self):

        self.assertEqual(1, math.sqrt(25))

    

# sqrt of negative number is not allowed.

    def 

test_sqrt_of_negative

(self):

        self.assertEqual(4, math.sqrt(-16))

9- Page
background image

Exercise: Run the Tests

Run on the command line:

cmd>

  python -m unittest math_test.py

..EF
===================================================
ERROR: test_sqrt_of_negative (math_test.MathTest)
---------------------------------------------------
Traceback (most recent call last):
  File "test_math.py", line 10, in test_sqrt_negative
    self.assertEqual(4, math.sqrt(-16))

ValueError

: math domain error

===================================================
FAIL: test_wrong_sqrt (test_math.MathTest)
Trackback (most recent call last):

AssertionError

: 1 != 5.0

10- Page
background image

Test Results

The test summary prints:

Ran 4 tests in 0.001s
FAILED (

failures

=1, 

errors

=1)

How are "

failure

" and "

error

" different?

Failure means __________________________

Error means ____________________________

11- Page
background image

Tests Outcomes

Success

:  passes all "assert"

Failure

:  fails an "assert" but code runs OK

Error

:  error while running test, such as exception raised

12- Page
background image

What Can You assert?

assertTrue

( gcd(-3,-5) > 0 )

assertFalse

( "hello".isupper() )

assertEqual

( 2*2, 4)

assertNotEqual

( "a", "b")

assertIsNone

(a)

           

# test "a is None"

assertIsNotNone

(a)

        

# test "a is not None"

assertIn

( a, list)

        

# test "a in list"

assertIsInstance

(3, int)

  

# test isinstance(a,b)

assertListEqual

( list1, list2 ) 

# all elments equal

Many more!

See "unittest" in the Python Library docs.

13- Page
background image

Skip a Test or Fail a Test

import unittest

class MyTest(unittest.TestCase):

    

@unittest.skip("Not done yet")

    def test_add_fractions(self):

        pass

    def test_fraction_constructor(self):

        

self.fail

(

"Write this test!"

)

14- Page
background image

Test for Exception

def test_sqrt_of_negative( self ):

    

"""sqrt of a negative number should throw

       ValueError.

   

 """

    self.

assert????

( math.sqrt(-1) )

What if your code should throw an exception?

15- Page
background image

Test for Exception

def test_sqrt_of_negative(self):

    

with self.assertRaises

(ValueError):

        

math.sqrt(-1)

assertRaises

 expects a block of code to raise an 

exception:

16- Page
background image

What to Name Your Tests?

1. 

Test methods

 begin with 

test_

 and use 

snake_case

.

    

def 

test_

sqrt(self)

  def 

test_

sqrt_of_negative(self)

2. 

Test class

 name

 either 

starts

 with Test (Python style) or 

ends

 with "Test" (JUnit style) and uses CamelCase.

    

class 

Test

Math(unittest.TestCase)

    

class Math

Test

(unittest.TestCase)

17- Page
background image

What to Name Your Tests?

3. 

Test filename

 should start with 

test_

 & use snake 

case 

    

test_

math.py

  

test_

list_util.py or 

test_

listutil.py

Note: 

    if test file 

ends

 with _test like 

math

_test

.py

 then 

Python's "test discovery" feature (used by Django) 
won't run the tests unless you write:

    

python -m unittest discover 

-p "*_test.py"

18- Page
background image

Exercise: Test Driven Development

Write some tests for this function 

before

 you write the 

function body.  Just return 0:

def average( lst ):

    

"""Return average of a list of numbers"""

    return 0

19- Page
background image

Exercise: Define Test Cases

1. 

Typical case

:  list contains a few numbers

2. 

Edge cases

:  a) list with only 1 number, 

    b) list with many values all the same, 
    c) list containing some 0 values (changes average).

3. 

Illegal case

:  empty list

    

What should happen in this case??

**

**

Hint:  Python has a builtin 

max(list)

 function.

 

TDD forces you to think about 

what the code 

should do

.

20- Page
background image

Write the Tests

File: 

test_average.py

import unittest

from listutil import average

class TestAverage(unittest.TestCase):

    def test_average_singleton_list(self):

self.assertEqual( 5, average([5]) )

  def test_list_with_many_values(self):

       

# test average of many values

    def test_average_of_empty_list(self):

       

# test that average([]) throws exception

10 minutes

thumb_up_alt Subscribers
layers 31 Items
folder Computer Category
0.00
0 Reviews
Share It Now!