python unittest (draft)

def add(a, b):
    return a + b

def minus(a, b):
    return a - b

def multi(a, b):
    return a * b

def divide(a, b):
    return a / b

import unittest
import HtmlTestRunner

class TestMathFunc(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("Set up class")

    @classmethod
    def tearDownClass(cls):
        print("Tear down class")

    def setUp(self):
        print("Set up test cases")

    def tearDown(self):
        print("Tear down")

    def test_add(self):
        print("call test method:%s" % "test_add")
        self.assertEqual(3, add(2, 1))
        self.assertNotEqual(5, add(1, 3))

    def test_minus(self):
        print("call test method:%s" % "test_minus")
        self.assertEqual(1, minus(10, 9))

    def test_multi(self):
        print("call test method:%s" % "test_multi")
        self.assertEqual(4, multi(2, 2))

    def test_divide(self):
        print("call test method:%s" % "test_divide")
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2.5, divide(5, 2))
        self.assertRaises(ZeroDivisionError, divide, 10, 0.1)

    def aaa_add(self):
        print("call test method:%s" % "aaa_add")
        self.assertEqual(10, add(8, 2))

使用unittest.main() 方法执行

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

输出:

Set up class.
Set up test cases
call test method:test_add
Tear down
Set up test cases
call test method:test_divide
Tear down
F.Set up test cases.
call test method:test_minus
Tear down
Set up test cases
call test method:test_multi
Tear down
Tear down class

======================================================================
FAIL: test_divide (__main__.TestMathFunc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\workspace\pythonProject\testProject\test\mathfunctester.py", line 54, in test_divide
    self.assertRaises(ZeroDivisionError, divide, 10, 0.1)
AssertionError: ZeroDivisionError not raised by divide

----------------------------------------------------------------------
Ran 4 tests in 0.001s

使用“unittest.main()”执行测试用例时,每个测试方法必须以“test”开头,否则unittest无法识别。例如,上面代码中的“aaa_add”方法未执行。

每个测试方法执行顺序并不是按照代码的书写顺序执行,而是按照前缀“test”后的字母顺序执行的。

setUp()方法
setUp()方法一般用来准备测试环境,在每个测试方法执行之前执行。

tearDown()方法
tearDown()方法一般用来清理测试环境,在每个测试方法执行之后执行,且不论测试方法执行是否成功。

setUpClass()方法
setUpClass()方法一般用来在所有测试方法执行之前准备一次测试环境,必须使用“@classmethod”装饰符,在所有测试方法执行前执行。

tearDownClass()
tearDownClass()方法一般用来在所有测试方法结束之后清理一次测试环境,必须使用“@classmethod”装饰符,在所有测试方法都执行完成否执行。

skip装饰器
不希望执行某个测试方法时,可以使用skip装饰器。skip装饰器共有三种:unittest.skip(reason)、unittest.skipIf(condition, reason)、unittest.skipUnless(condition, reason)。

那么,如何控制测试方法的执行顺序呢?如何执行非“test”开头的测试方法?接下来了解一下TestSuite。

TestSuite — 单元测试用例合集

if __name__ == '__main__':
    suite = unittest.TestSuite()
    tests = [TestMathFunc("test_add"), TestMathFunc("test_minus")]
    suite.addTest(TestMathFunc('test_multi'))
    suite.addTest(TestMathFunc('test_divide'))
    suite.addTests(tests)
    suite.addTest(TestMathFunc('aaa_add'))
    # with open('testResults.txt', 'w') as f:
    #     runner = unittest.TextTestRunner(stream=f, verbosity=2)
    #     runner.run(suite)
    with open('testResult.html', 'w') as f:
        runner = HtmlTestRunner.HTMLTestRunner(output='./')
        runner.run(suite)

输出:

Running tests... 
----------------------------------------------------------------------
 test_multi (__main__.TestMathFunc) ... OK (0.000000)s
 test_divide (__main__.TestMathFunc) ... FAIL (0.000992)s
 test_add (__main__.TestMathFunc) ... OK (0.000000)s
 test_minus (__main__.TestMathFunc) ... OK (0.000000)s
 aaa_add (__main__.TestMathFunc) ... OK (0.000000)s

======================================================================
FAIL [0.000992s]: test_divide (__main__.TestMathFunc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\workspace\pythonProject\testProject\test\mathfunctester.py", line 54, in test_divide
    self.assertRaises(ZeroDivisionError, divide, 10, 0.1)
AssertionError: ZeroDivisionError not raised by divide
Set up test cases
call test method:test_divide
Tear down

----------------------------------------------------------------------
Ran 5 tests in 0:00:00

FAILED
 (Failures=1)

Generating HTML reports... 
[Finished in 0.4s]

通过TestSuite, 可以执行非test开头的测试方法, 可以控制case执行的顺序。

注意:如果通过unittest.TestLoader()加载TestCase,测试方法是按照前缀“test”后的字母顺序执行的,并且非test前缀的 测试方法不会执行。

if __name__ == '__main__':
    suite = unittest.TestSuite() 
    suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))
    with open('testResult.html', 'w') as f:
        runner = HtmlTestRunner.HTMLTestRunner(output='./')
        runner.run(suite)
    # unittest.main()

Running tests... 
----------------------------------------------------------------------
 test_add (__main__.TestMathFunc) ... OK (0.000000)s
 test_divide (__main__.TestMathFunc) ... FAIL (0.000496)s
 test_minus (__main__.TestMathFunc) ... OK (0.000000)s
 test_multi (__main__.TestMathFunc) ... OK (0.000000)s

======================================================================
FAIL [0.000496s]: test_divide (__main__.TestMathFunc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\workspace\pythonProject\testProject\test\mathfunctester.py", line 54, in test_divide
    self.assertRaises(ZeroDivisionError, divide, 10, 0.1)
AssertionError: ZeroDivisionError not raised by divide
Set up test cases
call test method:test_divide
Tear down

----------------------------------------------------------------------
Ran 4 tests in 0:00:00

FAILED
 (Failures=1)

Generating HTML reports... 
[Finished in 0.4s]

你可能感兴趣的:(python unittest (draft))