测试的常用规则

  1. 一个测试单元必须关注一个很小的功能函数,证明它是正确的;
  2. 每个测试单元必须是完全独立的,必须能单独运行。这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作。通常通过setUp()和setDown()方法处理;
  3. 编写执行快速的测试代码。在某些情况下,测试需要加载复杂的数据结构,而且每次执行的时候都要重新加载,这个时候测试执行会很慢。因此,在这种情况下,可以将这种测试放置一个后台的任务中。
  4. 采用测试工具并且学着怎么使用它。
  5. 在编写代码前执行完整的测试,而且在编写代码后再重新执行一次。这样能保证你后来编写的代码不会破坏任何事情;
  6. 在提交代码前执行完整的测试;
  7. 如果在开发期间被打断了工作,写一个打断的单元测试,关于你下一步将要开发的。当你回来工作时,你能知道上一步开发到的指针;
  8. 单元测试函数使用长的而且具有描述性的名字。在正式执行代码中,可能使用square()或sqr()取名,但是在测试函数中,你必须取像test_square_of_number_2()、test_square_negativer_number()这些名字,这些名字描述更加清楚;
  9. 测试代码必须具有可读性;
  10. 单元测试对新进的开发人员来说是工作指南。

二、常见的测试框架

2.1 Unittest

unittest是Python内置的标准类库。它的API跟Java的JUnit、.net的NUnit,C++的CppUnit很相似。

通过继承unittest.TestCase来创建一个测试用例。

具体请参考 文档 。

举个例:

  1. import unittest
  2.  
  3. def fun(x):
  4. return x + 1
  5.  
  6. class MyTest(unittest.TestCase):
  7. def test(self):
  8. self.assertEqual(fun(3), 4)

执行后成功。

但是,如果将期望的结果改成5,则执行的结果如下图所示:

2.2 Doctest

doctest 模块会搜索那些看起来像交互式会话的 Python 代码片段,然后尝试执行并验证结果.即使从没接触过 doctest,我们也可以从这个名字中窥到一丝端倪。“它看起来就像代码里的文档字符串(docstring)一样” 如果你这么想的话,就已经对了一半了。

举个例子:

  1. def square(x):
  2. """Squares x.
  3.  
  4. >>> square(2)
  5. 4
  6. >>> square(-2)
  7. 4
  8. >>> square(5)
  9. 25
  10. """
  11.  
  12. return x * x
  13.  
  14. if __name__ == '__main__':
  15. import doctest
  16. doctest.testmod()

当执行该代码后,会执行文档内>>> 后面的测试代码,并与下一行的结果进行比对。执行的结果如下:

但是,如果我们把结果改一下,square(2)的结果改成5,测试代码如下:

  1. def square(x):
  2. """Squares x.
  3.  
  4. >>> square(2)
  5. 5
  6. >>> square(-2)
  7. 4
  8. >>> square(5)
  9. 25
  10. """
  11.  
  12. return x * x
  13.  
  14. if __name__ == '__main__':
  15. import doctest
  16. doctest.testmod()

执行的测试结果如下所示:

2.3 py.test

py.test是unittest的替代工具。

尽管它是一个功能丰富、灵活的测试框架,但是它的语法很简单。创建一个单元测试就像编写一个模块一样。相比unittest,实现相同的测试功能,py.test做的事情更少。

py.test详细 文档 。

首先,安装py.test

  1. pip install pytest

第二步,编写测试代码

  1. def func(x):
  2. return x + 1
  3.  
  4. def test_answer():
  5. assert func(3) == 5

第三步,执行测试代码。

  • 找到pytest安装路径。
  • 用其所在的解析器(python.exe)执行test.py ,执行命令比如:

执行的结果如下图所示:

2.4 Nose

Nose是对unittest的扩展,使得python的测试更加简单。nose自动发现测试代码并执行,nose提供了大量的插件,比如测试输出的xUnitcompatible,覆盖报表等等。

nose的详细文档: https://nose.readthedocs.org/en/latest/

注意:nose本身是支持python3的,但是很多它的插件不支持。

2.5 tox

最大的特色,是自动最测试环境的管理以及使用多个解析器配置进行测试。

tox的详细文档: http://testrun.org/tox/latest/

2.6  Unittest2

是unitest的升级版。对API进行了改善以及更好的诊断语法。

unittest2的详细文档: https://pypi.python.org/pypi/unittest2

首先,安装

  1. pip install unittest2

为了以后能在unittest与unittest2之间进行切换,最好的代码编写方式如下:

  1. import unittest2 as unittest
  2.  
  3. class MyTest(unittest.TestCase):
  4. ...

2.7 mock unittest.mock是用来测试python的库。在python3.3版本以后,这个是一个标准库。 对老版本来说,使用pip install mock 进行安装。

  1. mock的精髓在于,你可以使用模拟的对象来替代你的系统的一部分,然后验证后续的执行是否正确。
  1. mock的详细文档:http://www.voidspace.org.uk/python/mock/
  2. UNiTTEST

Pyhon工作原理—— 核心概念:test case, testsuite, TestLoder,TextTestRunner,TextTestResult, test fixture

TestCase(测试用例): 所有测试用例的基类,它是软件 测试中最基本的组成单元。

一个test case就是一个测试用例,是一个完整的测试流程,包括测试前环境的搭建setUp,执行测试代码(run),以及测试后环境的还原(tearDown)。测试用例是一个完整的测试单元,可以对某一问题进行验证。

TestSuite(测试套件):多个测试用例test case集合就是TestSuite,TestSuite可以嵌套TestSuite

TestLoder:是用来加载 TestCase到TestSuite中,其中有几个loadTestsFrom_()方法,就是从各个地方寻找TestCase,创建他们的实例,然后add到TestSuite中,再返回一个TestSuite实例

TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

 TextTestResult:测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息

TestFixture:又叫测试脚手,测试代码的运行环境,指测试准备前和执行后要做的工作,包括setUp和tearDown方法

二、测试流程:

1. 写好TestCase:一个class继承unittest.TestCase,就是一个测试测试用例,其中有多个以test开头的方法,那么 每一个这样的,在load的时候会生成一个TestCase实例。如果一个class中有四个test开头的方法,最后load到suite中时则有四个测试用例

2. 由TestLoder加载TestCase到TestSuite

3.然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中。

说明:a:通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者可以直接通过TextTestRunner来执行用例

b:Runner执行时,默认将结果输出到控制台,我们可以设置其输出到文件,在文件中查看 结果,也可以通过HTMLTestRunner将结果输出到HTML)

下面写一个简单的单元测试用例

  1. import unittest
  2.  
  3. class MyTest(unittest.TestCase): # 继承unittest.TestCase
  4. def tearDown(self):
  5. # 每个测试用例执行之后做操作
  6. print('111')
  7.  
  8. def setUp(self):
  9. # 每个测试用例执行之前做操作
  10. print('22222')
  11.  
  12. @classmethod
  13. def tearDownClass(self):
  14. # 必须使用 @ classmethod装饰器, 所有test运行完后运行一次
  15. print('4444444')
  16. @classmethod
  17. def setUpClass(self):
  18. # 必须使用@classmethod 装饰器,所有test运行前运行一次
  19. print('33333')
  20.  
  21. def test_a_run(self):
  22. self.assertEqual(1, 1) # 测试用例
  23.  
  24. def test_b_run(self):
  25. self.assertEqual(2, 2) # 测试用例
  26.  
  27. if __name__ == '__main__':
  28. unittest.main()#运行所有的测试用例

下面是一些常用的断言,也就是校验结果

  1. assertEqual(a, b) a == b
  2. assertNotEqual(a, b) a != b
  3. assertTrue(x) bool(x) is True
  4. assertFalse(x) bool(x) is False
  5. assertIsNone(x) x is None
  6. assertIsNotNone(x) x is not None
  7. assertIn(a, b) a in b
  8. assertNotIn(a, b) a not in b

那如何生成一个测试报告呢,需要加入另外一个模块了,HTMLTestRunner,这个模块需要自己安装,使用执行测试用例就会生成一个html的测试报告,里面会有每个测试用例的执行结果,代码如下:

  1. import HTMLTestRunner
  2. import unittest
  3. class MyTest(unittest.TestCase):#继承unittest.TestCase
  4. def tearDown(self):
  5. #每个测试用例执行之后做操作
  6. print('111')
  7. def setUp(self):
  8. #每个测试用例执行之前做操作
  9. print(22222)
  10. def test_run(self):
  11. # self.assertEqual(1,1)
  12. self.assertIs(1,1)
  13. #测试用例
  14. def test_run2(self):
  15. # self.assertEqual(1,1)
  16. self.assertIs(1,1)
  17. #测试用例
  18. def test_run3(self):
  19. # self.assertEqual(1,1)
  20. self.assertIs(1,1)
  21. #测试用例
  22. def test_run1(self):
  23. # self.assertEqual(1,1)
  24. self.assertIs(1,1)
  25. #测试用例
  26. if __name__ == '__main__':
  27. test_suite = unittest.TestSuite()#创建一个测试集合
  28. test_suite.addTest(MyTest('test_run1'))#测试套件中添加测试用例
  29. #test_suite.addTest(unittest.makeSuite(MyTest))#使用makeSuite方法添加所有的测试方法
  30. fp = open('res.html','wb')#打开一个保存结果的html文件
  31. runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='api测试报告',description='测试情况')
  32. #生成执行用例的对象
  33. runner.run(test_suite)
  34. #执行测试套件

如果我们有很多个模块,每个模块下面都写了很多python文件,每个python文件里面都有测试用例,那怎么把这个目录下的用例都执行了呢,就要先找到这个目录下的所有python文件,然后找到里面的测试用例,逐个执行,代码如下:

  1. import unittest,HTMLTestRunner
  2. suite = unittest.TestSuite()#创建测试套件
  3. all_cases = unittest.defaultTestLoader.discover('.','test_*.py')
  4. #找到某个目录下所有的以test开头的Python文件里面的测试用例
  5. for case in all_cases:
  6. suite.addTests(case)#把所有的测试用例添加进来
  7. fp = open('res.html','wb')
  8. runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='all_tests',description='所有测试情况')
  9. runner.run(suite)
  10. #运行测试

我们在后续进行持续集成的时候,要让代码自动运行,就会用到Jenkins了,但是上面产生的测试报告都是html格式的,Jenkins不认识,就在Jenkins里面显示不出来。那咱们就要产生一些Jenkins认识的测试报告,Jenkins认识xml格式的报告,那咱们就产生xml格式的呗,就需要用一个新的模块,xmlrunner,安装直接 pip install xmlrunner即可,代码如下:

  1. import unittest
  2. import xmlrunner
  3. #导入这个模块
  4. class My(unittest.TestCase):
  5.  
  6. def test1(self,a,b,c):
  7. self.assertEqual(a+b,c)
  8.  
  9. if __name__=='__main__':
  10. test_suite = unittest.TestSuite()
  11. test_suite.addTest(unittest.makeSuite(My))
  12. runner = xmlrunner.XMLTestRunner(output='report')#指定报告放的目录
  13. runner.run(test_suite)

然后咱们运行,可以看到在report目录下已经产生了xml格式的报告了,而且还自动把日期加上了

Python单元测试框架——unittest的更多相关文章

  1. Python单元测试框架unittest使用方法讲解

    这篇文章主要介绍了Python单元测试框架unittest使用方法讲解,本文讲解了unittest概述.命令行接口.测试案例自动搜索.创建测试代码.构建测试套件方法等内容,需要的朋友可以参考下   概 ...

  2. Python单元测试框架unittest之深入学习

    前言 前几篇文章该要地介绍了python单元测试框架unittest的使用,本篇文章系统介绍unittest框架. 一.unittest核心工作原理 unittest中最核心的四个概念是:test c ...

  3. Python单元测试框架unittest之单用例管理(一)

    一.概述 本文介绍python的单元测试框架unittest,unittest原名为PyUnit,是由java的JUnit衍生而来,这是Python自带的标准模块unittest.unittest是基 ...

  4. Python单元测试框架unittest

    学习接口自动化测试时接触了unittest单元测试框架,学习时参照了虫师编写的<selenium2自动化测试实战>,个人觉得里面讲的例子还比较容易理解的. 一.基础 1.main()和框架 ...

  5. Python单元测试框架unittest重要属性 与 用例编写思路

    前言 本文为转载,原文地址作者列举python unittest这个测试框架的主要属性和 测试用例思路 unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行, ...

  6. python单元测试框架-unittest(一)

    简介 unittest单元测试框架不仅可以适用于单元测试,还可以使用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果. ...

  7. Python单元测试框架 unittest详解

    一 整体结构概览 unittest原名为PyUnit,是由java的JUnit衍生而来.对于单元测试,需要设置预先条件,对比预期结果和实际结果. TestCase :通过继承TestCase类,我们可 ...

  8. python单元测试框架-unittest(四)之用例综合框架管理

    简述为何如要框架? 前面测试用例与执行都是写在一个文件,当用例数量不断增加的时候,用例的执行与管理变得非常麻烦,因此需要对用例根据具体的功能模块来使用单独的模块来管理.就像一所学校要根据不同年级进行分 ...

  9. Python3 Selenium自动化web测试 ==> 第一节 起始点之Python单元测试框架 unittest

    前置步骤 Python版本:3.6.4 selenium版本:3.11.0 >>> import selenium >>> help(selenium) IDE:P ...

随机推荐

  1. MathType可以编辑物理公式吗

    很多的物理专业的人都在为编辑物理公式头疼,其实要写出这些公式并不难,要写出这些物理公式,那你就需要一个MathType公式编辑器!这是一款专业的公式编辑器,不管多复杂的公式或方程,都可以用它编辑出来, ...

  2. 免费iOS第三方推送工具Urban Airship使用教程

     本文转载至 http://blog.csdn.net/mamong/article/details/8542404  http://www.dapps.net/dev/iphone/ios-free ...

  3. 面试之Java持久层(十)

    91,什么是ORM?         对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术: 简单的说,O ...

  4. python array

    python中通常情况下for循环会枚举各个元素不会访问下标,例如: l = [1,2,4,6] for val in l: print l 但是有时候我们会需要在便利数组的同时访问下标,这时候可以借 ...

  5. 模块 - time/datetime

    time 模块 time模块方法: >>> import time >>> time.time() #时间戳 秒级别 1519212085.6211221 #从19 ...

  6. 【Linux command reference】

    ubuntu16.04安装中文输入法: https://blog.csdn.net/singleyellow/article/details/77448246 ubuntu16.04 用vi编辑代码, ...

  7. Dictionary里使用struct,enum做key

    首先看下Dictionary的源码 public void Add (TKey key, TValue value) { if (key == null) throw new ArgumentNull ...

  8. A4纸网页打印中对应像素的设定和换算

    最近开发项目时遇到了网页打印的问题,这是问题之二,打印宽度设置 在公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot PerInch)指标.  经过我仔细的测试,发现了网页打印中,默认采用 ...

  9. Redis与Memcached的比较(转)

    原文:http://blog.nosqlfan.com/html/3729.html 这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memc ...

  10. 安卓项目eclipse有用教程:设置应用名字和图标、屏幕、签名、真机调试、clean、logcat、json解析

    怎样在安卓项目中.设置游戏的应用名字和图标? 我们在Androidproject的res资源目录下.会看到3个drawable的目录和一个values目录.就是在这里改动即可.   关于改动应用程序名 ...