Python测试代码unittest简单使用笔记,增加Python3标准库内容。
学习Python有段时间了,关于测试的部分基本没咋学过,初学的时候看不懂,现在都2018年了,回头再来学习下,要不然一点不了解说不过去。
首先参考的是入门初级《Python编程从入门到实践》第11章,测试代码。
Python标准库中的模块unittest提供了代码测试工具。单元测试用于何时函数的某个方法没有问题;
测试用例是一组单元测试,这些单元测试一起核实函数在各种情况下的行为都符合要求。
良好的测试用例考虑到了函数可能收到的各种输入,包含针对目标情形的测试。
全覆盖测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要实现全覆盖很难。
通常,最初只要针对代码的重要行为编写测试既可,等项目被广泛使用时再考虑全覆盖。
首先编写一个测试函数
def get_formatted_name(first, last): full_name = first + ' ' + last return full_name.title()
然后编写一个测试该函数的类
import unittest from name_function import get_formatted_name # 编写一个测时类继承unittest.TestCase class NamesTestCase(unittest.TestCase): # 定义一个测试的方法,方法名字要以test开头,这样在unittest.main()执行的时候会自动执行 def test_first_last_name(self): # 调用被测试的函数,输入参数,并通过变量接收 formatted_name = get_formatted_name('janis', 'joplin') # 通过assertEqual判断测试函数返回的,与实际正确的结果是否一致。 self.assertEqual(formatted_name, 'Janis Joplin') if __name__ == '__main__': unittest.main()
执行该脚本
shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
一个点表示一个测试方法通过了,第二个是花费的时间,第三个参数为所有的测试方法都通过了。
故意搞错了试试。
def get_formatted_name(first, middle, last): full_name = first + ' ' + middle + ' ' + last return full_name.title()
把函数改成三个参数输入的。
运行测试的输出
shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py E ====================================================================== ERROR: test_first_last_name (__main__.NamesTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_name_function.py", line 10, in test_first_last_name formatted_name = get_formatted_name('janis', 'joplin') TypeError: get_formatted_name() missing 1 required positional argument: 'last' ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1)
测试没通过,就要新办法去修改你的函数,让其通过
def get_formatted_name(first, last, middle=''):
if middle:
full_name = first + ' ' + middle + ' ' + last
else:
full_name = first + ' ' +last
return full_name.title()
改成这样就又可以通过了。
因为这个函数可以接收三个参数,所以原来的测试类上面添加一个测试的方法。
import unittest from name_function import get_formatted_name # 编写一个测时类继承unittest.TestCase class NamesTestCase(unittest.TestCase): # 定义一个测试的方法,方法名字要以test开头,这样在unittest.main()执行的时候会自动执行 def test_first_last_name(self): # 调用被测试的函数,输入参数,并通过变量接收 formatted_name = get_formatted_name('janis', 'joplin') # 通过assertEqual判断测试函数返回的,与实际正确的结果是否一致。 self.assertEqual(formatted_name, 'Janis Joplin') def test_first_last_middle_name(self): formatted_name = get_formatted_name( 'wolfgang', 'mozart', 'amadeus' ) self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart') if __name__ == '__main__': unittest.main()
返回的结果
shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
作业不写了,基本跟书上的一模一样,只不过把名字改成了城市。
测试类。
各种断言方法
self.assertEqual(a,b) 核实 a == b
self.assertNotEqual(a, b) 核实 a != b
assertTrue(x) 核实x为True
assertFalse(x) 核实x为False
assertIn(item, list) 核实item在list中
assertNotIn(item, list) 核实item不在list中
看了一下,其实跟测试函数差不多。
先些测试准备被测试的类
class AnonymousSurvey: def __init__(self, question): self.question = question self.responses = [] def show_question(self): print(self.question) def store_response(self, new_response): self.responses.append(new_response) def show_results(self): print('Survey result:') for response in self.responses: print('- ' + response)
在写一个脚本使用这个类
from survey import AnonymousSurvey question = "What language did you first learn to spaek?" my_survey = AnonymousSurvey(question) my_survey.show_question() print('Enter "q" at any time to quit.\n') while True: response = input("Language: ") if response == 'q': break my_survey.store_response(response) print('\nThank you to everyone who participated in the survey!') my_survey.show_results()
运行脚本显示的情况
/usr/local/bin/python3.7 /Users/shijianzhong/study/测试/Python从入门到实践/language_survey.py What language did you first learn to spaek? Enter "q" at any time to quit. Language: python Language: java Language: js Language: q Thank you to everyone who participated in the survey! Survey result: - python - java - js
编写测试 AnonymousSurvey的类,因为每添加一门语言,在实例的responses属性里面都会多一门,所以测试的时候用了AssertIn()
import unittest from survey import AnonymousSurvey # 创建测试类 class TestAnonymousSurvey(unittest.TestCase): # 首先针对只输入了一门语言的情况 def test_store_single_response(self): question = "What language did you first learn to spaek?" my_survey = AnonymousSurvey(question) # 保存一门语言 my_survey.store_response('English') # 准备测试,这么语言是否在对象的responses属性里面 self.assertIn('English', my_survey.responses) if __name__ == '__main__': unittest.main()
shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_survey.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
后面写测试三个答案时候,是否也能妥善保管
import unittest from survey import AnonymousSurvey # 创建测试类 class TestAnonymousSurvey(unittest.TestCase): # 首先针对只输入了一门语言的情况 def test_store_single_response(self): question = "What language did you first learn to spaek?" my_survey = AnonymousSurvey(question) # 保存一门语言 my_survey.store_response('English') # 准备测试,这么语言是否在对象的responses属性里面 self.assertIn('English', my_survey.responses) def test_store_three_responses(self): question = "What language did you first learn to spaek?" my_survey = AnonymousSurvey(question) # 答案列表 responses = ['English', 'Spanish', 'Mandarin'] for response in responses: # 把答案先存起来 my_survey.store_response(response) for response in responses: # 测试所有的答案到底在不在实例的responses里面 self.assertIn(response, my_survey.responses) if __name__ == '__main__': unittest.main()
shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_survey.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
方法setUp()
前面的测试,每次测试都要在测试方法中实例化对象,很蛮烦,所以有了setUp方法,就好比普通类里面的__init__,在每次执行的时候,该方法内的逻辑会先执行。
import unittest from survey import AnonymousSurvey # 创建测试类 class TestAnonymousSurvey(unittest.TestCase): def setUp(self) -> None: question = "What language did you first learn to spaek?" # 对象变成实例属性,后面大家可以用 self.survey = AnonymousSurvey(question) # 答案列表 self.responses = ['English', 'Spanish', 'Mandarin'] # 首先针对只输入了一门语言的情况 def test_store_single_response(self): # 从答案列表拿一个元素出来,进行存储操作 self.survey.store_response(self.responses[0]) # 准备测试,这么语言是否在对象的responses属性里面 self.assertIn(self.responses[0], self.survey.responses) def test_store_three_responses(self): for response in self.responses: # 把答案先存起来 self.survey.store_response(response) for response in self.responses: # 测试所有的答案到底在不在实例的responses里面 self.assertIn(response, self.survey.responses) if __name__ == '__main__': unittest.main()
运行结果是一样的。这本书中的学习结束,作业不做了,这个书中的作业太简单了。
从另外一本书上看到,说写函数或者方法之前应该先写测试,这个感觉。。。。。。好苛刻啊。。。。。。
以前写过unittest,嗨,一段时间没用忘记了,重新记录一下,新添加一些内容,以后自己写的类或者函数可以测试下。
import unittest class SimplisticTest(unittest.TestCase): def test(self): a = 'a' b = 'a' self.assertEqual(a, b)
这个一个简单的单元测试,可以在终端运行python -m unittest 文件名运行
测试的结果一般有三种
1、通过
2、没有通过,产生了AssertionError的异常
3、产生了AssertionError以外的异常
代码
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest class OutcomesTest(unittest.TestCase): def testPass(self): return def testFail(self): self.assertFalse(True) def testError(self): raise RuntimeError('Test error!')
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_outcomes.py EF. ====================================================================== ERROR: testError (unittest_outcomes.OutcomesTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_outcomes.py", line 15, in testError raise RuntimeError('Test error!') RuntimeError: Test error! ====================================================================== FAIL: testFail (unittest_outcomes.OutcomesTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_outcomes.py", line 12, in testFail self.assertFalse(True) AssertionError: True is not false ---------------------------------------------------------------------- Ran 3 tests in 0.000s FAILED (failures=1, errors=1)
可以添加一些测试失败的信息输出(代码)
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest class FailureMessageTest(unittest.TestCase): def testFail(self): self.assertFalse(True, 'failure message goes here')
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python3 -m unittest unittest_failwithmessage.py F ====================================================================== FAIL: testFail (unittest_failwithmessage.FailureMessageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_failwithmessage.py", line 9, in testFail self.assertFalse(True, 'failure message goes here') AssertionError: True is not false : failure message goes here ---------------------------------------------------------------------- Ran 1 test in 0.000s
断言真假(代码)
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest class TruthTest(unittest.TestCase): def testAssertTure(self): # 返回一个通过 self.assertTrue(True) def testAssertFalse(self): # 返回一个不通过 self.assertFalse(False,'This is False')
输出
Try `python -h' for more information. (base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_truth.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
测试相等性
import unittest class EqualityTest(unittest.TestCase): def testExpectEqual(self): self.assertEqual(1, 3 - 2) def testExpectEqualFails(self): self.assertEqual(2, 3 - 2, msg='Equal fail') def testExpectNotEqual(self): self.assertNotEqual(2, 3 - 2) def testExpectNotEqualFails(self): self.assertNotEqual(1, 3 - 2)
输出:
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_equality.py .F.F ====================================================================== FAIL: testExpectEqualFails (unittest_equality.EqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality.py", line 13, in testExpectEqualFails self.assertEqual(2, 3 - 2, msg='Equal fail') AssertionError: 2 != 1 : Equal fail ====================================================================== FAIL: testExpectNotEqualFails (unittest_equality.EqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality.py", line 19, in testExpectNotEqualFails self.assertNotEqual(1, 3 - 2) AssertionError: 1 == 1 ---------------------------------------------------------------------- Ran 4 tests in 0.000s FAILED (failures=2)
几乎相等(用在浮点数的操作)
import unittest class AlmostEqualTest(unittest.TestCase): def testEqual(self): self.assertEqual(1.1, 3.3 - 2.2) def testAlmostEqual(self): self.assertAlmostEqual(1.1, 3.3 - 2.2, places=1) def testNotAlmostEqual(self): self.assertNotAlmostEqual(1.1, 3.3 - 2.0, places=1)
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python3 -m unittest unittest_almostequal.py .F. ====================================================================== FAIL: testEqual (unittest_almostequal.AlmostEqualTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_almostequal.py", line 10, in testEqual self.assertEqual(1.1, 3.3 - 2.2) AssertionError: 1.1 != 1.0999999999999996 ---------------------------------------------------------------------- Ran 3 tests in 0.000s FAILED (failures=1)
容器
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import textwrap import unittest class ContainerEqualityTest(unittest.TestCase): def testCount(self): # 测试两个对象元素的个数是否相等,元素的各个数量是否相等 self.assertCountEqual( [1, 2, 3, 2], [1, 3, 2, 3] ) # 测试字典是否相等 def testDict(self): self.assertDictEqual( {'a': 1, 'b': 2}, {'a': 1, 'b': 3} ) # 测试列表是否相等 def testList(self): self.assertListEqual( [1, 2, 3], [1, 3, 2] ) # 测试多行字符串是否相等 def testMultiLineString(self): # textwrap.dedent去除字符串的前后空格 self.assertMultiLineEqual( textwrap.dedent(''' This string has more than one line. '''), textwrap.dedent(''' This string has more than two lines. ''') ) # 测试两个序列是否相等,元祖可以与列表测试 def testSequence(self): self.assertSequenceEqual( [1, 2, 3], [1, 3, 2] ) def testSet(self): self.assertSetEqual( set([1, 2, 3]), set([1, 3, 2, 4]) ) def testTuple(self): self.assertTupleEqual( (1, 'a'), (1, 'b') )
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_equality_container.py FFFFFFF ====================================================================== FAIL: testCount (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 12, in testCount self.assertCountEqual( AssertionError: Element counts were not equal: First has 2, Second has 1: 2 First has 1, Second has 2: 3 ====================================================================== FAIL: testDict (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 19, in testDict self.assertDictEqual( AssertionError: {'a': 1, 'b': 2} != {'a': 1, 'b': 3} - {'a': 1, 'b': 2} ? ^ + {'a': 1, 'b': 3} ? ^ ====================================================================== FAIL: testList (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 26, in testList self.assertListEqual( AssertionError: Lists differ: [1, 2, 3] != [1, 3, 2] First differing element 1: 2 3 - [1, 2, 3] + [1, 3, 2] ====================================================================== FAIL: testMultiLineString (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 34, in testMultiLineString self.assertMultiLineEqual( AssertionError: '\nThis string\nhas more than one\nline.\n' != '\nThis string has\nmore than two \nlines.\n' - This string + This string has ? ++++ - has more than one + more than two - line. + lines. ? + ====================================================================== FAIL: testSequence (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 49, in testSequence self.assertSequenceEqual( AssertionError: Sequences differ: [1, 2, 3] != [1, 3, 2] First differing element 1: 2 3 - [1, 2, 3] + [1, 3, 2] ====================================================================== FAIL: testSet (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 55, in testSet self.assertSetEqual( AssertionError: Items in the second set but not the first: 4 ====================================================================== FAIL: testTuple (unittest_equality_container.ContainerEqualityTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_equality_container.py", line 61, in testTuple self.assertTupleEqual( AssertionError: Tuples differ: (1, 'a') != (1, 'b') First differing element 1: 'a' 'b' - (1, 'a') ? ^ + (1, 'b') ? ^ ---------------------------------------------------------------------- Ran 7 tests in 0.002s FAILED (failures=7)
使用assertIn()来测试容器的成员关系。代码
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest class ContaineMembershipTest(unittest.TestCase): def testDict(self): self.assertIn(4, {1: 'a', 2: 'b', 3: 'c'}) def testList(self): self.assertIn(4, [1, 2, 3]) def testSet(self): self.assertIn(4, {1, 2, 3})
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_in FFF ====================================================================== FAIL: testDict (unittest_in.ContaineMembershipTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_in.py", line 10, in testDict self.assertIn(4, {1: 'a', 2: 'b', 3: 'c'}) AssertionError: 4 not found in {1: 'a', 2: 'b', 3: 'c'} ====================================================================== FAIL: testList (unittest_in.ContaineMembershipTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_in.py", line 13, in testList self.assertIn(4, [1, 2, 3]) AssertionError: 4 not found in [1, 2, 3] ====================================================================== FAIL: testSet (unittest_in.ContaineMembershipTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_in.py", line 16, in testSet self.assertIn(4, {1, 2, 3}) AssertionError: 4 not found in {1, 2, 3} ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=3)
测试上浮错误的函数,用方法assertRaises
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest def raise_error(*args, **kwargs): raise ValueError('Invalid value: ' + str(args) + str(kwargs)) class ExceptionTest(unittest.TestCase): # 普通的逻辑测试 def testTrapLocally(self): try: raise_error('a', b='c') except ValueError: ... else: self.fail('Did not see valueError') # 内置的assertRaises测试 def testAssertRaises(self): self.assertRaises( ValueError, raise_error, 'a', b='c', )
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_exception.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
测试固件,在测试种添加额外的模块,类或者实例的属性
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import random import unittest # 第一个进 def setUpModule(): print('In setUpModule()') # 最后一个出 def tearDownModule(): print('In teatDownModule()') class FixturesTest(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print('In setUpClass()') cls.good_range = range(10) @classmethod def tearDownClass(cls) -> None: print('In tearDownClass()') del cls.good_range
# 每个测试都会启动,测试之前 def setUp(self) -> None: super(FixturesTest, self).setUp() print('\nIn setUp()') self.vales = random.randint(self.good_range.start, self.good_range.stop-1)
# 每个测试都会启动,测试之后 def tearDown(self) -> None: print('In tearDown()') del self.vales super(FixturesTest, self).tearDown() def test1(self): print('In test1()') self.assertIn(self.vales, self.good_range) def test2(self): print('In test2()') self.assertIn(self.vales, self.good_range)
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest unittest_fixtures.py In setUpModule() In setUpClass() In setUp() In test1() In tearDown() . In setUp() In test2() In tearDown() .In tearDownClass() In teatDownModule() ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
如果清理固件的过程种出现错误,那么tearDown方法可能不会被调用,为了确保总能正确的释放固件,要使用addCleanup()方法
代码
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import random import shutil import tempfile import unittest def remove_tmpdir(dirname): print(f'In remove_tmpdir() path:{dirname}') shutil.rmtree(dirname) class FixturesTest(unittest.TestCase): # 每次测试都会调用 def setUp(self) -> None: super(FixturesTest, self).setUp() self.tmpdir = tempfile.mkdtemp() self.addCleanup(remove_tmpdir, self.tmpdir) def test1(self): print('\nIn test1()') def test2(self): print('\nIn test2()')
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest -v unittest_addcleanup.py test1 (unittest_addcleanup.FixturesTest) ... In test1() In remove_tmpdir() path:/var/folders/m3/98pgmzbn44vg8btxff80mrm80000gn/T/tmpndg93pqi ok test2 (unittest_addcleanup.FixturesTest) ... In test2() In remove_tmpdir() path:/var/folders/m3/98pgmzbn44vg8btxff80mrm80000gn/T/tmp2g2mk_6e ok ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK (base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$
用不同输入重复测试
import unittest class SubTest(unittest.TestCase): def test_combined(self): self.assertRegex('abc', 'a') self.assertRegex('abc', 'B') # 下面的不会执行 self.assertRegex('abc', 'c') self.assertRegex('abc', 'd') # 通过with self.subTest创建上下文空间 def test_with_subtest(self): for pat in ['a', 'B', 'c', 'd']: with self.subTest(pattern=pat): self.assertRegex('abc', pat)
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest -v unittest_subtest.py test_combined (unittest_subtest.SubTest) ... FAIL test_with_subtest (unittest_subtest.SubTest) ... ====================================================================== FAIL: test_combined (unittest_subtest.SubTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_subtest.py", line 10, in test_combined self.assertRegex('abc', 'B') AssertionError: Regex didn't match: 'B' not found in 'abc' ====================================================================== FAIL: test_with_subtest (unittest_subtest.SubTest) (pattern='B') ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_subtest.py", line 19, in test_with_subtest self.assertRegex('abc', pat) AssertionError: Regex didn't match: 'B' not found in 'abc' ====================================================================== FAIL: test_with_subtest (unittest_subtest.SubTest) (pattern='d') ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_subtest.py", line 19, in test_with_subtest self.assertRegex('abc', pat) AssertionError: Regex didn't match: 'd' not found in 'abc' ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=3) (base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$
跳过测试
在一些特定的环境下,跳过一些测试,用了Python的装饰器
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import sys import unittest class SkippingTest(unittest.TestCase): # 一直跳过 @unittest.skip('always skipped') def test(self): self.assertTrue(False) @unittest.skipIf(sys.version_info[0] > 2, 'only runs on python2') def test_python2_only(self): self.assertTrue(False) # 除非条件成立取执行装饰器下面的 @unittest.skipUnless(sys.platform == 'Darwin', 'only runs on macOS') def test_macos_only(self): self.assertTrue(False) def test_raise_skiptest(self): # 直接跳过 raise unittest.SkipTest('skipping via exception')
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest -v unittest_skip.py test (unittest_skip.SkippingTest) ... skipped 'always skipped' test_macos_only (unittest_skip.SkippingTest) ... skipped 'only runs on macOS' test_python2_only (unittest_skip.SkippingTest) ... skipped 'only runs on python2' test_raise_skiptest (unittest_skip.SkippingTest) ... skipped 'skipping via exception' ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK (skipped=4) (base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$
忽略失败的测试,用装饰器@unittest.expectedFailure
代码
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import unittest class Test(unittest.TestCase): @unittest.expectedFailure def test_never_passed(self): self.assertTrue(False) @unittest.expectedFailure def test_always_passed(self): self.assertTrue(True) def test3(self): self.assertTrue(True) def test4(self): self.assertFalse(True)
输出
(base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$ python -m unittest -v unittest_expectedfailure.py test3 (unittest_expectedfailure.Test) ... ok test4 (unittest_expectedfailure.Test) ... FAIL test_always_passed (unittest_expectedfailure.Test) ... unexpected success test_never_passed (unittest_expectedfailure.Test) ... expected failure ====================================================================== FAIL: test4 (unittest_expectedfailure.Test) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/shijianzhong/work_space/new_platfrom/platform/smt/test_directory/unittest_study/unittest_expectedfailure.py", line 20, in test4 self.assertFalse(True) AssertionError: True is not false ---------------------------------------------------------------------- Ran 4 tests in 0.000s FAILED (failures=1, expected failures=1, unexpected successes=1) (base) shijianzhongdeMacBook-Pro:unittest_study shijianzhong$
结束