原理

参考:单元测试原理

背景

年后有段时间没写代码了,所以趁着周末找了个python单元测试玩下,测试自己的Android应用。发现PyUnit虽然在单个脚本文件中添加多个测试用例,比如官网提供的方法:官网地址

        import unittest

        class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget("The widget")
def tearDown(self):
self.widget.dispose()
self.widget = None
def testDefaultSize(self):
assert self.widget.size() == (50,50), 'incorrect default size'
def testResize(self):
self.widget.resize(100,150)
assert self.widget.size() == (100,150), \
'wrong size after resize'

然后结合HTMLTestRunner模块,就可以简单执行一个测试脚本并生成测试报告,如下图(整改之后的):

然而发现有个不好用的地方,每一次执行单元测试脚本后都会生成一个报告,所以有了修改单元测试的想法(增加截图、日志、批量执行所有的脚本并合成一份报告)

思路

查看单元测试报告html源码,发现增加截图、日志比较容易,但是要整合每一个单元测试的报告对我来说就比较难,所以采用下边的方法:

1、直接继承现有的测试报告,在上边增加截图、日志查看功能


2、遍历所有的单元测试脚本名称、类名,动态的加载脚本名称 + 类名 + 方法名到单元测试集合中


3、最后用HTMLTestRunner.HTMLTestRunner模块的run方法执行

搞起

增加截图

根据单元测试流程,最终在HTMLTestRunner._generate_report_test()方法中增加一个截图保存参数

        import CommonLib
print CommonLib.screenshotPath
row = tmpl % dict(
tid = tid,
Class = (n == 0 and 'hiddenRow' or 'none'),
style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),
desc = desc,
'''截图参数'''
screenshot = str(CommonLib.screenshotPath),
script = script,
status = self.STATUS[n],
)
rows.append(row)
if not has_output:
return

在HTMLTestRunner._generate_report_test()方法使用的html模板REPORT_TEST_WITH_OUTPUT_TMPL中增加截图标签。方法:查看单元测试报告源码,里边有个error异常的标签,所以在同级的地方增加截图标签

<a href="%(screenshot)s">screenshot</a>

<a href="%(logcat)s">logdetail</a>

效果如上边的单元测试报告截图。增加日志的方法应该差不多

动态加载单元测试依赖的模块

有两种方法:

1、使用importlib动态加载,但是在调试的过程中发现,循环加载模块时会报模块未定义的错,搞了半天没搞定,所以pass掉

2、使用文件遍历的方式,找到所以单元测试脚本名称 + 类名 + 方法名。为了方便,我把每个脚本的名称和类名都定义成一样、所有脚本的测试方法都是teststep()

步骤:

1、遍历单元测试脚本路径下所有脚本并记录脚本名称

def get_file_name(path):
'''
@see: 遍历单元测试脚本文件下的.py文件并获取.py文件名
@param path: 单元测试脚本文件路径
'''
fileNameList = []
for root, dirs, files in os.walk(path):
if files:
for fi in files:
if 'init' in fi or '.pyc' in fi:
continue
if '.py' in fi:
fileNameList.append(fi.split('.')[0])
return fileNameList

2、单独写一个单元测试脚本unitTestDemo.py,用来添加所有的testcase到testsuite中

if __name__ == "__main__":
testsuite = unittest.TestSuite()
path = CommonLib.unittestcasePath
'''添加单个测试用例到测试集中:'''
TestDemo = add_testcase_to_suite(path)
testsuite.addTests(TestDemo)
def add_testcase_to_suite(path):
'''
@see: 添加测试用例集合
'''
fl = Util.get_file_name(path)
TestDemo = []
for f in fl:
ef = f + '.' + f + '("teststep")'
TestDemo.append(eval(ef))
return TestDemo

3、在脚本unitTestDemo.py中动态添加第一步中获取到的脚本名称 (即依赖的模块名称)

def config_unittest_demo_read(path, moudleName):
'''
@see: 追加单元测试脚本文件模块到单元测试集合脚本中
@param path: 单元测试集合脚本文件路径
@param moudleName: 单元测试脚本依赖的模块
'''
fl = []
fo = open(path,'r')
try:
for f in fo.readlines():
if 'from UnitTestDemo import' in f:
p = 'from.+?\r'
rc = re.compile(p)
fr = f.replace(rc.findall(f)[0], moudleName + '\r')
fl.append(fr)
continue
else:
fl.append(f)
return fl
except IOError,e:
print e
return False
finally:
fo.close()

4、使用HTMLTestRunner.HTMLTestRunner的run方法执行所有的脚本

    '''生成测试报告文件'''
file_name = CommonLib.unittestresultPath
fp = file(file_name, 'wb')
'''执行单元测试'''
renner = HTMLTestRunner.HTMLTestRunner(
stream=fp,
title='测试结果',
description='测试报告'
)
renner.run(testsuite)

命令行方式

为了批量执行方便,还可以使用命令行方式,具体可以查看官方的命令行运行方式。我这里使用bat脚本运行。首先初始化所有要执行的单元测试脚本的依赖,再执行unitTestDemo.py

configUTDemo.bat

cd E:\Python27
python E:\PythonProject\conifgUTDemo.py
ping 127.0.0.1 -n >nul

startUTTest.bat

cd E:\Python27
python E:\PythonProject\unitTestDemo.py
ping 127.0.0.1 -n >nul

如果有必要也可以加入到定时任务,定时执行

Python单元测试PyUnit框架轻度整改的更多相关文章

  1. selenium自动化测试、Python单元测试unittest框架以及测试报告和日志输出

    部分内容来自:https://www.cnblogs.com/klb561/p/8858122.html 一.基础介绍 核心概念:test case, testsuite, TestLoder,Tex ...

  2. python单元测试unittest框架

    环境:PyCharm 2016.2 + python 3.5 待测试的类:(Widget.py) 测试类:(Auto.py) 测试结果: 总结:1.第一步:先写好测试类2.第二步:导入unittest ...

  3. [译]PyUnit—Python单元测试框架(1)

    1. 原文及参考资料 原文链接:http://docs.python.org/2/library/unittest.html# 参考文档: http://pyunit.sourceforge.net/ ...

  4. python单元测试框架 pyunit

    概况 系统要求 使用PyUnit构建自己的测试 安装 测试用例介绍 创建一个简单测试用例 复用设置代码:创建固件 包含多个测试方法的测试用例类 将测试用例聚合成测试套件 嵌套测试用例 测试代码的放置位 ...

  5. Python单元测试框架

    目录 概况 系统要求 使用PyUnit构建自己的测试 安装 测试用例介绍 创建一个简单测试用例 复用设置代码:创建固件 包含多个测试方法的测试用例类 将测试用例聚合成测试套件 嵌套测试用例 测试代码的 ...

  6. Python单元测试框架之pytest 4 -- 断言

    From: https://www.cnblogs.com/fnng/p/4774676.html Python单元测试框架之pytest -- 断言 2015-08-31 23:57 by 虫师, ...

  7. Python单元测试框架之pytest 3 -- fixtures

    From: https://www.cnblogs.com/fnng/p/4769020.html Python单元测试框架之pytest -- fixtures 2015-08-29 13:05 b ...

  8. Python单元测试框架之pytest 2 -- 生成测试报告

    From: https://www.cnblogs.com/fnng/p/4768239.html Python单元测试框架之pytest -- 生成测试报告 2015-08-29 00:40 by ...

  9. python中的单元测试pyUnit

    python中的单元测试pyUnit   在Python中进行单元测试时需要用到PyUnit模块,Python 2.1及其以后的版本都将PyUnit作为一个标准模块,但如果你使用的是较老版本的Pyth ...

随机推荐

  1. objective-c学习笔记2

    Objective-c学习笔记 1.cocoa的对象初始化一般使用alloc和init两个方法,不适用new,其中alloc用于分配内存,init用于初始化,因为初始化方法返回的对象可能和分配的对象不 ...

  2. “canvas画布仿window系统自带画图软件"项目的思考

    "canvas画布仿window系统自带画图软件"项目的思考 首先贴上DEMO图,并没有美化效果.对UI有要求的,请自带补脑技术. 思考一 在做项目的过程中,我发现"工具 ...

  3. js Date 日期格式化(转)

    var myDate = new Date();myDate.getYear();        //获取当前年份(2位)myDate.getFullYear();    //获取完整的年份(4位,1 ...

  4. asp.net-mvc验证码 asp.net-mvc c#验证码

    验证码看不清换一组 写一个类 public class ValidateCode { public ValidateCode() { } /// <summary> /// 验证码的最大长 ...

  5. iOS开发——代理与block传值

    一.代理传值的方法 1.Hehe1ViewController.h中 #import <UIKit/UIKit.h> @protocol Hehe1ViewControllerDelega ...

  6. html块级元素和内联元素区别详解

    块级元素(block)特性: 总是独占一行,表现为另起一行开始,而且其后的元素也必须另起一行显示; 宽度(width).高度(height).内边距(padding)和外边距(margin)都可控制; ...

  7. 配置Log4J(转载)

    Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...

  8. CSS3 :target伪类实现Tab切换效果 BY commy

    http://www.shejidaren.com/examples/css3-target/css3-target.html#tab1 标签一 标签二 标签三 欢迎加设计达人Q群:50063010设 ...

  9. iOS 之 绘图简介

    iOS 实现图形编程主要有三种技术:UIKit.Core Graphics.OpenGL. 绘图需要在图形环境中进行,图形环境分为三种:屏幕图形环境.off screen 位图环境和PDF图形环境.在 ...

  10. Unity 压缩texture

    当我们往服务器保存图片时 并不会仅仅保留原图 一般会另外保存一张缩略图 当加载文件夹时只加载缩略图 当在点击缩略图打开图片时 再加载原缩略图 以节省时间和内存 下面以将屏幕截图保存到服务器为例 将屏幕 ...