简介

unittest就是python的一个单元测试框架,unittest非常适合做自动化测试。

官方源码栗子:

import unittestclass IntegerArithmeticTestCase(unittest.TestCase):def testAdd(self):  # test method names begin with 'test'self.assertEqual((1 + 2), 3)self.assertEqual(0 + 1, 1)def testMultiply(self):self.assertEqual((0 * 10), 0)self.assertEqual((5 * 8), 40)if __name__ == '__main__':unittest.main()

解析下这个源码:

1. 引入unittest包
3. class定义一个测试类,并继承unittest.TestCase这个类
4 - 9. 定义两个测试case的名称,分别是testAdd和testMultiply, 然后增加了断言。assertEqual()
Note: 第四行中 “test method names begin with 'test'” 我们定义测试case的名称必须以test开头
11 - 12. 这个程序的主函数

运行的结果:

..
----------------------------------------------------------------------
Ran 2 tests in 0.001sOK

unittest中一些重要的概念

静态框架图如下:

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方法。总结就是:对一个测试用例环境的搭建和销毁。如何销毁呢?就是通过覆盖TestCase的setUp()和tearDown()方法来实现,tearDown()的过程很重要,为后面的case保证了一个干净的测试环境。

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

unittest工作原理

我们可以简化一下就是:

先写好TestCase然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。在Runner运行的时候,我们的测试结果会被输出到控制台,可以清晰的看到,我们还可以输出到文件,运用HTMLTestRunner生成一个漂亮的报告。

unittest case调用顺序

其中我们一个TestCase调用的顺序如下图所示:

举个栗子

这是我项目中 uiautomator2框架 + python unittest 写的手机自动化测试用例中的一小部分

import time
import unittest
import uiautomator2 as u2from NormativeExamination import commonclass GoogleSecurityCheck(unittest.TestCase):@classmethoddef setUpClass(cls):cls.d = u2.connect('04030148AO000175')cls.d.make_toast('测试开始', 3)@classmethoddef tearDownClass(cls):cls.d.make_toast('测试结束', 3)def setUp(self):self.d.info.get("screenOn")self.d.screen_on()def tearDown(self):self.d.press('Home')time.sleep(1)def test_persistent(self):u'''persistent进程内存占用'''persistent, code = self.d.shell("dumpsys meminfo | grep persistent")result = persistent.split("K:")[0].replace(",", "")self.assertLessEqual(int(result), 92160, 'persistent小于90M')def test_bluetooth(self):u'''测试蓝牙状态, 蓝牙必须默认关闭'''common.open_settings_menu(self.d, "Bluetooth")bluetooth_off = self.d(resourceId="com.android.settings:id/switch_widget", text=u"OFF")self.assertTrue(bluetooth_off, "蓝牙默认是关闭的")  if __name__ == '__main__':unittest.main()     

上面这个栗子中,还有几个额外的知识:

setup就是前置条件,tearDown就是后置条件,在我们执行完case之后,tearDown最好要写,做数据的还原,清理测试环境,比如退出浏览器、返回到手机的Home页面,保证后面的case不会执行失败。

这里有个坑,就是比如我们做测试打开百度页面的操作,每次执行用例就重新打开一次,这样就非常的浪费时间,我的本意是打开了百度的页面,我想做完所有的操作,然后再去关闭百度页面,这个时候就用到了装饰器(@classmethod)

  • 装饰器

用setUp与setUpClass区别

setup():每个测试case运行前运行

teardown():每个测试case运行完后执行

setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次

tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次

  • @是修饰符,classmethod是python里的类方法

Note: 在写测试用例的时候,一定要用test开头,假如不用test开头,你会发现程序识别不了。这个开头就说过了

def test_persistent(self):pass

小课堂:如何控制unittest执行的顺序呢?

答案:TestSuite(测试套件)的addTest()方法

unittest的main()方法执行用例的顺序是按照测试类、测试方法的名字的ASCII顺序来执行测试方法。假如不控制unittest执行顺序,有的有依赖测试的case就会运行失败,比如:下单 -> 付款, case的执行顺序必须要先执行下单才能付款,不能反过来。

假如我们要控制它,有2个办法:

1、 通过TestSuite按照顺序添加想要执行的方法

if __name__ == "__main__":suite = unittest.TestSuite()# 第一种方法:suite.addTest(TestBddClass("test_persistent_c"))suite.addTest(TestBddClass("test_bluetooth_a"))

这样方法的执行顺序就是先执行test_persistent_c,再执行test_bluetooth_a

这种方式可以实现,但是你必须要一个个手动去添加,用例一多就会你就会添加的爆炸,不适用。

2、 控制方法名字来实现

直接用 test_a_xxx , test_b_xxx, test_c_xxx来控制。abc换成123也行等等~

例子:

def test_a_persistent(self):u'''persistent进程内存占用'''persistent, code = self.d.shell("dumpsys meminfo | grep persistent")result = persistent.split("K:")[0].replace(",", "")self.assertLessEqual(int(result), 92160, 'persistent小于90M')def test_b_bluetooth(self):u'''测试蓝牙状态, 蓝牙必须默认关闭'''common.open_settings_menu(self.d, "Bluetooth")bluetooth_off = self.d(resourceId="com.android.settings:id/switch_widget", text=u"OFF")self.assertTrue(bluetooth_off, "蓝牙默认是关闭的")

如何跳过某个Case?

如果我们临时想要跳过某个case不执行怎么办?unittest也提供了几种方法:

# 第一种写法
class GoogleSecurityCheck(unittest.TestCase):# 跳过测试类@unittest.skip("I don't want to run this case.")def test_AFW(self):u'''AFW功能支持检查'''max_user, code = self.d.shell("pm get-max-users")result = max_user.split(':')[-1]self.assertTrue(result, 'get-max-ulser must be greater than 1')class GoogleSecurityCheck(unittest.TestCase):# 跳过测试casedef test_AFW(self):u'''AFW功能支持检查'''self.skipTest('Do not run this case')max_user, code = self.d.shell("pm get-max-users")result = max_user.split(':')[-1]self.assertTrue(result, 'get-max-ulser must be greater than 1') 两种方法得到的结果是一样的。 

运行程序,你就会发现 test_AFW就不会被执行,跳过了。

skip装饰器有三个:

unittest.skip(reason)
unittest.skipIf(condition, reason)
unittest.skipUnless(condition, reason)
skip无条件跳过
skipIf当condition为True时跳过
skipUnless当condition为False时跳过。

一个完整的小栗子:

import unittest
import timeclass Test(unittest.TestCase):def setUp(self):print ("start!")def tearDown(self):time.sleep(1)print ("end!")def test01(self):print ("执行测试用例01")def test03(self):print ("执行测试用例03")if __name__ == '__main__':# 构造测试集suite = unittest.TestSuite()suite.addTest(Test("test01"))suite.addTest(Test("test03"))# 执行测试runner = unittest.TextTestRunner()runner.run(suite)

运行结果:

start!
执行测试用例01
end!
start!
执行测试用例03
end!
----------------------------------------------------------------------
Ran 2 tests in 2.000sOK

将结果输出到文件中:

如上我们的结果就是输出到控制台,运行一次得到一次的结果,要查看之前的历史记录就没办法,我们可以把结果输出到文件。

修改一下代码:

if __name__ == '__main__':# 构造测试集suite = unittest.TestSuite()suite.addTest(Test("test03"))suite.addTest(Test("test01"))# 执行测试# runner = unittest.TextTestRunner()# runner.run(suite)with open('UnittestTextReport.txt', 'a') as f:runner = unittest.TextTestRunner(stream=f, verbosity=2)runner.run(suite)

运行结果:

我猜你嫌弃报告不够漂亮,早有人想到了,我们可以用HTMLTestRunner来生存一个漂亮的测试报告

Note:这种方法适用于python2

from HTMLTestRunner import HTMLTestRunnerwith open('HTMLReport.html', 'w') as f:runner = HTMLTestRunner(stream=f,title='测试报告',description='规范性检查测试报告.',verbosity=2)runner.run(suite)

python 3中:

import HTMLTestRunnerif __name__ == '__main__':# 构造测试集suite = unittest.TestSuite()suite.addTest(Test("test03"))suite.addTest(Test("test01"))now = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())fp = open(now + 'result.html', 'wb')# 定义报告格式runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='规范性检查测试报告',description=u'用例执行情况:')# 运行测试用例runner.run(suite)# 关闭报告文件fp.close()

让我们看看漂亮的报告:

代码中为什么加了如下两行呢?

now = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
fp = open(now + 'result.html', 'wb')

因为为了区分报告,报告的名称用当前的时间来表示,不会造成重复。效果如下:

断言

断言可以说是自动化测试中很重要的了,正确设置断言以后才能帮助我们判断测试用例执行结果。

例如你写代码的时候,IDE给你的提示:

总结几个常用的就是:

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
assertIsNot(a, b)     # a is not b
assertIsNone(x)       # x is None
assertIsNotNone(x)     # x is not None
assertIn(a, b)  # a in b
assertNotIn(a, b)   # a not in b
assertIsInstance(a, b)  # isinstance(a, b)
assertNotIsInstance(a, b)   # not isinstance(a, b)
assertGreater(a, b[, msg])   # 和self.assertTrue(a > b)用法一样,但是多了设置条件 .

太多了,大家直接自己在编辑器上查查看吧

25.3. unittest - Unit testing framework - Python 2.7.15 documentation​docs.python.org

unittest测试框架_python接口自动化测试 - 4.unittest单元测试框架学习相关推荐

  1. python 数据驱动接口自动化框架_python接口自动化测试 - 数据驱动DDT模块的简单使用...

    DDT简单介绍 名称:Data-Driven Tests,数据驱动测试 作用:由外部数据集合来驱动测试用例的执行 核心的思想:数据和测试代码分离 应用场景:一组外部数据来执行相同的操作 优点:当测试数 ...

  2. python自动化测试教程百度云盘_Python接口自动化测试框架实战视频教程百度云下载...

    主流的Fiddler.Requests.Unittest.Mock等接口测试工具/框架应用 进阶自动化框架设计开发 课程目录: 1-1 接口自动化测试从基础到框架-导学 1-2 接口基础知识回顾 1- ...

  3. python接口自动化用例管理_python接口自动化测试(六)-unittest-单个用例管理

    前面五节主要介绍了环境搭建和requests库的使用,可以使用这些进行接口请求的发送.但是如何管理接口案例?返回结果如何自动校验?这些内容光靠上面五节是不行的,因此从本节开始我们引入python单元测 ...

  4. python接口自动化测试面试题_Python 接口自动化测试实战

    Python接口自动化测试实战 简介 本课程主要围绕Python相关库再服务端接口自动化测试中的应用展开介绍,重点讲解接口自动化基础.编写接口自动化脚本.框架原理.项目实战,此外还扩展介绍多用例管理与 ...

  5. Python单元测试框架之unittest+requests+ddt+excel接口自动化测试

    unitetest是python里单元测试框架,是基于 java 的 junit 测试框架 相当于是一个 python 版的 junit,除了 unittest,还有一个 pytest 框架 unit ...

  6. python接口测试_Python接口自动化测试框架实战开发(一)

    目录 一丶叙述 二丶接口基础知识 三丶接口测试工具 四丶Fiddler的使用 五丶unittest使用 六丶mock服务入门到实战 七丶接口自动化框架设计到开发 一丶叙述 1.项目介绍 整个项目分为四 ...

  7. python接口自动化测试框架实战从设计到开发_Python接口自动化测试框架实战 从设计到开发...

    第1章 课程介绍(不要错过) 本章主要讲解课程的详细安排.课程学习要求.课程面向用户等,让大家很直观的对课程有整体认知! 第2章 接口测试工具Fiddler的运用 本章重点讲解如何抓app\web的h ...

  8. 软件测试必学之python+unittest+requests+HTMLRunner编写接口自动化测试集

    问题描述: 搭建接口测试框架,执行用例请求多个不同请求方式的接口 实现步骤: ① 创建配置文件config.ini,写入部分公用参数,如接口的基本url.测试报告文件路径.测试数据文件路径等配置项 1 ...

  9. python 接口自动化测试框架有哪些_Python接口自动化测试框架

    Python接口自动化测试框架 在自动化的测试体系中,包含了UI自动化测试和接口自动化测试,UI自动化实现的前提是软件版本进入稳定期,UI界面稳定.变动少,相比较之下接口自动化,接口受外界因素的影响较 ...

最新文章

  1. 深度学习框架:GPU
  2. IOS7原生API进行二维码条形码的扫描
  3. 计算机课有什么作业,计算机课作业~
  4. 管理之道(三) - 不要吝惜赞美
  5. Ubuntu 18.04从源代码编译安装GPU支持的Tensorflow 1.8.0
  6. 吴恩达旗下Drive.ai商业化第一步!现在去德州能打无人驾驶出租车
  7. Lucene PriorityQueue JDK PriorityQueue
  8. 升降压型电感电容计算
  9. ruoyi 项目启动步骤
  10. 单龙芯3A3000-7A1000PMON研究学习-(25)撸起袖子干-再来一杯代码7
  11. Python暴力破解ZIP文件密码
  12. 为什么手机网速太慢_为什么苹果手机的网速变慢了_苹果手机上网速度慢的解决方法-系统城...
  13. 水星mw310r虚拟服务器,水星MW310R(V1-V4)路由器桥接设置教程 | 192路由网
  14. React-Redux 学习,转载
  15. Android快速入门教程1
  16. 史上最全vue优化方案
  17. C++实验七——类的继承(1)
  18. Modbus的基础学习
  19. 关于山大计科转专业的二三事
  20. 阿里云服务器云盘性能对比

热门文章

  1. android打不开,android加入权限应用打不开
  2. 虚拟专题:知识图谱 | 其他文章
  3. 【2016年第6期】大规模分布式科学数据管理与服务技术架构及系统
  4. 作者:高翔(1984-),男,国防大学信息作战与指挥训练教研部博士后,主要研究方向为体系分析与超网建模。...
  5. 作者:罗威,男,中国国防科技信息中心副研究员。
  6. 大数据第1期——目录
  7. 【Java】Maven工程目录下ImageIcon读图片失败爆空指针的解决方案
  8. 【Python】Numpy包的安装使用
  9. 让SH/BAT脚本定位到运行目录的相对位置,实现其脚本可在任意运行目录下被正确执行...
  10. SSH框架中怎么使用Hibernate查询一个对象