最新无惧代码错误,从unittest开始的单元测试之旅!,附超全教程文档

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

def test_add_5_5(self):
    self.assertEqual(self.test_class.add(5, 5), 10)

def test_bool_value(self):
    self.assertTrue(self.test_class.is_string("hello world!"))

def test_raise(self):
    self.assertRaises(KeyError, self.test_class.raise_error)

def tearDown(self):
    del self.test_class

if name == “main”:
unittest.main()


上述这个例子就概括了**unittest**的基本使用,下面我们来详细剖析一下关键点。


首先,我在这里实现了一个**用于测试**的类`TestClass`,它包含3个方法,分别是用于加和的`add`,返回的是一个**确切的数值**;其次,是一个判断是否为字符串的方法`is_string`,返回的是一个布尔型的结果;最后是抛出异常的`raise_error`方法,返回的是一个异常类型。


我们接下来就要测试`TestClass`中的3个方法是否按照我们期望的那样获取正确的结果,我们来用特定的数据作为输入,


* `add`:输入数据为5,5,如果功能正确返回值是10;
* `is_string`:输入数是'hello world!',如果功能正确返回的是True;
* `raise_error`:直接抛出异常;


明确了我们要测试的方法和重点,接下来就是写测试用例,在这个示例中我的测试用例是这样写的,



class Case(unittest.TestCase):
def setUp(self):
self.test_class = TestClass()

def test_add_5_5(self):
    self.assertEqual(self.test_class.add(5, 5), 10)

def test_bool_value(self):
    self.assertTrue(self.test_class.is_string("hello world!"))

def test_raise(self):
    self.assertRaises(KeyError, self.test_class.raise_error)

def tearDown(self):
    del self.test_class

这个测试用例包含几个**需要关注**的点:


* 继承
* 测试方法名称
* setUp
* tearDown
* 断言


下面以此来说一下上述提及的这几点。



现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】


![](https://img-blog.csdnimg.cn/direct/c237ec31d1394621baeaeea08e65e8e8.png)


**继承**


**unittest**提供一个基类**TestCase**,如果我们要编写一个测试用例,就需要继承这个抽象基类,这样当我们运行测试程序时它会自动的运行这些测试用例。


**测试方法的名称**


测试方法要以test开头,这样测试程序能够自动找到要运行的方法,在上述例子中包含3个测试方法,


* test\_add\_5\_5
* test\_bool\_value
* test\_raise


**setUp和tearDown**


setUp和tearDown有点类似于C++中的构造方法和析构方法,通俗的来讲,它们分别用于处理测试开始前和完成后要执行的命令。我们都知道C++中有构造和析构的概念,当调用一个类时,它会首先进入构造方法,用于一些初始化操作,当执行完成,它会调用析构方法,用于调用后的处理,例如清理内存和对象等。  
 setUp和tearDown和这个有点类似,当一个测试用例开始之前,会先进入setUp方法,当测试结束后会进入tearDown方法。  
 在上面测试用例中,我在setUp中用于实例化`TestClass`这个要被测试的类,然后在tearDown中清理对象。


**断言**


在上述测试用例中也用到一些用于断言的方法,它们来自于unittest基类,`assertEqual()`来检查预期的输出;调用`assertTrue()`或`assertFalse()`来验证一个条件;调用`assertRaises()`来验证抛出了一个特定的异常。


执行测试程序,得到如下结果,



Ran 3 tests in 0.001s

OK


可以看出,共执行了3个测试,没有出现异常现象。


如果觉得上述输出的信息比较少,不够详细,也可以在命令行执行下面命令,



$ python -m unittest -v test


其中`test`是脚本名称。


输出详细信息如下,



test_add_5_5 (test.Case) … ok
test_bool_value (test.Case) … ok
test_raise (test.Case) … ok


Ran 3 tests in 0.002s

OK


上述就是unittest的一种常用方法。


### **测试套件**


上述演示了一种比较基础、简单的测试用例的使用方法,但是这样比较固化,只能自动的去查找以test开头的测试方法,然后顺序的去执行测试方法,这样显然是有点僵化的,不能按照重要程度或者我们的意愿去执行测试方法,而且遇到多个测试用例是会比较混乱。  
 这里要讲的测试套件能够归档测试用例,能够让我们按照指定的顺序去执行测试方法。


还是针对前面的例子来讲,在之前我们执行测试程序时通过以下方法,



if name == “main”:
unittest.main()


我们要使用**测试套件**只需要修改执行部分的代码即可,



suite = unittest.TestSuite()
tests = [
Case(‘test_raise’),
Case(‘test_bool_value’),
Case(‘test_add_5_5’)
]
suite.addTests(tests)
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)


这里也有几个**需要注意**的点,


* 初始化套件
* 添加测试用例
* 执行测试用例


**初始化套件**


这里我们通过`suite = unittest.TestSuite()`来初始化套件。


**添加测试用例**


添加测试用例有两种方法,第一种就是上述示例中使用的这种方法,


* 把测试用例放入一个列表中
* 用`suite.addTests()`把测试用例列表加入套件


还有一种方法是逐个添加测试用例,



suite.addTest(Case(‘test_raise’))
suite.addTest(Case(‘test_bool_value’))
suite.addTest(Case(‘test_add_5_5’))


**请注意**,上面前者使用的是`addTests`,后者使用的是`addTest`。


**执行测试用例**


这里需要提及一个概念,测试运行器(test runner),它是一个用于执行和输出测试结果的组件。  
 使用测试运行器,首先要初始化运行器`runner = unittest.TextTestRunner(verbosity=2)`,执行器的参数列表如下,



class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)


其中stream可以用于指定输出测试信息到文件,verbosity用于指定输出详细信息。


然后用运行器运行测试套件即可,结果如下,



test_raise (main.Case) … ok
test_bool_value (main.Case) … ok
test_add_5_5 (main.Case) … ok


Ran 3 tests in 0.002s

OK




![img](https://img-blog.csdnimg.cn/img_convert/760e265b990313f8b16928fc0df155b4.png)
![img](https://img-blog.csdnimg.cn/img_convert/66d5bb0aec94d8d1b976d100bdc948b2.png)
![img](https://img-blog.csdnimg.cn/img_convert/e0bc308886b1d65996fbd6b16ee47c2b.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

片转存中...(img-2E3EYPtV-1715499910399)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值