什么是单元测试
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。
比如对于函数abs(),我们可以编写的测试用例为:
(1)输入正数,比如1、1.2、0.99,期待返回值与输入相同
(2)输入复数,比如-1、-1.2、-0.99,期待返回值与输入相反
(3)输入0,期待返回0
(4)输入非数值类型,比如None、[]、{}、期待抛出TypeError
把上面这些测试用例放到一个测试模块里,就是一个完整的单元测试
unittest工作原理
unittest中最核心的四部分是:TestCase,TestSuite,TestRunner,TestFixture
(1)一个TestCase的实例就是一个测试用例。测试用例就是指一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
(2)而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
(3)TestLoader是用来加载TestCase到TestSuite中的。
(4)TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法
(5)测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
综上,整个流程就是首先要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。
python unittest简介
unittest是python下的单元测试框架,是java JUnit的python版本, 跟其它语言下的单元测试框架风格类似,unittest支持自动化测试、共享setup和teardown代码、测试聚合成集、独立于报告框架。unittest模块提供了一个丰富的工具集用于构建和执行用例,先看一个入门的例子:
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创建一个测试用例TestStringMethods,在这个用例中定义了测试函数,这些函数名字都以”test”开头,在执行测试用例TestStringMethods时,这些方法会被自动调用。每个测试函数中都调用了assertTrue()和assertFalse()方法检查预期结果,或者使用assertRaises()确认产生了一个特定异常。现在来看一下这段代码的运行结果:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000sOK
有时我们需要在用例执行前后做一些工作如初始化和清理,这就需要实现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()
运行结果:
setUp()
.test_1
tearDown()
setUp()
.test_2
tearDown()
----------------------------------------------------------------------
Ran 2 tests in 0.000sOK
注:如果setUp()执行成功(没有异常发生),那么无论测试方法是否通过,tearDown()都会被执行
根据所测的特性测试用例被组合在一起,通过调用unittest.main(),unittest测试框架会自动收集所有模块的测试用例然后执行。
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()
运行结果:
FuncTestCase setUp()
test_func
FuncTestCase tearDown()
.WidgetTestCase setUp()
test_Widget
WidgetTestCase tearDown()
.
----------------------------------------------------------------------
Ran 2 tests in 0.003sOK
如果想构建自已的用例集,只需要这么做:
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())
运行结果:
FuncTestCase setUp()
test_func
FuncTestCase tearDown()
.
----------------------------------------------------------------------
Ran 1 test in 0.001sOK
unittest中相关类和函数
在unittest中 TestCase类的实例代表逻辑测试单元,这个类通常被当作测试类的基类使用, TestCase类实现了许多测试相关的接口,主要是以下三组方法:
1.执行测试用例的方法
setUp() #在每个测试方法之前执行,这个方法引发的异常会被认为是错误,而非测试失败,默认实现是不做任何事 tearDown() #在每个测试方法之后执行,即使测试方法抛出异常tearDown()方法仍会执行,并且只有setUp()成功执行时tearDown()才会执行, #同样这个方法引发的异常会被认为是错误,而非测试失败。默认实现是不做任何事 setUpClass() #在一个测试类的所有测试方法执行之前执行,相当于google test中的SetUpTestCase()方法,setUpClass()必须被装饰成一个classmethod() @classmethod def setUpClass(cls): ... tearDownClass() #在一个测试类的所有测试方法执行之后执行,相当于google test中的TearDownTestCase()方法,tearDownClass()必须被装饰成一个classmethod() @classmethod def tearDownClass(cls): ...
2.检查条件和报告错误的方法
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
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]