python单元测试框架-Python unittest单元测试框架总结
什么是單元測(cè)試
單元測(cè)試是用來(lái)對(duì)一個(gè)模塊、一個(gè)函數(shù)或者一個(gè)類來(lái)進(jìn)行正確性檢驗(yàn)的測(cè)試工作。
比如對(duì)于函數(shù)abs(),我們可以編寫的測(cè)試用例為:
(1)輸入正數(shù),比如1、1.2、0.99,期待返回值與輸入相同
(2)輸入復(fù)數(shù),比如-1、-1.2、-0.99,期待返回值與輸入相反
(3)輸入0,期待返回0
(4)輸入非數(shù)值類型,比如None、[]、{}、期待拋出TypeError
把上面這些測(cè)試用例放到一個(gè)測(cè)試模塊里,就是一個(gè)完整的單元測(cè)試
unittest工作原理
unittest中最核心的四部分是:TestCase,TestSuite,TestRunner,TestFixture
(1)一個(gè)TestCase的實(shí)例就是一個(gè)測(cè)試用例。測(cè)試用例就是指一個(gè)完整的測(cè)試流程,包括測(cè)試前準(zhǔn)備環(huán)境的搭建(setUp),執(zhí)行測(cè)試代碼(run),以及測(cè)試后環(huán)境的還原(tearDown)。元測(cè)試(unit test)的本質(zhì)也就在這里,一個(gè)測(cè)試用例是一個(gè)完整的測(cè)試單元,通過運(yùn)行這個(gè)測(cè)試單元,可以對(duì)某一個(gè)問題進(jìn)行驗(yàn)證。
(2)而多個(gè)測(cè)試用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
(3)TestLoader是用來(lái)加載TestCase到TestSuite中的。
(4)TextTestRunner是來(lái)執(zhí)行測(cè)試用例的,其中的run(test)會(huì)執(zhí)行TestSuite/TestCase中的run(result)方法
(5)測(cè)試的結(jié)果會(huì)保存到TextTestResult實(shí)例中,包括運(yùn)行了多少測(cè)試用例,成功了多少,失敗了多少等信息。
綜上,整個(gè)流程就是首先要寫好TestCase,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來(lái)運(yùn)行TestSuite,運(yùn)行的結(jié)果保存在TextTestResult中,整個(gè)過程集成在unittest.main模塊中。
python unittest簡(jiǎn)介
unittest是python下的單元測(cè)試框架,是java JUnit的python版本, 跟其它語(yǔ)言下的單元測(cè)試框架風(fēng)格類似,unittest支持自動(dòng)化測(cè)試、共享setup和teardown代碼、測(cè)試聚合成集、獨(dú)立于報(bào)告框架。unittest模塊提供了一個(gè)豐富的工具集用于構(gòu)建和執(zhí)行用例,先看一個(gè)入門的例子:
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual("foo".upper(), "FOO")
def test_isupper(self):
self.assertTrue("FOO".isupper())
self.assertFalse("Foo".isupper())
def test_split(self):
s = "hello world"
self.assertEqual(s.split(), ["hello", "world"])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
if __name__ == "__main__":
unittest.main()
可以通過繼承unittest.TestCase創(chuàng)建一個(gè)測(cè)試用例TestStringMethods,在這個(gè)用例中定義了測(cè)試函數(shù),這些函數(shù)名字都以”test”開頭,在執(zhí)行測(cè)試用例TestStringMethods時(shí),這些方法會(huì)被自動(dòng)調(diào)用。每個(gè)測(cè)試函數(shù)中都調(diào)用了assertTrue()和assertFalse()方法檢查預(yù)期結(jié)果,或者使用assertRaises()確認(rèn)產(chǎn)生了一個(gè)特定異常。現(xiàn)在來(lái)看一下這段代碼的運(yùn)行結(jié)果:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
有時(shí)我們需要在用例執(zhí)行前后做一些工作如初始化和清理,這就需要實(shí)現(xiàn)setUp()和tearDown()方法
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
print("setUp()")
def test_1(self):
print("test_1")
def test_2(self):
print("test_2")
def tearDown(self):
print("tearDown()")
if __name__ == "__main__":
unittest.main()
運(yùn)行結(jié)果:
setUp()
.test_1
tearDown()
setUp()
.test_2
tearDown()
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
注:如果setUp()執(zhí)行成功(沒有異常發(fā)生),那么無(wú)論測(cè)試方法是否通過,tearDown()都會(huì)被執(zhí)行
根據(jù)所測(cè)的特性測(cè)試用例被組合在一起,通過調(diào)用unittest.main(),unittest測(cè)試框架會(huì)自動(dòng)收集所有模塊的測(cè)試用例然后執(zhí)行。
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
print("WidgetTestCase setUp()")
def test_Widget(self):
print("test_Widget")
def tearDown(self):
print("WidgetTestCase tearDown()")
class FuncTestCase(unittest.TestCase):
def setUp(self):
print("FuncTestCase setUp()")
def test_func(self):
print("test_func")
def tearDown(self):
print("FuncTestCase tearDown()")
if __name__ == "__main__":
unittest.main()
運(yùn)行結(jié)果:
FuncTestCase setUp()
test_func
FuncTestCase tearDown()
.WidgetTestCase setUp()
test_Widget
WidgetTestCase tearDown()
.
----------------------------------------------------------------------
Ran 2 tests in 0.003s
OK
如果想構(gòu)建自已的用例集,只需要這么做:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
print("WidgetTestCase setUp()")
def test_Widget(self):
print("test_Widget")
def tearDown(self):
print("WidgetTestCase tearDown()")
class FuncTestCase(unittest.TestCase):
def setUp(self):
print("FuncTestCase setUp()")
def test_func(self):
print("test_func")
def tearDown(self):
print("FuncTestCase tearDown()")
def suite():
suite = unittest.TestSuite()
suite.addTest(FuncTestCase("test_func"))
return suite
if __name__ == "__main__":
runner=unittest.TextTestRunner()
runner.run(suite())
運(yùn)行結(jié)果:
FuncTestCase setUp()
test_func
FuncTestCase tearDown()
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
unittest中相關(guān)類和函數(shù)
在unittest中 TestCase類的實(shí)例代表邏輯測(cè)試單元,這個(gè)類通常被當(dāng)作測(cè)試類的基類使用, TestCase類實(shí)現(xiàn)了許多測(cè)試相關(guān)的接口,主要是以下三組方法:
1.執(zhí)行測(cè)試用例的方法
setUp()
#在每個(gè)測(cè)試方法之前執(zhí)行,這個(gè)方法引發(fā)的異常會(huì)被認(rèn)為是錯(cuò)誤,而非測(cè)試失敗,默認(rèn)實(shí)現(xiàn)是不做任何事
tearDown()
#在每個(gè)測(cè)試方法之后執(zhí)行,即使測(cè)試方法拋出異常tearDown()方法仍會(huì)執(zhí)行,并且只有setUp()成功執(zhí)行時(shí)tearDown()才會(huì)執(zhí)行,
#同樣這個(gè)方法引發(fā)的異常會(huì)被認(rèn)為是錯(cuò)誤,而非測(cè)試失敗。默認(rèn)實(shí)現(xiàn)是不做任何事
setUpClass()
#在一個(gè)測(cè)試類的所有測(cè)試方法執(zhí)行之前執(zhí)行,相當(dāng)于google test中的SetUpTestCase()方法,setUpClass()必須被裝飾成一個(gè)classmethod()
@classmethod
def setUpClass(cls):
...
tearDownClass()
#在一個(gè)測(cè)試類的所有測(cè)試方法執(zhí)行之后執(zhí)行,相當(dāng)于google test中的TearDownTestCase()方法,tearDownClass()必須被裝飾成一個(gè)classmethod()
@classmethod
def tearDownClass(cls):
...
2.檢查條件和報(bào)告錯(cuò)誤的方法
Method
Checks that
New in
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
3.1
assertIsNot(a, b)
a is not b
3.1
assertIsNone(x)
x is None
3.1
assertIsNotNone(x)
x is not None
3.1
assertIn(a, b)
a in b
3.1
assertNotIn(a, b)
a not in b
3.1
assertIsInstance(a, b)
isinstance(a, b)
3.2
assertNotIsInstance(a, b)
not isinstance(a, b)
3.2
assertRaises(exc, fun, *args, **kwds)
fun(*args, **kwds) raises exc
assertRaisesRegex(exc, r, fun, *args, **kwds)
fun(*args, **kwds) raises exc and the message matches regex r
3.1
assertWarns(warn, fun, *args, **kwds)
fun(*args, **kwds) raises warn
3.2
assertNotAlmostEqual(a, b)
round(a-b, 7) != 0
assertGreater(a, b)
a > b
3.1
assertGreaterEqual(a, b)
a >= b
3.1
assertLess(a, b)
a < b
3.1
assertLessEqual(a, b)
a <= b
3.1
assertRegex(s, r)
r.search(s)
3.1
assertNotRegex(s, r)
not r.search(s)
3.2
assertCountEqual(a, b)
a and b have the same elements in the same number, regardless of their order
3.2
assertWarnsRegex(warn, r, fun, *args, **kwds)
fun(*args, **kwds) raises warn and the message matches regex r
3.2
assertLogs(logger, level)
The with block logs on logger with minimum level
3.4
assertMultiLineEqual(a, b)
strings
3.1
assertSequenceEqual(a, b)
sequences
3.1
assertListEqual(a, b)
lists
3.1
assertTupleEqual(a, b)
tuples
3.1
assertSetEqual(a, b)
sets or frozensets
3.1
assertDictEqual(a, b)
dicts
3.1
本文標(biāo)題: Python unittest單元測(cè)試框架總結(jié)
本文地址: http://www.cppcns.com/jiaoben/python/239363.html
總結(jié)
以上是生活随笔為你收集整理的python单元测试框架-Python unittest单元测试框架总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断用户是否存在再进行新增_4招教你判断
- 下一篇: ununtu20.04系统中如何划词翻译