昨天一位园友sinodragon21在Windows phone应用开发[9]-单元测试评论中.提出关于Windows phone 单元测试中可否使用微软的Pex自动化生成工具生成单元测试用例.和单元测试质量即代码覆盖率统计问题.颇有价值.html
针对这两个问题.首先须要解释.关于Windows phone 中单元测试现状.针对Windows phone应用程序Unit Test 官方并无在IDE提供对应的测试框架,目前开发者社区使用比较普遍框架是MS Windows phone 产品组Jeff.wilcox维护的Silverlight Unit Test Framework[SUTF] Windows phone版本.详见Blog:Updated Silverlight Unit Test Framework bits for Windows Phone and Silverlight 3 . 但这个版本始终做为我的形式对开发者发布.并无以正式的官方渠道向Windows phone开发者推送,因此官方对此并无提供指定的维护和开发者社区支持.数组
至此官方也就没有提供自动化测试工具道理. 相似Android 平台自动化Monkeyrunner以外还有更多选择.而Windows phone自动化测试只能靠开发者本身想办法.app
那么关于SUTF 中Code Converage代码覆盖率呢? 针对这个问题 特别咨询SUTF WP版本维护做者Jeff.Wilcox.获得回复信息以下:框架
HI Jeff,
how to take code coverage from SilverLight Unit test framework for WP7?编辑器
jeffwilcox Reply:ide
Code coverage is not available, it was a feature that was cut before
shipping for 2010 from the toolkit.函数
在2010年发布SUTF版本时已经去掉对Code Converage支持. so.既然如此是否真的就此定论了.? Now 如今提到Pex and Moles.仍是不甘心.打算动手在应用程序中亲自验证.本篇并不打算当即采用Pex在SUTF进行验证.有必要系统了解Pex and Moles.工具
<1>构建Pex测试环境Well.关于Pex And Moles其实能够分为两个部分.其一Pex-全称是[Program EXploration]是微软研究院的一个关于白盒测试自动生成工具.原来开发人员只能经过指定路径编写独立的测试用例.PEX经过分析代码来自动生成测试用例。对于程序里面的每一行代码,PEX都会尽量地生成合适的输入值来达到提升覆盖率的目标。同时PEX还会分析代码中的分支,生成覆盖更多分支的测试代码(输入数据);PEX在执行代码的同时会监控和分析代码的控制流和数据流,了解程序的行为。每运行完单一个测试之后,PEX会选择一条在前面的测试中没有覆盖到的路径,而且尝试执行它.本篇主要来说到的是PEX.单元测试
PEX自动化生成用例并执行UT返回测试结果的过程.大大减小开发人员手动编写大量测试用例状况发生.测试
关于PEX and Moles可经过以下连接了解更多:
PEX And Moles:
Pex and Moles - Isolation and White box Unit Testing for .NET
Download Page:
Pex and Moles – Download Page LinkGet Start Online PDF Document:
找到下载页面.PEX如今有3个Flavor,支持2个版本的Visual Studio,分别是VSTS2010和VSTS2008,这3个版本的PEX在功能上存在区别,这主要由于下载受众群体不一样,通常用户只能使用到PEX功能.本篇全部演示都是基于Visual Studio 2010. 基于MSDN订阅权限下载PEX And Moles完整版本.
安装完成后.能够打开Visua Studio 当即建立一个Console Application命名为BasicConsolePexComponent_Demo,在此先不要把焦点放在PEX原理实现上.来快速体验一下PEX.首先须要在Program类中顶一个转换字符串的方式.做为测试用例的宿主程序.建立以下:
well通常状况下.关于如何创建单元测试应用程序,通常若是没有PEX以前.可能做为开发人员更多的是根据该方法实现.建立一个新的Test测试项目.构建对应测试用例.实现对该方法的UT.其实这个过程已经Visual Studio内置了这些工做已经自动建立.只需右键点击就能看到Create Unit Test选项:
点击后能发现.其实Create Unit TEst为了不测试框架和测试用例污染源代码自己.通常状况要对单元测试用例和源代码执行分离.也就是建立一个新的单独测试项目.
此时在执行测试以前须要作一些设置点击Settings按钮:
须要设置建立默认文件以及对应测试类和测试方法名称.点击ok.若是没有设置对应测试项目名称会以下提示:
修改完成后开始建立.建立过程可能会有以下提示:
建立前提示主要提到两点.须要为测试项目BasiceConsolePexComponent_Demo设置InternalsVisible属性可用.这是设置其实内在的缘由是.对一个组件或模块进行单元测试时.单元测试用例须要调用定义在测试组件或模块中的Internal成员对象时. 须要跨程序集访问.而Modifier的Internal类型成员默认设置仅限于当前程序集访问.而对宿主程序而言须要暴露给测试程序集调用.
另一点在不少状况下,咱们须要将最终的程序集以强命名的形式发布。为此,咱们修改Lib项目设置,开启"Sign the assembly”开关,并建立一个密钥文件.不能经过编译,具体的错误信息为:“Friend assembly reference 'Test' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.”,针对须要指定的不是程序名的强命名,而是指定对程序集进行签名时采用的公钥.把公钥指定到InternalsVisibleToAttribute特性中便可.
点击ok.看一下项目结构:
多了一个测试项目和该项对应Program方法测试类.now构建好了测试项目.在回到宿主程序Program类中对字符串转换操做的方法见一个UT.找到该方法名右键依然可见Create Unit Test选项点击看到:
能够看到针对方法作UT时会把该UT的应用程序的输出默认为刚才建立的测试项目:AutomationConsole.Test.点击ok.找到测试项目下ProgramProgramTestHelper类能够看到增长一个测试方法以下:
能够看到该测试方法命名依然采用默认命名方式.方法内代码实现关于调用Program类中字符串转换大写操做的方法ConvertStringToUpper. 分别定义三个变量的字.其实从变量名称彻底能够看出这是一个默认的测试用例.要想改UT达到想作.只需修改对应变量参数的值来匹配.InputString做为方法参数输入.通过测试用例会会生成对应指望值和方法执行实际值.最后经过对指望值和实际比对得到对应测试结果.直接运行 能够看到测试结果以下:
well由于两个测试用例都没作了修改没有实际值传入因此都是Inconcluetive测试结果不肯定.如今看看这种传统方式下一Visual Studio Unit TEst框架为主UT编写开发人员要重复作哪些工做.?首先要重复手动编写大量的UT测试用例.目的是在给定的方法中为每一个执行路径手写独立测试. 并且针对这种没法避免的要建立一个独立的测试项目.其实在实际编码中.并非全部模块都须要即时创建UT.可能需求发生变动.从开发人员角度来讲建立一个笨重测试项目这意味更多精力发在测试代码维护上.可能咱们更须要一种既可以建立对应测试项目同时也能即时看到当前版本Code UT效果.
Now.UT属于白盒测试的范畴.若是可以有一个很好白盒测试工具可以封装这些重复的行为.并可以重复执行UT测试用例.让开发人员从Ut的过多细节和维护中解放出来关注更核心的业务逻辑.Pex and moles就是这样的一个工具.
<2>Pex 构建白盒测试虽然本篇幅没有核心焦点放到Pex实现原理上.但关于Pex and Moles其实分为两块整理官方原文翻译以下[直译]:
Pex Pex 是一个 Visual Studio 外接程序,用于补充 .NET Framework 应用程序上的单元测试。 Pex 在 Visual Studio 代码编辑器中查找对应程序方法的输入和输出值。 PEx将这些值另存为将具备高代码覆盖率的小型测试套件。
Moles Moles 容许开发人员将任何 .NET 方法替换为委托。 Moles 经过使用 Detour 和 Stub 提供隔离来支持单元测试。 由于 Moles 在方法级别工做,因此当目标 API 不支持它时,它提供替代项进行模拟。 SharePoint 是一个受益于隔离的常见 API 示例,但不直接支持模拟。Moles 还可用于错误植入,由于它使得开发人员在测试下向代码中注入任意行为变得轻松.
Pex核心是给开发人员一个手写的参数化单元测试,Pex彻底自动地分析代码,来决定相关的测试输入。其结果就是生成一个有着高度代码覆盖的传统单元测试,另外,Pex还会建议开发人员如何去修复所发现的Bug.
安装完Pex and Moles工具后.打开Visual Studio 能够看到右键选项中多了:
Run Pex 和Pex 下Create Parameterized Unit Tests两个可操做选项.针对Pex测试效果.首先在Programe类添加一个字符串合并操做方法代码以下:
注意该方法的输入参数firstname和lastname在方法内都没有判断是否空字符串或是Null并且里面涉及字符数组的操做.针对该方法采用Pex方式执行UT操做.右键调集选中Run Pex 提示以下:
注意咱们当前类是在Program类下.该类的签名以下:
提示的意思当前类型不可见.没法经过Pex方式建立UT,须要把当前类的签名改为公开 虚类型便可:
在来运行Run Pex 弹出执行 结果窗体以下:
能够看到Pex在没有建立一个独立单元测试项目和对应测试类状况.自动对当前方法进行白盒测试封装.运行测试109 Runs次.建立了7个测试用例. PEx会监视当前类,而且运行这个方法.执行屡次测试.其中有三次测试失败的.并Sunmmary/Exception 提出具体测试参数和出现的异常信息.
点击对应失败的测试用例.能够在右侧弹出对应异常堆栈详细信息.:
点击DEtails能够看到执行该测试用例的代码和对应异常信息:
在查看异常详情右侧窗口中.能够执行以下操做:
Save Test保存当前PEX的测试用例为普通单元测试用例.点击保存:
若是在此以前没有建立对应Pex测试项目会提示当前测试用例输出.或是提示建立一个新的测试项目:
上面Project Under Test是待测试的宿主项目.而下面是须要建立新的测试项目设置.点击OK建立一个新的测试项目.这里在RunPex时并无强制开发人员强制创建一个新的测试项目.可是这里SAve 目的是在于若是以为当前测试代码能够留存作之后回归测试.PEX也是支持测试代码保存的.
add Precondition是用来经过Pex自动添加代码来避免错误的发生.而All Exception则容许次异常在当前应用程序中出现.send to若是你的项目采用TFS版本控制.sendto操做会吧全部信息发到文本或剪切板中.这里全部的信息包括Detail和STack Trace 若是TFS里配置WorkItem,PEX会自动发送对应的WorkItem中.
well如今既然存在异常.经过Add PreCondition来经过Pex来修正.会看到以下菜单:
这个窗体中上半部分告诉开发人员PEX在当前会作哪些操做.操做会修改哪些方法等.下半部分则是PEX具体的添加的修复代码.能够看到对firstname输入参数因当前NullException异常因此添加了是否非Null的判断。点击Apply能够看到原来代码中添加一段判断代码 完整以下:
<pex>标签之间注释就是PEX修复是添加的代码.若是以为PEX代码不够美化.开发人员也彻底能够手工修改.自此你会看到PEX帮开发人员找到一个Bug并尝试不在维护UT代码的状况下并修复该异常.well.固然如上演示只是PEX做为白盒测试工具的丰富功能一个特性.其实刚开始看官方给出解释最吸引我莫过于它支持写参数化单元测试[Parameterized Unit Test].方式.
<3>Pex参数化单元测试在Pex中针对白盒测试提出参数化单元测试的概念-Parameterized Unit Test。Dang咱们经过PEX实现更多模块的UT操做.确保全部单个模块可以按照程序设计预期执行. 其实实际效果并不是如此.PEX经过一个指令一个指令地分析.NET代码,解释代码执行时的动做,而后“以一种彻底自动的方式,计算出那些能触发边角代码的相关测试输入。”
PEX在执行和分析代码行为时.只是获得代码最基本代码模块行为简单异常相似NullException.可是实际上开发人员并无写过一个关于全部模块集成起来以后完整测试用例. 没法预期当前软件的行为.PEX提供参数化的单元测试提供一种强大的方式来评估当前代码在集成后是否如预期同样行为.
找到上次增长SpiltStringToMerge字符串合并操做方法作实例.建立参数化单元测试:
找到该方法选中右键点击能够看到Pex->Create Parameterized Unit Tests选项:
若是原来没有建立对应的PEX测试项目会提示建立一个新的Test Project.与宿主程序分离.能够看到增对测试文件目标PEX增长多重过滤项. 在Test Project项目输出上若是没有建立Test Project则建立.固然针对建立的测试项目能够指定不一样的测试框架.PEX中集成了NUnit/Visual Studio Unit TEst/MbUnit V系列等.让开发人员以本身最熟悉的测试框架来维护测试代码.Pex还基于扩展反射可管理子协议API (Extended Reflection managed profiling API)对监测应用程序的集成提供了支持.在建立看一下设置项Settings:
能够设置默认建立的命名空间和测试类下默认PexMethod测试方法.这里采用默认方式建立:
建立成功后Solution目录:
打开ProgramTest.cs文件能够看到这个PEX自动生成的参数化单元测试方法:
其实关于PEX参数化单元测试的概念.其实它就是一个带有参数并经过调用宿主测试程序简单测试方法.其实这里不少人都很疑惑怎么和传统建立单元测试方法和PEX参数化方法区别在哪呢?其实昨天我在看到这时也很困惑好久.后来在官方找了不少资料.总算是找到一点权威的论述:
A unit test is a method without parameters represents a test case which typically executes. a method of a class-under-test with fixed arguments and verifies that it returns the.
expected result. A parameterized unit test (PUT) is the straightforward generalization。of a unit test by allowing parameters. PUTs make statements about the code’s behavior.
for an entire set of possible input values, instead of just a single exemplary input value.
相对传统建立的单元测试通常状况参数都是指定固定的参数值.并在执行后会预期函数中返回对应的结果.PEX参数化单元测试概念则不一样.在PEX中单元测试的参数能够输入任何可能的参数用来验证程序代码执行中全部可能的行为.你大概明白PEX提出这个概念的目的了吧.也就是说PEX在执行的时候会分析PEX参数化单元测试代码方式来查看宿主程序代码的行为.固然这个过程须要集成宿主程序的代码.而相对于传统固定参数值.PEX单元测试参数能够是任意的.这样更便于测试过程当中测试宿主程序代码可能出现崩溃的概率和行为.
当前已经建立PEX对应的测试项目.在回到宿主横须Program类中.再次运行Run PEX:
出了能看到原来Pex Test Results窗体测试结果.注意这时PEX内部根据测试须要会在测试项目对应测试ProgramTEst类中.建立普通测试方法[TestMethod]同时也会建立PEX下参数化单元测试. 建立普通测试的数量和测试结果中测试用例的数量是一致的.若是TestReaults.PEX使用7个用例那么在ProgramTest.SpiltStringToMerme.g.cs文件中确定会有相同数量的普通测试方法存在.PEX参数化单元测试方法则放在ProgramTest.cs文件中.
若是你以为这个过程不明显.或是想了解一些PEX工做处理过程.能够选中右键能够PEX->Delete Generated Unit Tests操做:
其实该操做的目的会自动删除ProgramTest.SpiltStringToMerme.g.cs文件中全部的普通测试方法[TestMethod]也就是当前使用测试用例.而后找到该方法在运行Run PEX./运行玩后能够找到对应测试实例的Save Test方式在把指定的测试用例保存到ProgramTest.SpiltStringToMerme.g.cs文件中.well 这里保存第一个经过的测试用例 低级Save TEst:
Apply.完成后.会看到ProgramTest.SpiltStringToMerme.g.cs文件中多了一个普通测试方法.同时在Test Result窗体中发现每一个测试的图标再也不包含一个磁盘位图而是一个对号.:
这样有选择的方式让开发人员很轻松可以保存在不一样版本需求变更生成的测试用例/.并且是可选择的.固然在添加过程每每会提示一些命名上问题例如以下提示:
这是由于如今PEX如今对中文GB2312格式支持存在乱码的问题. 固然在建立是PEX为了防止访问路径过长.就限制在PEX全部文件命名长度.
其实到这里不少人依然对PEX 参数化单元测试的概念依然有些困惑.这个概念其实很简单.但在实际运用你会发现它的实际用途的好处.若是你熟悉并经常使用的单元测试.但还不理解PEX中参数化单元测试概念.能够从如下几个方向去考虑[仅做参考]:
理解参数化单元测试的方向:
[1]:当时你手写普通的单元测试.思考如下你要测试代码的行为.在构建单元测试时你的须要多少个独立参数传入.?
[2]:目前尚不清楚确切的数字可能会是什么.但在测试过程它是很重要的,因PEX角度来讲开发人员永远有时间来即时建立和维护测试代码.
固然更多还请参考官方的资料:http://research.microsoft.com/en-us/projects/pex/default.aspx
<4>Pex小结本篇PEX 自身应用角度来阐述PEX相对传统单元测试所具备的特色.做为一个白盒的测试工具.开发人员常在程序开发过程当中.需求每每也是不断变化的.固然也没法避免将来开发过程当中.或进入代码维护阶段是.所须要面对代码修正的问题.为了每次都能保证软件代码工做都正确无误.并且即时在需求发生变动须要添加新功能时.也能保证原有功能正常运行.使用可控的测试导向的开发模式是必行的.
固然做为开发人员要在开发过程手工编写大量的测试用例并维护笨重测试的代码.这会在必定程度上致使项目开发进度延缓。这也是不少开发人员忽视UT一个缘由之一.但如今PEX白盒测试工具.能够把测试流程彻底的自动化.把开发人员从单元测试的需求中解脱出来专一于核心业务开发之上.
本篇并无急于在Windows phone Application 中验证PEX是否可行.可是PEX透露出来关于测试理念确实颇有深刻的价值.稍后会在下篇副中不管成功仍是失败.演示Windows phone应用程序中使用PEX整个过程.
若有问题请在评论中提出.本篇全部源代码下载地址以下:/Files/chenkai/BasicConsolePexComponent_Demo.rar