- 一、不同文件用例构建测试套件
- 二、整合测试报告
- 三、测试报告优化
- 易读性优化
- 框架结构改进
- 用例读取改进
- 四、简单框架目录架构
生成HTMLTestRunner测试报告的时候,会发现一个.py文件产生一个测试报告,那么对于测试用例的多个测试用例文件会产生多个测试报告,这在实际中会导致测试报告不方便阅读
如果把所有测试用例写在一个py文件里,会导致用例不好维护。之前使用TestSuite只是在一个.py文件里添加多个测试用例,我们可以跨文件通过TestSuite来组织测试用例
实现组织用例结构如下: 测试套件文件解决后,多个文件中的测试用例执行生成的测试报告就会是一份测试报告
例如:
import unittest #导入单元测试框架
import asearch,baidu #导入测试用例py文件
alltest = unittest.TestSuite(); #构建测试套件
alltest.addTest(unittest.makeSuite(asearch.search)); #增加测试用例集
alltest.addTest(unittest.makeSuite(baidu.baidu)); #增加测试用例集
runner = unittest.TextTestRunner(verbosity=2);
runner.run(alltest); #运行测试
makeSuite用于生产testsuite对象的实例,把所有的测试用例组装成TestSuite,最后把TestSuite传给TestRunner执行,文件结构如下图所示 另一种嵌套测试套件的语法如下:
suite1 = module1.TheTestSuite();
suite2 = module2.TheTestSuite();
alltests = unittest.TestSuite((suite1, suite2));
二、整合测试报告
import unittest #导入单元测试框架
import asearch,baidu #导入测试用例py文件
import HTMLTestRunner
alltest = unittest.TestSuite(); #构建测试套件
alltest.addTest(unittest.makeSuite(asearch.search)); #增加测试用例集
alltest.addTest(unittest.makeSuite(baidu.baidu)); #增加测试用例集
filename = 'D:\\unittest\\test_case\\result.html';
fp = file(filename,'wb');
runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title=u"百度知道测试报告",description=u"用例执行情况test:");
runner.run(alltest);
备注:unittest.makeSuite()是直接从一个TestCase的类生成一个TestSuite。测试套件运行每个测试用例的顺序是由测试方法名根据Python内建函数cmp所排序的顺序而决定的
三、测试报告优化 易读性优化1.可以给每个测试用例加上注释
部分代码如下:
def test_baidu_set(self):
u"""百度知道链接测试"""
driver =self.driver
driver.maximize_window()
在函数后面加函数说明,得出的结果如下图: 2.名称加时间戳 引入Python的time模块给测试报告加自定义名称
部分代码如下:
import time
# 生成格式化时间
now = time.strftime("%Y_%m_%d_%H_%M_%S",time.localtime(time.time()))
#或now = time.strftime("%Y_%m_%d_%H_%M_%S”)采取字符串拼接给测试报告加时间
filename = 'D:\\unittest\\test_case\\'+ now +'_result.html'
# 生成的报告文件名格式为:2016_01_15_22_15_29_result.html
框架结构改进
1.执行用例的主文件移出测试用例文件夹 执行用例的主文件是执行所有测试用例的程序,而并非是测试用例本身,把它移出来结构更为合理。移出来执行用例的主文件后,会发现import 测试用例类报错,这是需要使用Python包
在test_case下新建一个 init.py 的文件,文件内容可以为空,同时将test_case目录添加到sys.path中
部分代码如下:
import sys
sys.path.append("\test_case")
from test_case import baidu,asearch
sys.path.append 把test_case目录添加到path下,使用的是相对路径当执行用例的主文件和测试用例放置在同一目录下,可以直接调用;移除出来之后就找不到模块了;Python查找模块是先从当前目录下查找,如果找不到再从安装python安装设置的相关路径下去查找,这里使用sys.path目的就是设置路径
为了标识一个目录是可引用的包,需要在目录下创建__init__.py的文件
2.__init__.py文件的使用 一个Python包是一个带有特殊文件 init.py 的目录。init.py 文件定义了包的属性和方法,它控制着包的导入行为
假如 init.py 为空,那么仅仅导入包是什么都做不了的。对于 from test_case import baidu,asearch 把baidu和asearch文件导入到测试用例执行主文件,也可以在__init__.py文件实现导入: 在__init__.py中添加如下内容:
import baidu
import asearch
然后在测试用例执行主文件中,可以如下方式调用baidu和asearch文件:
from test_case import *
这样也跟 编写代码from test_case import baidu,asearch 的作用是一致的
3.把用例中的公共模块移出 首先在test_case目录下创建一个Public目录,然后把一些公共的模块用函数或者类实现,比如:登录模块,退出模块,同时把测试用例做相应修改
测试用例中部分代码如下:
sys.path.append("\Public")
from Public import login
login.login()
代码结构如下图:
在实际过程中,可能我们需要组织成百上千条测试用例,虽然我们可以通过导入包文件的方式添加测试用例,但每创建一个新的测试用例都需要在测试套件中增加一条addTest语句,随着用例的增加,不便于管理和维护。
解决方法一: 首先把用例文件组装成为一个数组,然后使用for循环遍历的方式读取测试用例文件。 示例如下:
testnames = [asearch.search,baidu.baidu]
alltest = unittest.TestSuite() #构建测试套件
for testname in testnames:
alltest.addTest(unittest.makeSuite(testname)) #增加测试用例集
然后,为了在增添或者删除测试用例时不必对执行测试用例的主文件做任何修改,可以把用例列表放置到一个单独的文件中通过执行测试用例的主文件导入
解决方法二: 使用discover解决用例的读取。在使用解决方法一for循环处理用例读取的时候,如果新增测试用例文件testa.py,那么需要在 init.py 文件中编写import testa,还需要在测试用例列表文件的数组中增加相应测试用例名称,这样才能使新的测试用例添加到测试套件中执行,这样做显然不方便。对于上述情况,可以使用TestLoader(测试用例加载器)中的加载多个测试用例方法来实现
discover函数原型如下:
discover(start_dir, pattern='test*.py', top_level_dir=None)
递归查找指定目录(start_dir)及其子目录下的全部测试模块,将这些测试模块放入一个TestSuite 对象并返回。只有匹配pattern的测试文件才会被加载到TestSuite中。如果一个测试文件的名称符合pattern,将检查该文件是否包含 load_tests()函数,如果 load_tests() 函数存在,则由该函数负责加载本文件中的测试用例。如果不存在,就会执行loadTestsFromModule(),查找该文件中派生自TestCase 的类包含的 test 开头的方法。top_level_dir=None :测试模块的顶级目录(指测试用例不是放在多级目录中),如果没有顶级目录,默认为空
discover使用举例:
test_lists = "D:\\unittest\\test_case";
def createsuite():
testunit = unittest.TestSuite();
discover = unittest.defaultTestLoader.discover(
test_lists, pattern='ok_*.py',
top_level_dir=None
)
for testsu in discover:
for testcase in testsu:
testunit.addTests(testcase);
return testunit;
testnames = createsuite();
runner.run(testnames);
在实际测试用例开发过程中,我们可以使用约定,写好的用例用ok_或者其他标识开头,没有写好的暂时不用ok_开头。不然会影响测试用例的执行
四、简单框架目录架构