1、什么是单元测试

  测试函数/方法或者一段代码,用于检验被测代码的一个很小的、很明确的功能是否正确,通常是开发做。

  在Python中的单元测试框架有Unittest和Pytest,现在总结Unittest。

2、单元测试框架

1、Unittest框架的五个概念

  •   test fixture:测试固件

  •   test case:测试用例

  •   test suit:测试套件

  •   test runner:测试运行器

  •   test loader:测试加载器

1) Test Case

  一个TestCase 的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。单元测试(unittest)的本质也就在这里。一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

2) Test Suite

  多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套Test Suite。

3) Test runner

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

4) Test Loader

  是用来加载TestCase到Test Suite中的,其中几个 loadTestsFrom__() 方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite 实例。

5) Test fixture

  对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖Test Case的setUp() 和tearDown() 方法来实现。

2、Unittest中的两个方法

方法1:setup 和teardown

1)结构:

测试基本setup方法:第一个测试开始之前只执行一次
多个类
类:
类setup方法:在当前类的第一个测试方法调用前执行,只执行一次 setup方法:在执行测试方法前的一些环境或者数据相关的准备
测试的方法:每个测试方法执行前,都会执行setup方法,然后执行teardown方法
teardown方法:在执行方法后的一些环境或者数据相关的清理 类teardown方法:在当前类的最后一个测试方法调用后执行,只执行一次 测试级别teardown方法:所有的测试结束之后只执行一次

2)说明

  setUp:实现测试前的初始化工作

  tearDown:实现测试结束后的清理工作

  用例之间按用例ASCII码的顺序加载,数字和字母顺序为 0~9,A~Z,a~z。

方法2:断言方法

3、加载测试用例的四种方法

  首先实例化:

suite = unittest.TestSuite()
loader = unittest.TestLoader()

  方法一:通过测试用例类进行加载

suite.addTest(loader.loadTestsFromTestCase(MyTest1))
suite.addTest(loader.loadTestsFromTestCase(MyTest2))

  方法二:通过测试用例模版去加载

suite.addTest(loader.loadTestsFromTestModule(MyTest1))
suite.addTest(loader.loadTestsFromTestModule(MyTest2))

  方法三:通过路径加载

import os
path = os.path.dirname(os.path.abspath(__file__))
suite.addTest(loader.discover(path))

  方法四:逐条加载 low

case1 = MyTest1("test1")
case2 = MyTest1("test2")
suite.addTest(case1)
suite.addTest(case2)

3、代码举例

举例1:

#encoding=utf-8
import unittest # 被测试类
class myclass(object):
@classmethod #可以不加,但是调用前需要实例化
def sum(self, a, b):
return a + b #将两个传入参数进行相加操作 @classmethod #可以不加,但是调用前需要实例化
def sub(self, a, b):
return a - b #将两个传入参数进行相减操作 class mytest(unittest.TestCase):
@classmethod #必须加
def setUpClass(cls):#每个测试类的setup方法,只会执行一次
"初始化类固件,固件是准备的意思"
print ( "----setUpClass") @classmethod #必须加
def tearDownClass(cls):#每个测试类的tearDown方法,只会执行一次
"重构类固件"
print ( "----tearDownClass") # 初始化工作
def setUp(self):#每个测试方法均会执行一次
self.a = 3
self.b = 1
print ( "--setUp") # 退出清理工作
def tearDown(self):#每个测试方法均会执行一次
print ( "--tearDown") # 具体的测试用例,一定要以test开头
def testsum(self): #每个测试用例执行成功一次,打印一个 .
# 断言两数之和的结果是否是4
self.assertEqual(myclass.sum(self.a, self.b), 4, 'test sum fail') def testsub(self):
# 断言两数之差的结果是否是2
self.assertEqual(myclass.sub(self.a, self.b), 2, 'test sub fail') if __name__ == '__main__':
unittest.main() # 启动单元测试

执行结果:

举例2:跳过指定的测试用例的三种方法

# coding=utf-8
import random
import unittest
import sys class TestSequenceFunctions(unittest.TestCase):
a = 6 def setUp(self):
self.seq = list(range(10)) @unittest.skip("skipping") # 无条件忽略该测试方法
def test_shuffle(self):
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, list(range(10)))
self.assertRaises(TypeError, random.shuffle, (1, 2, 3)) # 如果变量a > 5,则忽略该测试方法
@unittest.skipIf(a > 5, "condition is not satisfied!")
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq) # 除非执行测试用例的平台是Linux平台,否则忽略该测试方法 win32是windows
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux") #被忽略时打印 第二个参数
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq) if __name__ == '__main__':
# unittest.main()
# 指定加载哪几个测试类,生成测试集合
suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
suite = unittest.TestSuite(suite)
unittest.TextTestRunner(verbosity = 2).run(suite)

结果:

D:\学习\自动化\单元测试>py -3 e4_unittest_skip.py
test_choice (__main__.TestSequenceFunctions) ... skipped 'condition is not satisfied!'
test_sample (__main__.TestSequenceFunctions) ... skipped 'requires Linux'
test_shuffle (__main__.TestSequenceFunctions) ... skipped 'skipping' ----------------------------------------------------------------------
Ran 3 tests in 0.003s OK (skipped=3)

举例3:常用断言举例

#encoding=utf-8
import unittest
import random # 被测试类
class MyClass(object):
@classmethod
def sum(self, a, b):
return a + b @classmethod
def div(self, a, b):
return a / b @classmethod
def retrun_None(self):
return None # 单元测试类
class MyTest(unittest.TestCase): # assertEqual()方法实例
def test_assertEqual(self):
# 断言两数之和的结果
# 一般不需要捕获异常,unittest会自动捕获异常
try:
a, b = 1, 2
sum = 3
self.assertEqual(a + b, sum, '断言失败,%s + %s != %s' %(a, b, sum))
except AssertionError as e:
print (e) # assertNotEqual()方法实例
def test_assertNotEqual(self):
# 断言两数之差的结果
try:
a, b = 5, 2
res = 1
self.assertNotEqual(a - b, res, '断言失败,%s - %s != %s' %(a, b, res))
except AssertionError as e:
print (e) # assertTrue()方法实例
def test_assertTrue(self):
# 断言表达式的为真
try:
self.assertTrue(1 == 1, "表达式为假")
except AssertionError as e:
print (e) # assertFalse()方法实例
def test_assertFalse(self):
# 断言表达式为假
try:
self.assertFalse(3 == 2, "表达式为真")
except AssertionError as e:
print (e) # assertIs()方法实例
def test_assertIs(self):
# 断言两变量类型属于同一对象
try:
a = 12
b = a
self.assertIs(a, b, "%s与%s不属于同一对象" %(a, b))
except AssertionError as e:
print (e) # test_assertIsNot()方法实例
def test_assertIsNot(self):
# 断言两变量类型不属于同一对象
try:
a = 12
b = "test"
self.assertIsNot(a, b, "%s与%s属于同一对象" %(a, b))
except AssertionError as e:
print (e) # assertIsNone()方法实例
def test_assertIsNone(self):
# 断言表达式结果为None
try:
result = MyClass.retrun_None()
self.assertIsNone(result, "not is None")
except AssertionError as e:
print (e) # assertIsNotNone()方法实例
def test_assertIsNotNone(self):
# 断言表达式结果不为None
try:
result = MyClass.sum(2, 5)
self.assertIsNotNone(result, "is None")
except AssertionError as e:
print (e) # assertIn()方法实例
def test_assertIn(self):
# 断言对象A是否包含在对象B中
try:
strA = "this is a test"
strB = "is"
self.assertIn(strB, strA, "%s不包含在%s中" %(strB, strA))
except AssertionError as e:
print (e) # assertNotIn()方法实例
def test_assertNotIn(self):
# 断言对象A不包含在对象B中
try:
strA = "this is a test"
strB = "Selenium"
self.assertNotIn(strB, strA, "%s包含在%s中" %(strB, strA))
except AssertionError as e:
print (e) # assertIsInstance()方法实例
def test_assertIsInstance(self):
# 测试对象A的类型是否值指定的类型
try:
x = MyClass
y = object
self.assertIsInstance(x, y, "%s的类型不是%s" %(x, y))
except AssertionError as e:
print (e) # assertNotIsInstance()方法实例
def test_assertNotIsInstance(self):
# 测试对象A的类型不是指定的类型
try:
a = 123
b = str
self.assertNotIsInstance(a, b, "%s的类型是%s" %(a, b))
except AssertionError as e:
print (e) # assertRaises()方法实例
def test_assertRaises(self):
# 测试抛出的指定的异常类型
# assertRaises(exception)
with self.assertRaises(TypeError) as cm:
random.sample([1,2,3,4,5], "j")
# 打印详细的异常信息
#print "===", cm.exception # assertRaises(exception, callable, *args, **kwds)
try:
self.assertRaises(ZeroDivisionError, MyClass.div, 3, 0)
except ZeroDivisionError as e:
print (e) # assertRaisesRegexp()方法实例
def test_assertRaisesRegexp(self):
# 测试抛出的指定异常类型,并用正则表达式具体验证
# assertRaisesRegexp(exception, regexp)
with self.assertRaisesRegex(ValueError, 'literal') as ar:
int("xyz")
# 打印详细的异常信息
#print ar.exception
# 打印正则表达式
#print "re:",ar.expected_regexp # assertRaisesRegexp(exception, regexp, callable, *args, **kwds)
try:
self.assertRaisesRegexp(ValueError, "invalid literal for.*XYZ'$", int, 'XYZ')
except AssertionError as e:
print (e) if __name__ == '__main__':
# 执行单元测试
unittest.main()

举例4:生成图形化测试报告

导入文件HTMLTestRunner.py ;放到python的安装目录下(D:\Python37-32\Lib\site-packages)

运行对应的主方法:

import unittest

import HTMLTestRunner

if __name__ == '__main__' :
# 加载当前目录下所有有效的测试模块(以test开头的文件),“.”表示当前目录
testSuite = unittest.TestLoader().discover('.')
filename = "test.html" # 定义个报告存放路径,支持相对路径。
# 以二进制方式打开文件,准备写
fp = open(filename, 'wb')
# 使用HTMLTestRunner配置参数,输出报告路径、报告标题、描述,均可以配
runner = HTMLTestRunner.HTMLTestRunner(stream = fp,
title = 'Report_title', description = 'Report_description')
# 运行测试集合
runner.run(testSuite)

结果:

举例5:单元测试框架跑UI测试

#encoding=utf-8
import unittest
from selenium import webdriver
import time class GloryRoad(unittest.TestCase):
def setUp(self):
# 启动Chrome浏览器
# 驱动文件位置要改,本地自己的驱动
self.driver = webdriver.Chrome() def testSoGou(self):
# 访问搜狗首页
self.driver.get("http://sogou.com")
# 清空搜索输入框默认内容
self.driver.find_element_by_id("query").clear()
# 在搜索输入框中输入“光荣之路自动化测试”
self.driver.find_element_by_id("query").send_keys(u"WebDriver实战宝典")
# 单击“搜索”按钮
self.driver.find_element_by_id("stb").click()
# 等待3秒
time.sleep(3)
assert u"吴晓华" in self.driver.page_source, u"页面中不存在要寻找的关键字!".encode("gbk") def testBing(self):
# 访问bing首页
self.driver.get("http://cn.bing.com")
# 清空搜索输入框默认内容
self.driver.find_element_by_id("sb_form_q").clear()
# 在搜索输入框中输入“光荣之路自动化测试”
self.driver.find_element_by_id("sb_form_q").send_keys(u"WebDriver实战宝典")
# 单击“搜索”按钮
self.driver.find_element_by_id("sb_form_go").click()
# 等待3秒
time.sleep(3)
assert u"吴晓华" in self.driver.page_source, u"页面中不存在要寻找的关键字!".encode("gbk") def tearDown(self):
# 退出浏览器
self.driver.quit() if __name__ == '__main__':
unittest.main()

举例6:单元测试和ddt数据驱动结合

安装包:pip3 install ddt

代码:

import unittest
import ddt @ddt.ddt
class Praddt(unittest.TestCase): def setUp(self):
print("my test start!") def tearDown(self):
print("my test complete!") @ddt.data(["admin", "1qaz", "OK"], #一组数据,每一行都会触发运行
["admin", "", "ERROR"], #另一组数据
["1", "1qaz", "ERROR"], #另一组数据..
["admin", "1234", "ERROR"],
["Admin", "1qaz", "ERROR"]) #实现了数据驱动,可以执行5次 @ddt.unpack
def test_ddt(self, user, passwd, expect_value):
print(user,passwd,expect_value)
self.assertTrue(len(user)>0) if __name__ == '__main__':
# 执行单元测试
unittest.main()

测试结果:

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

    测试的常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过se ...

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

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

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

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

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

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

随机推荐

  1. AI绘画| 迪士尼风格|可爱头像【附Midjourney提示词】

    Midjourney案例分享 图片预览 迪士尼风格|可爱头像 高清原图及关键词Prompt已经放在文末网盘,需要的自取 在数字艺术的新时代,人工智能绘画已经迅速崭露头角.作为最先进的技术之一,AI绘画 ...

  2. 从原理聊 JVM(五):JVM 的编译过程和优化手段

    一.前端编译 前端编译就是将Java源码文件编译成Class文件的过程,编译过程分为4步: 1 准备 初始化插入式注解处理器(Annotation Processing Tool). 2 解析与填充符 ...

  3. Netease研发实习生一面

    最想去的公司和部门..今天终于面了,感觉跪了..实质性的问题的确打得不好..庆幸的是拿到了B公司的offer,实习是不愁了.. 记下问题,希望对之后的同学有一定帮助. 问的问题总结: 1.进程线程协程 ...

  4. k8s 入门到实战--部署应用到 k8s

    背景 最近这这段时间更新了一些 k8s 相关的博客和视频,也收到了一些反馈:大概分为这几类: 公司已经经历过服务化改造了,但还未接触过云原生. 公司部分应用进行了云原生改造,但大部分工作是由基础架构和 ...

  5. WEB组态编辑器插件(BY组态)介绍

    BY组态是一款非常优秀的纯前端的[web组态插件工具],采用标准HTML5技术,基于B/S架构进行开发,支持WEB端呈现,支持在浏览器端完成便捷的人机交互,简单的拖拽即可完成可视化页面的设计.可无缝嵌 ...

  6. 每日一题:如何判断是否是数组,一个既简单又复杂的问题。(不要再用Object.prototype.toString.call、instance of判断了!!!)

    1.不要使用Object.prototype.toString.call() 正常情况下: const arr = [1,2,3,4,5] const obj = {} console.log(Obj ...

  7. 「Semigroup と Monoid と Functional と」

    一个被国内 oi 环境弱化至几乎不存在的概念,不过我觉得还是有学一学的必要.因为我没学过代数结构所以大部分内容都在开黄腔,欲喷从轻. Semigroup 的定义是,\(\forall a,b\in\m ...

  8. 新零售SaaS架构:面向中小连锁的SaaS系统整体规划

    零售企业的发展路径 零售企业的发展路径一般可分为以下几个阶段: 单店经营阶段:企业在一个地区或城市开设单个门店.这时,企业需要把精力放在了解当地市场和顾客需求上,这是积累经验和品牌知名度的重要环节.为 ...

  9. 解决软件安装无法自定义文件夹,自动安装在C盘 (Windows系统)

    其实就是软链接的简单应用 1.软件已经自动安装 2.完全退出当前软件 3.通过软件图标的属性找到其实际的安装目录 4.进入该软件的安装目录 5.将该软件整个剪切(你没有看错)到指定文件夹(自定义的安装 ...

  10. socket应用的例子

    当使用 C 语言实现 Socket 编程时,可以通过系统提供的网络库来实现网络通信.以下是一个简单的示例,演示了如何创建一个简单的服务器和客户端,实现客户端向服务器发送消息并接收回复的功能. 服务器端 ...