单元测试框架unitest和自动化测试高级应用
单元测试框架:为了让单元测试代码更容易维护和编写,遵循一定的规范来编写测试用例。
创建被测类calculator.py
#计算器
class count:
def _init_(self,a,b)
self.a = int(a)
self.b = int(b)
#计算加法
def add(self):
return self.a + self.b
通过unittest单元测试框架编写单元测试用例 test.py
from calculator import count
import unitest
class TestCount(unitest.TestCase):
def setUp(self):
print("test start")
def test_add(self):
j = count(2,3)
self.assertEqual(j.add(),5)
def tearDown(self):
print("test end")
if _name_ == '_main_':
unittest.main()
说明:1.首先引入unitest模块,创建testcount类继承unitest的testcase类。
2.setUp():用于测试用例执行前的初始化工作,与tearDown()相呼应,用于执行后的善后工作。
3.test_add中调用count类并传入要计算的数,通过调用add()方法得到两数相加的返回值,
这里不再使用繁琐的异常处理,而是调用unitest框架所提供的assertEqual()对add()的返回值进行断言
判断两者是否相等。assertEqual()方法是由testcase类继承而来的。
4.main():unitest提供了全局的main()方法,使用它可以方便的将一个单元测试模块变成可以直接运行的测试脚本。
main()方法使用Testloader类来搜索所有包含在该模块中以“test”命名开头的测试方法。
5._name_:作为模块的内置属性,简单地说就是.py文件的调用方式。.py文件有两种使用方式
作为模块调用和直接使用,如果它等于“_main_”就表示是直接使用
1.重要概念
1.TestCase:一个TestCase的实例就是一个测试用例,是一个完整的测试流程,包括测试前准备环境的搭建(setUp),
实现测试过程的代码(run),测试后环境的还原(tearDown).
2.Test Suite:把多个测试用例集合在一起来执行。可以通过addTest加载TestCase到Test Suite中,从而返回一个TestSuite实例。
3.Test Runner:测试的执行,通过TextTestRunner类提供的run()方法来执行Test Suite/TestCase。Test Runner可以使用图形界面,
文本界面,或者返回一个特殊的值的方式来表示测试执行的结果。
4.Test Fixture:对一个测试用例环境的搭建和销毁。通过覆盖TestCase的setUp()和tearDown()方法来实现。tearDown()为下一个
测试用例提供一个干净的环境。
from calculator import count
import unitest
class TestCount(unitest.TestCase):
def setUp(self):
print("test start")
def test_add(self):
j = count(2,3)
self.assertEqual(j.add(),5)
def test_add2(self):
j = count(7,8)
self.assertEqual(j.add(),15)
def tearDown(self):
print("test end")
if _name_ == '_main_':
unittest.main()
#构建测试集
suite = unittest.TestSuite()
suite.addTest(TestCount("test_add2"))
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
本例只执行第二个测试用例,1.调用unittest框架的TestSuite()来创建测试套件。
2.通过它所提供的addTest()方法来添加测试用例test_add2。
3.调用unitest框架的TextTestRunner().
4.通过它下面的run()方法来运行suite所组装的测试用例。
2.断言方法
unittest框架的TestCase类提供的断言方法用于测试结果的判断
1. 格式:-assertEqual(first,second,msg=None)
断言第一个参数和第二个参数是否相等,如果不相等则测试失败,msg为可选参数,用于定义测试失败时打印的信息。
比如:self.assertEqual(j.add(),15,msg="测试结果不等于15")
格式:-assertNotEqual(first,second,msg=None)则与之相反
2. 格式:-assertTrue(expr,msg=None)
-assertFalse(expr,msg=None)
测试表达式是true(或false)
创建count.py用于判断质数的
def is_prime(n):
if n<=1:
return False
for i in range(2,n):
if n % i = = 0:
return False
retun True
测试用例:调用is_prime()函数和unittest
self.assertTrue(is_prime(7),msg="is not prime")
3. 格式:-assertIn(first,second,msg=None)
-assertNotIn(first,second,msg=None)
断言第一个参数是否在第二个参数中,就是第二个参数是否包含第一个参数。
测试用例(部分):
def test_case(self):
a = "hello"
b = "hello world"
self.assertIn(a,b,msg="a is not in b")
4.格式:-assertIs(first,second,msg=None)
-assertIsNot(first,second,msg=None)
断言第一个参数和第二个参数是否为同一对象
5.格式:-assertIsNone(expr,msg=None)
-assertIsNotNone(expr,msg=None)
断言表达式是否为None对象
6.格式:-assertIsInstance(obj,cls,msg=None)
-assertNotIsInstance(obj,cls,msg=None)
断言obj是否为cls的一个实例
3.组织单元测试用例
方法1.setUp()和setDown方法分别作用于每个测试用例的开始和结束
方法2.如果每个类中的setUp()和setDown方法所做的事情是一样的,那么可以封装成一个自己的测试类
4.discover更多测试用例
如果单元测试用例达到成百上千个,可以将这些用例按照所测试的功能进行拆分,分散到不同的测试文件中
最后再创建用于执行所有测试用例的runtest.py文件。
方法1:可以通过addTest()加载TestCase到TestSuite中。用于少量的测试用例
方法2:使用TestLoader类提供的discover()方法来加载所有的测试用例。正常情况下,不需要创建这个类的实例,
unittest提供了可以共享的defaultTestLoader类,可以使其子类和方法创建实例,discover()方法就是其中之一。
格式:discover(start_dir,pattern='test*.py',top_level_dir=None)
start_dir:要测试的模块名或测试用例的目录
pattern='test*.py':表示用例文件名的匹配原则,此处文件名以“test”开头的“.py”类型的文件,“*”表示任意多个字符。
top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,默认为None.
5.用例执行的原则
unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以TestAdd会优于
TestBdd类被执行,test_aaa()方法会优于test_ccc被执行,因而它并没有按照用例从上到下的顺序执行。对于
测试目录和测试文件来说,unittest框架同样是按照这个规则来加载测试用例的。
如果按照指定的顺序执行,可以通过TestSuite类的addTest()方法按照一定得顺序加载。不能默认main()方法了。
构造测试集,然后通过run()方法执行测试。
注意:discover()的加载测试用例的规则与main()方法相同,所以只能通过测试用例的命名来提高被执行的优先级。
6.执行多级的用例
discover()方法中的start_dir只能加载当前目录下的.py文件,如果加载子目录下的.py文件,需在每个子目录下放
一个_init_.py文件。
7.跳过测试和预期失败
unittest提供了实现某些需求的装饰器,在 执行测试用例时每个装饰前面加@符号。
unittest.skip(reason):无条件的跳过装饰的测试,说明跳过测试的原因
unittest.skipIf(condition,reason):跳过装饰的测试,如果条件为真。
unittest.skipUnless(condition,reason):跳过装饰的测试,除非条件为真。
unittest.expectedFailure():测试标记为失败,不管执行结果是否失败,统一标记为失败,但不会抛出错误信息。
8.fixtures
fixtures可以形象的把他看作是夹心饼干外层的两片饼干,这两片饼干就是setUp/tearDown,中间的心就是测试用例,
除此以外,unittest还提供了更大范围的fixtures,例如对于测试类和模块的fixtures。
setUpModule/tearDownModule:在整个模块的开始和结束时被执行。
setUpClass/tearDownClass: 在测试类的开始和结束时被执行。
setUp/tearDown:在测试用例的开始与结束时被执行
注意:setUpClass/tearDownClass的写法稍有不同,首先通过@classmethod进行装饰,其次方法的参数为cls,也可以是别的。
每一个上面都要进行装饰
自动化测试高级应用
9.HTML测试报告
HTMLTestRunner是python标准库unittest单元测试框架的一个拓展,它生成易于使用的HTML测试报告。
HTMLTestRunner下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html
这个拓展只有一个HTMLTestRunner.py文件,选中后单击鼠标右键,在弹出的快捷菜单中选择目标另存为,
将它保存到本地。安装方法是将其复制到python安装目录下即可。
windows:将下载的文件保存到...\python35\Lib目录下
Ubuntu:以root身份将HTMLTestRunner.py文件复制到/usr/local/python3.4/dist-packages/目录下。
HTMLTestRunner.py文件是基于python2开发的,若要支持python3 环境需要对其中的部分内容进行修改。
生成测试报告的步骤:
1.将HTMLTestRunner模块用import导入进来
2.通过open()方法以二进制写模式打开当前目录下的result.html,如果没有,则自动创建该文件。
3.调用HTMLTestRunner模块下的HTMLTestRunner类,stream指定测试报告文件,title用于定义测试报告的标题,
description用于定义测试报告的副标题。
4.最后,通过HTMLTestRunner的run()方法来运行测试套件中所组装的测试用例。
5.通过close()关闭测试报告文件。
10.更易读的测试报告
方法:加注释并用一种方法读取
在类和方法的下方,通过三引号(""" """或''' ''')来添加doc string类型的注释,这类注释在平时调用的时候
不显示,可以通过help()方法来查看类或方法的这种注释。
HTMLTestRunner可以读取doc string类型的注释,所以只需给测试类或方法添加这种类型的注释即可。
11.测试报告文件名
在每次运行测试之前,都要手动修改报告的名称,如果忘记修改,就会把之前的报告覆盖,为了使每次生成
的报告名称都不重复并且有意义,最好的方法是在报告名称中加入当前时间,这样生成的报告既不会重叠,
又能更清晰的知道报告的生成时间。
time.time():获取当前时间戳 比如:1445694559.2290168
time.ctime():当前时间的字符串形式 比如:'sat oct 24 21:49:29 2015'
time.localtime():当前时间的struct_time形式 比如:tm_year=2015,tm_mon=10,tm_mday=24,..........等等。
time.strftime("%Y_%m_%d %H:%M:%s"):用来获得当前时间,可以将时间格式化为字符串。比如:'2015_10_24 21:50:15'
方法:通过时间操作的方法以指定的格式获取当前时间,将当前时间的字符串赋值给now变量,将now通过加号(+)拼接到生成的
测试报告的文件名中,再次运行测试用例,生成测试报告文件名。
12.项目集成测试报告
目前HTMLTestRunner只是针对单个测试文件生成测试报告,若要使其作用于整个测试项目,
要将它集成到runtest.py文件中,对其文件进行修改。
13.自动发邮件功能
SMTP:是简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
python的smtplib模块提供了一种很方便的途径用来发送电子邮件,它对SMTP协议进行了简单的封装。
导入SMTP对象,通过help()查看对象的注释,从中找到sendmail()方法的使用说明。
发送HTML格式的邮件
除了引入SMTP模块外,还要用到email模块,它主要用来定义邮件的标题和正文,Header()方法用来定义邮件的标题,
MIMEText()用于定义邮件正文,参数为html格式的文本。
发送带附件的邮件
通过MIMEMultipart()模块构造带附件的邮件
查找最新的测试报告
1.首先定义测试报告的目录result_dir,os.listdir()可以获取目录下的所有文件及文件夹。
2.利用sort()方法对目录下的文件及文件夹按时间重新排序。
3.list[-1]取到的就是最新生成的文件或文件夹。
整合自动发邮件功能
1.通过unittest框架的discover()找到匹配测试用例,由HTMLTestRunner的run()方法执行测试用例并生成最新的测试报告。
2.调用new_report()函数找到测试报告目录(report)下最新生成的测试报告,返回测试报告的路径。
3.将得到的最新测试报告的完整路径传给send_mail()函数,实现发邮件功能。
14.认识Page Object
Page Object设计模式的优点:
1.减少代码的重复性
2.提高测试用例的可读性
3.提高测试用例的可维护性,特别是针对UI频繁变化的项目
为web页面编写测试时,需要操作该web页面上的元素,如果在测试代码中直接操作HTML元素,那么你的代码是极其脆弱的,因为UI经常变动。
我们可以将一个page对象封装成一个HTML页面,然后通过提供的应用程序特定的API来操作页面元素,而不是在HTML中四处搜寻。
page对象应当将在GUI控件上所有查询和操作数据的行为封装为方法,即使改变具体的控件,page对象的接口也不应当发生变化。
“页面”对象不仅是针对每个页面建立一个这样的对象,对由重要意义的元素也可以独立为一个page对象。
15.Page Object实例
1.创建page类
2.创建LoginPage类
3.创建test_user_login()函数
4.创建main()函数
单元测试框架unitest和自动化测试高级应用的更多相关文章
- 【Python】单元测试框架unitest及其高级应用
Unittest Unittest是python的一个单元测试框架,但是它不仅适用于单元测试,还适用自动化测试用例的开发与执行.我们可以很方便的使用它组织执行测试用例,使用它提供的丰富的断言方法进行测 ...
- python之使用单元测试框架unittest执行自动化测试
Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 单元测试框架即一堆工具的集合. 在说unittest ...
- Selenium自动化测试-unittest单元测试框架
一.Pyhon工作原理-- 核心概念:test case, testsuite, TestLoder,TextTestRunner,TextTestResult, test fixture TestC ...
- 华为五年自动化测试工程详细解说:unittest单元测试框架
一.单元测试框架说明 单元测试是指在编程中,针对程序模块的最小单元(类中的方法)进行正确性检验的测试工作.python+selenium自动化测试中通常使用unittest或者pytest作为单元 ...
- Selenium自动化测试-unittest单元测试框架使用
一.什么是unittest 这里我们将要用的unittest是python的单元测试框架,它的官网是 https://docs.python.org/2/library/unittest.html,在 ...
- Qt高级——QTestLib单元测试框架
一.QTestLib简介 1.QTestLib简介 QTestLib是Qt提供的一种针对基于Qt编写的程序或库的单元测试框架.QTestLib提供了单元测试框架的基本功能,并提供了针对GUI测试的扩展 ...
- Selenium 2自动化测试实战26(unittest单元测试框架)
一.unittest单元测试框架 1.认识单元测试 1.断言方法 #计算器类 #coding:utf-8 #计算器类 class Count: def __init__(self,a,b): self ...
- Groovy单元测试框架spock数据驱动Demo
spock是一款全能型的单元测试框架. 上次文章分享了spock框架的基础功能的使用,在此基础上,我根据自己写的Groovy的封装方法.数据驱动以及一些Groovy的高级语法做了一些尝试.发现还是有一 ...
- Groovy单元测试框架spock基础功能Demo
spock是一款全能型的单元测试框架. 最近在做单元测试框架的调研和尝试,目前确定的方案框架包括是:spock,Junit,Mockito以及powermock.由于本身使用Groovy的原因,比较钟 ...
随机推荐
- [51nod1227]平均最小公倍数(莫比乌斯反演+杜教筛)
题意 求 $\sum_{i=a}^b \sum_{j=1}^i \frac{lcm(i,j)}{i}$. 分析 只需要求出前缀和, $$\begin{aligned}\sum_{i=1}^n \sum ...
- hadoop java.io.EOFException: Unexpected end of input stream
执行hadoop 报错 java.io.EOFException: Unexpected end of input stream at org.apache.hadoop.io.compress.De ...
- SDOI2010选做
Round1 D1T1外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\ ...
- 转载-mysql中文编码问题
具体原理见:MySQL:windows中困扰着我们的中文乱码问题 分割线: 我的电脑win7 64位,这个问题可能是所有win系统出现的问题 我出现的问题: 是正确的 出现了中文的张三,则错误,编码错 ...
- python paramiko模块简介及安装
一:简介 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 由于使用的是python这样的能够跨平台运行的语言,所以所有python支 ...
- 回溯法 | n皇后问题
今早上看了一篇英语阅读之后,莫名有些空虚寂寞冷.拿出算法书,研读回溯法.我觉得n皇后问题完全可以用暴力方式,即先对n个数进行全排列,得到所有结果的下标组合,问题规模为n!. 全排列花了比较久的时间才编 ...
- Spring Boot 知识笔记(thymleaf模板引擎)
一.pom.xml中引入 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...
- 第10组 Alpha事后诸葛亮
一.组长博客链接 组长博客 二.总结思考 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的APP主要解决大学生闲置物品处理问题,定义的很清楚,用户 ...
- web前端图片模糊到清晰的实现过程
在网页图片显示的时候,会发现许多网站采用了先模糊,然后在慢慢清晰的过程,这样的加载用户体验是比较好的,那么如何实现? 默认加载2张图片,一张缩略图,一张原图,当打开网页的时候默认只显示缩略图,然后我们 ...
- Python 3.X 练习集100题 03
一个整数,它加上 100 后是一个完全平方数,再加上 168 又是一个完全平方数,请问该数是多少? import math for i in range(10000): n1 = math.sqrt( ...