在本文中,我将就Fash Builder 4 beta 2和FlexUnit下测试驱动开发(Test Driven Development,TDD)的基本知识做一些介绍。
Flash应用变得日益动态和复杂的同时,程序的维护性和扩展性也随之变差,尤其是业务需求在开发过程中经常变化的项目。这些问题存在于几乎所有类 型的开发中,无论是移动、Web还是桌面应用,对我们构成了巨大挑战。
在一个大型应用中,如果因为业务需求的变化,你需要在某处做一些修改。那么你怎么确定这些看似不大的改动不会影响应用的其他部分?如何保证这些代码 仍然安全,特别是你并非它们的作者时?
对于任何开发平台下的软件工程师而言,这个问题都不陌生。Java和ASP开发者都同样遇到这个问题的挑战。大家正逐步发现,测试驱动开发 (TDD)对于创建易于维护的应用来说,是一项十分有用的技术。
Flash从一个小型动画工具起步,经过漫长道路成长至今。现在,Adobe Flash Platfom不仅有了兼容ECMAScript规范的编程语言,而且引入了与具体编程语言无关、构建大型动态应用所必需的方法论。实际上,Adobe和 其他很多公司一样,已经发现TDD技术可以有效解决开发者在各自每天工作中遇到的很多问题。
我发现知道TDD的技术人员很多,但真正愿在实际工作中使用的人很少,因为大家对TDD并不熟悉,担心使用后反而会增加开发时间。就我的个人经验而 言,我认为只要在合适的项目中正确运用TDD,不但不会增加,而且能减少开发时间,并提升应用的可维护性。而且我发现在已经进行的项目中也可以使用 TDD,或用一些方法将TDD集成到其他各种框架。
特别要说明的是,即使存在单独的、负责常规测试的QA(Quality Assurance)部门,TDD也是适用的。TDD能帮助开发人员编写出更稳定的代码,QA就能专注于其他工作,如测试UI、创建测试用例等。
那 么究竟什么是TDD?测试驱动开发是一种软件开发技术,在这种技术中,程序员可以在进行实际编码前编写测试用例,从而清晰定义软件的功能。
当然在使用FlexUnit时,你可能经常会因为要测试已经存在的代码,而在已有代码后再编写测试用例。
极限编程* (XP)团队承担的开发项目 是动态的,需求不断变化,通常会使用在设计编码前编写测试用例这种TDD方法。当然,TDD并未涵盖开发周期全过程,而只是极限编程开发范式的一个组成部 分。在编写实际代码前准备测试用例,有利于开发团队渐进产出工作成果,而不是让用户等待很长时间后一次见到完整效果。
小步快跑,更容易应对需求的变化,你编写的代码目的更明确、能直面需求。特别要强调的是,TDD技术的关注点是最终代码的产出,而非创建一个测 试平台。它具有的测试能力,只是一个副产物。
TDD的理论基础是:你创造的任何东西,都应该能经过测试;如果无法测试,那么你就应该再次考虑是否真的应该让它出世了。
在FlexUnit 4中应用TDD技术
图1 . 测试驱动开发周期
TDD过程由六个简单步骤组成(如图1):
- 添加测试用例 — 第一步是理解业务需求,考虑到所有可能的场景,并在这些场景基础上编写测试用例。如果需求不够清晰,就能马上发现问题,而不是整个软件完成后,才发现有问 题需要修改。
- 编写单元测试用例 — 本阶段确保测试单元自身能正确工作。它要执行的测试现在当然不能通过,因为你还没有写任何业务代码。
- 编写代码 - 在这个阶段,你可以用最简单、最高效的方法编写代码,目的是保证通过测试。此时没有必要引入任何设计模式、兼顾应用的其他部分,或整理这些代码。你的唯一 目标,就是通过测试。
- 执行测试并通过 - 一旦编写完成所有代码并通过测试,那么你就知道程序已满足所有业务需求,可以将此刻的成功与用户或团队成员分享了。
- 重 构 - 测试已经通过,你能确定程序可满足业务要求,那么现在就是为代码产品化做准备的时候了——具体包括替换临时参数、引入设计模式、删除重复代码、创建类等 等。理想情况下,一旦重构阶段完成,代码将进入代码复审,以保证代码的质量、符合公司代码标准。经过重构和代码复审,应该重新运行测试用例,保证重构过程 没引入新的破坏。
- 循环 - 一个单元测试完成后,你可将已经测试的代码和用户或团队其他成员分享,并进入下一个测试单元了。
利用FlexUnit测试Flex和ActionScript项目
FlexUnit* 是 适用于Flex和ActionScript 3.0应用程序、库的一个单元测试框架。它的功能与JUnit(一个Java单元测试框架)类似。FlexUnit已经在Adobe很多内部项目中使用, 本身也是开源的。
Flash Builder 4 beta 2集成了FlexUnit,可以为你自动创建测试单元的框架,帮你节省时间,避免多次手工创建同样的类,确保测试过程按最佳实践的要求进行。
FlexUnit目前有两个版本:FlexUnit 0.9(又名FlexUnit 1)和FlexUnit 4 beta 2.0(名FlexUnit 4)。本文使用FlexUnit 4 beta 2.0。
若要在以前版本的Flex Builder中使用FlexUnit,你需手工下载FlexUnit SWC文件,并包含到你的工程中。如下SWC文件应添加到工程的“Referenced Libraries”中:
- flexunit_0.9.swc
- Hamcrest.swc
- FlexUnit4_1.0.swc
- flexunitextended.swc
- FlexUnitTestRunner_rb.swc
这些SWC文件包含FlexUnit 0.9、FlexUnit 4、TestRunner以及其他库的提供全部API。Flex 4 SDK已经集成了这些SWC,因此在Flex 4中无需人工下载并配置FlexUnit;只要新增测试用例,这些文件就会被自动添加到工程中。
创 建测试套件类
为演示Flash Builder中FlexUnit的用法,我们将创建一个非常简单的应用:数值计算器。请按照如下步骤创建该应用,并添加测试套件:
- 选择菜单File > New > Flex Project创建工程。
- 在工程名处填入CalculatorApplication 。
- 点击“Finish”按钮。
-
选择菜单File > New > Test Suite Class创建测试套件(如图2)。
图2. 在Flash Builder 4中创建一个新的测试套件类
- 在新测试套件类对话框中,将类命名为CalculatorTestSuite 。
- 选择“New FlexUnit 4 Test”(如图3)。
- 点击“Finish”按钮。
图3. 创建一个名为CalculatorTestSuite的新测试套件类
测试套件是多个测试用例的集合。在开发过程中,你可以创建多个测试用例并一一添加到测试套件中。用例添加到套件后,就可以在任何时候运行测试套 件(比如每次修改代码后),保证代码的正确性。
注意: 尽管在极限编程中,在实际编码前编写测试用例(这是一种理想状态)最被推崇,但在实际工作中,很多时候你在编码后才能编写测试用例。类似这样的做法需要根 据实际情况具体分析,依据你的工作流程调整方法论,是没有问题的。
Flash Builder 4在flexUnitTests目录下增加了如下类:
package flexUnitTests
{
[Suite ]
[RunWith ("org.flexunit.runners.Suite" )]
public class CalculatorTestSuite
{
}
}
Suite
元数据标签标明该类是一个测试套件。RunWith
标签指示 TestRunner使用指定类执行后面的测试。FlexUnit 4可看做多种Runner的集合。你可以自定义Runner,实现特定接口。比如特别指定一个类(而非FlexUnit 4中的内建的缺省Runner)执行测试。
添加测试用例类
接下来,你应该创建测试用例了。测试用例包含的是你用于验证业务需求的条件断言。在FlexUnit 4中,每个测试用例都必须是一个独立的类。你可按照如下步骤创建前面提到过的计算器类:
- 选择菜单File > New > Package。
- 在名称处输入com.elad.calculator.utils 。
- 点击“Finish”按钮。
- 在包浏览器(Package Explorer)中选择“new com.elad.calculator.utils package”。
- 选择菜单File > New > ActionScript Class。
- 在名称处键入CalculatorLogicHelper 。
- 点击“Finish”按钮。
这个类负责计算器的内部逻辑。你要测试的第一个方法是additionMethod
,它负责数值加法。依照TDD最佳实 践原则,你应该在编写你要测试的类的实际代码前,创建测试用例。因此,我们创建方法additionMethod
后,暂时保持 它的实现体为空。在创建测试用例之后,你就可以测试这个方法了。
该类的内容如下:
package com.elad.calculator.utils
{
public class CalculatorLogicHelper
{
public function CalculatorLogicHelper()
{
}
public function additionMethod():void
{
}
}
}
现在,你已经有了你要测试的类,可以创建测试用例类了:
- 选择菜单File > New > Test Case Class。
- 择“New FlexUnit 4 Test”。
- 在包名处键入flexUnitTests 。
- 在用例类名 处键入CalculatorLogicTester 。
- 在被测试类的名称处输入com.elad.calculator.utils.Calculator (如 图4)。
-
点击“Next”。
图4. 创建一个新的测试用例类
注意: 在FlexUnit 1中可选择是否生成setUp()和tearDown()这两个桩函数。它们会在测试用例开始(
setUp()
)和结束(tearDown()
) 时自动调用,因此开发者可在测试启动前初始化数据和事件、测试结束前清除数据和事件,避免内存泄露。而在FlexUnit 4中,将用元数据标签[Before]
和[After]
定 义这些方法,具体请参看本文后面内容。在下一个对话框(如图5)中,你可以选择要测试的方法。
- 选择方法
additionMethod
。 -
点击“Finish”按钮。
图5. 选择要测试的方法
编写单元测试用例
现在可以开始编写测试代码了。打开CalculatorLogicTester.as , 我们注意到additionMethod
的测试方法已经创建好。在FlexUnit 1中,你创建的每个方法都以“test”开头,以保证TestRunner能够识别。因此,这个方法的名字应该是testAdditionMethod
。 在FlexUnit 4中,方法名不再需要以“test”开头,而用元数据标签[test]
标识,因此你可以自由重构方法名。 如下是生成的代码:
package flexUnitTests
{
import com.elad.calculator.utils.CalculatorLogicHelper;
import flexunit.framework.Assert;
public class CalculatorLogicTester
{
// Reference declaration for class to test
private var classToTestRef :
com.elad.calculator.utils.CalculatorLogicHelper;
public function CalculatorLogicTester()
{
}
[Test ]
public function testAdditionMethod():void
{
// Add your test logic here
Assert.fail("Test method Not yet implemented" );
}
}
}
最后,请记得将你要测试的这个用例添加到CalculatorTestSuite.as 套 件中去:
package flexUnitTests
{
[Suite ]
[RunWith ("org.flexunit.runners.Suite" )]
public class CalculatorTestSuite
{
public var calculatorLogic:CalculatorLogicTester;
}
}
编译并运行工程,具体请参考如下步骤:
-
点击编译图标,选择FlexUnit Tests(如图6),或选择菜单Run > Run > FlexUnit Tests。
图6. 运行FlexUnit测试程序
- 在“Run FlexUnit Tests”对话框中,选择全部测试套件和用例(见图7)。只选Suite不要选所有用例,如果在前面 已经“把要测试的这个用例添加到CalculatorTestSuite.as套件中去”,否则会运行两次
-
点击“OK”按钮。
图7. 选择所有测试用例和套件
-
当应用运行完毕后,检查浏览器中的测试状态(如图8)。
图8. 浏览器中的FlexUnit测试结果
- 关闭浏览窗口。
- 在FlexUnitResults视图中检查测试结果(如图9)。
正如你所看到的,因为你在CalculatorLogicTester.as中包含如下代码,测试返回失 败:
Assert.fail("Test method Not yet implemented");
图9. FlexUnit Results视图
编辑additionMethod(),让它返回0,因为我们还没写任何代码。并分别用static、final修饰 additionMethod方法及其类,如下所示:
package com.elad.calculator.utils
{
public final class CalculatorLogicHelper
{
public static function additionMethod(value1:Number, value2:Number):Number
{
return 0;
}
}
}
同时更新testAdditionMethod:
var result:Number = CalculatorLogicHelper.additionMethod(5,5);
Assert.assertEquals(result,10);
assertEquals 仍将失败,因为方法additionMethod现在总是返回0。运行程序,你会看到结果为测试失败(见图10),并有一条消息标明错误原因 (Error: expected: <10> but was <0>)和测试失败的方法(testAdditionMethod)。
图10. 测试失败的FlexUnit Results视图
深入了解
在应用的目录结构下,你能发现CalculatorLogicTester.as、CalculatorTestSuite.as 和FlexUnitCompilerApplication.mxml这 三个文件(如图11):
图11. CalculatorApplication目录结构
FlexUnitApplication.mxml的内容如下:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009 "
xmlns:s="library://ns.adobe.com/flex/spark "
xmlns:mx="library://ns.adobe.com/flex/halo "
minWidth="1024 " minHeight="768 "
xmlns:flexunit="flexunit.flexui.* "
creationComplete="onCreationComplete()" >
<fx:Script>
<![CDATA[
import org.flexunit.runner.Request;
import flexUnitTests.CalculatorTestSuite;
import flexUnitTests.CalculatorLogicTester;
public function currentRunTestSuite():Array
{
var testsToRun:Array = new Array();
testsToRun.push(flexUnitTests.CalculatorTestSuite);
testsToRun.push(flexUnitTests.CalculatorLogicTester);
return testsToRun;
}
private function onCreationComplete():void
{
testRunner.runWithFlexUnit4Runner(currentRunTestSuite(), "CalculatorApplication" );
}
]]>
</fx:Script>
<flexunit:FlexUnitTestRunnerUI id="testRunner "/> </s:Application>
你应该注意到了FlexUnitTestRunnerUI这个GUI,它和FlexUnit 0.9(即上一代FlexUnit1 ) 中的FlexUnit TestRunner类功能相似。此应用会将整个测试添加到这个UI中,并在其中运行测试。
在FlexUnitApplication.mxml中,你能看到FlexUnit使用FlexUnit 4 Runner:
private function onCreationComplete():void
{
testRunner.runWithFlexUnit4Runner(currentRunTestSuite(), "CalculatorApplication");
}
不过,这个框架是非常灵活的,开发者在使用相同UI的前提下创建并使用自己的Runner。目前有FlexUnit 1、FlexUnit 4、Fluint和SLT等多个版本的Runner。FlexUnit中的TestRunner是一个UI组件,它负责创建测试套件的实例,并运行全部测 试用例。测试完成后,TestRunner会在浏览器中显示结果信息。
注意: 目前Flex应用下TestRunner还不支持纯ActionScript应用。不过,你可以自己创建Flex工程,用来测试纯 ActionScript代码或执行Ant任务。具体请参看 http://opensource.adobe.com/wiki/display/flexunit/CI+ReadMe* (ANT!)
除了你在工程导航器(Project Navigator)中可直接看到的外,还有很多其他文件:
- _FlexUnitApplication_FlexInit-generated.as
- _FlexUnitApplication_mx_managers_SystemManager-generated.as
- _FlexUnitApplication-binding-generated.as
- _FlexUnitCompilerApplication_FlexInit-generated.as
- _FlexUnitCompilerApplication_mx_managers_SystemManager-generated.as
- FlexUnitApplication-generated.as
- FlexUnitApplication-interface.as
- FlexUnitCompilerApplication-generated.astem
- FlexUnitCompilerApplication-interface.as
- FlexUnitTestRunner_properties.as
这些类负责处理FlexUnit中的绑定、样式和定义等任务。
注意: bin-debug/generated包包含了MXMLC编译器创建的所有文件,正常情况下是不可见的。为了使其可见,你需选中工程,然后右键选择 “Properties”,在“Additional Compiler Arguments” 中的“Flex Compiler”下添加选项:-keep-generated-actionscript 或 -keep-generated-actionscript=true。
编写代码
因为没有编写实际业务代码,前面进行的测试都是失败的。现在你可以真正编码了。这时候编写代码应该尽可能少——只要能通过测试。编辑方法 additionMethod(),返回两个数值的和:
package com.elad.calculator.utils
{
public final class CalculatorLogicHelper
{
public static function additionMethod(value1:Number, value2:Number):Number
{
var retVal:Number = value1+value2;
return retVal;
}
}
}
测试通过
现在,不需对方法testAdditionMethod做任何修改就可以通过测试了。如果你看到结果视图是绿色高亮的,则说明测试成功(见图 12)。
图12. 测试成功的FlexUnit Results视图
重构代码
现在,测试已经通过,你可以重构代码了,为产品化做好准备。例如,你可以用某种设计模式替换if..else
语句块。在 这个例子中,我们不需要任何重构,因为它实在是太简单了。
重复上述步骤,完成剩下工作
你可以继续为减、乘和除等编写单元测试方法,最终完成的全部代码如下:
package com.elad.calculator.utils
{
public final class CalculatorLogicHelper
{
public static function additionMethod(value1:Number,
value2:Number):Number
{
var retVal:Number = value1+value2;
return retVal;
}
public static function subtractionMethod(value1:Number,
value2:Number):Number
{
var retVal:Number = value1-value2;
return retVal;
}
public static function multiplicationMethod(value1:Number,
value2:Number):Number
{
var retVal:Number = value1*value2;
return retVal;
}
public static function divisionMethod(value1:Number,
value2:Number):Number
{
var retVal:Number = value1/value2;
return retVal;
}
}
}
本文的示例文件包中的CalculatorLogicTester.as 文件包含单元测试 类的全部代码。
断言方法
到目前为止,我们仅在测试用例中使用了assertEquals
这一个断言方法。其实除此之外,还有很 多其他断言方法(见表1)。
Assertion method | Meanings |
---|---|
assertEquals | Asserts that two values are equal. |
assertContained | Asserts that the first string is contained in the second one. |
assertNotContained | Asserts that the first string is not contained in the second one. |
assertFalse | Asserts that a condition is false. |
assertTrue | Asserts that a condition is true. |
assertMatch | Asserts that a string matches a regular expression_r(regexp). |
assertNoMatch | Asserts that a string doesn't match a regexp. |
assertNull | Asserts that an object is null. |
assertNotNull | Asserts that an object is not null. |
assertNotUndefined | Asserts that an object is defined. |
assertUndefined | Asserts that an object is undefined. |
assertStrictlyEquals | Asserts that two objects are strictly identical. |
assertObjectEquals | Asserts that two objects are equal. |
表1. FlexUnit 1和4中支持的断言方法
断言方法要求三个参数:一个包括字符串信息,另两个参数参与比较。字符串参数包含了测试失败时的描述信息。例如:
assertEquals("Error testing the application state", state, 1);
如果不传入该消息参数,FlexUnit将使用缺省信息。
在编辑器中键入Assert. 你可以通过代码提示功能看到可以使用的全部断言方法。
Hamcrest断言方法
除了标准断言之外,FlexUnit 4还支持新的断言方法,为此要感谢建立在matcher 基础上的Hamcrest library* 。在每个matcher中,都可以为你的断言设置匹配条件。
如下是取自Drew Bourne的工程的一个例子,它用于测试两个数据的接近程度 (可自行指定程度级别):
package org.hamcrest.number
{
import org.hamcrest.AbstractMatcherTestCase;
public class CloseToTest extends AbstractMatcherTestCase
{
[Test]
public function comparesValuesWithinThreshold():void
{
assertMatches("close enough", closeTo(1, 0.5), 1.5);
assertDoesNotMatch("too far", closeTo(1, 0.5), 1.6);
}
[Test]
public function hasAReadableDescription():void
{
assertDescription("a Number within <0.1> of <3>", closeTo(3, 0.1));
}
}
}
整理
现在,你已有了一个可以完成计算器全部基本操作的类,以及测试这些操作的用例,因此你已经可以实现一个简单的计算器应用程序了(见图13)。
请注意CalculatorApplication.mxmll中的示例代码,它使用了utility类。
FlexUnit 4框架大量依赖元数据,例如你在前面看到过的[Suite]、[Test]和[RunWith]。如下是其他一些常见的元数据标签:
- [Ignore]——方法被忽略。可以用这个标签代替注释功能。
- [Before]——替代FlexUnit 1中的setUp(),并支持多个方法。
- [After]——替代FlexUnit 1中的tearDown(),并支持多个方法。
- [BeforeClass] ——支持执行测试类前的方法。
- [AfterClass]——支持执行测试类后的方法。
在测试用例中使用元数据标签
前面的计算器例子设计得非常简单,这样可让我们专注于理解TDD的用法。在这部分内容,我们将介绍一些在更复杂的应用中使用的FlexUnit 元数据标签。
为此,我们创建一个新的FlexUnit 4测试用例类,并命名为FlexUnitTester。并将FlexUnitTester.as 例子文件中的代码复制到这个类中。
紧跟Before元数据的方法将在每次测试之前执行,而After标签之后的方法则在测试之后执行:
[Before]
public function runBeforeEveryTest():void
{
// implement
}
[After]
public function runAfterEveryTest():void
{
// implement
}
如下代码演示了Test元数据的用途。rangeCheck方法创建一个新的Sprite对象。因为索引为1的child对象并不 存在,因此如下代码将引起一个运行时异常,成功完成测试。
[Test(expected="RangeError")]
public function rangeCheck():void
{
var child:Sprite = new Sprite();
child.getChildAt(1);
}
如下例子用于测试预先指定的断言错误。testAssertNullNotEqualsNull方法希望生成一个 AssertionFailedError错误。这个测试将失败,因为assertEquals方法返回成功(null等于null)。
[Test(expected="flexunit.framework.AssertionFailedError")]
public function testAssertNullNotEqualsNull():void
{
Assert.assertEquals( null, null );
}
在FlexUnit 1中,为避免测试你不想再测试的方法,必须将相应代码注释掉。而在FlexUnit 4中 ,使用Ignore元数据标签可直接跳过这些方法。
[Ignore("Not Ready to Run")]
[Test]
public function methodNotReadyToTest():void
{
Assert.assertFalse( true );
}
如果你想执行Test、Before或After的顺序,还可以像下面这样为order属性指定值:
[Test(order=1)]
public function checkMethod():void
{
Assert.assertTrue( true );
}
异步测试
如果你以前用过FlexUnit 1,就知道执行异步测试和测试事件驱动型的代码并不总是那么容易。我就常常发现为了适应FlexUnit或创建某些测试,不得不修改已经写好的代码,越改 越乱。Fluint的最大好处之一,就是它适应多种异步事件的能力。FlexUnit 4集成了Fluint的功能,加强了对异步测试(包括异步启动和停止)的支持。每个测试桩(test stub)都能使用这项特性。为了实际了解这一特性,我们创建一个新的测试用例类,命名为AsynchronousTester,并将 AsynchronousTester.as 文件中的代码复制进去。
这个例子测试对一个服务的调用。testServiceRequest()函数通过调用服务获得一个XML文件(该文件已包含在工程中)。测试设定 了超时时间。如果ResultEvent在超时之前触发,则表明测试成功。第二个测试函数(testFailedServiceRequest())则向 服务请求一个原本就不存在的文件。和预想的一样,因为它测试的是出现故障事件,这个测试可以通过。
最后一个测试用于多个异步调用同时存在的场景。
假设
FlexUnit 4还引入了假设(theory )的概念。所谓假设,顾名思义,可用于检查你对测试行为的猜测。这种类型的测试,对 于你需要测试返回大、甚至无限大数据的方法非常有用。 利用这项功能,你可以检查返回值是否落在指定范围。
为了具体了解其工作过程,我们创建一个名为FlexUnit4TheorySuite的新测试套件类,并将 FlexUnit4TheorySuite.as中 的代码复制进去。代码如下:
[Theory]
public function testNumber( number:Number ):void
{
assumeThat( number, greaterThan( 0 ) );
assertThat( number, instanceOf(Number) );
}
上述代码检查变量number的值是否大于0,并检查其类型。
测试UI
如果TDD应用中包含UI,测试会有点麻烦。不过FlexUnit 4中已经为你测试UI和MXML组件提供了支持。
FlexUnit 4引入了序列(sequences )的概念,序列可以包含所有你将施加在UI上的操作。
FlexUnit4CheckUITester.as 包含这个这个功能的例子。
testButtonClick方法是执行一个简单的异步测试,它设置一个鼠标事件处理函数并派发一个鼠标事件。事件处理函数UIImpersonator.addChild()
仅 检查事件字符串类型。
第二个测试(testButtonClickSequence
),它包含一个用于设置按钮标签名称的序 列。接下来,SequenceWaiter指示该序列在按钮点击事件被派发前等待。事件被派遣前,代码会调用方法 addAssertHandler( handleButtonClickSqEvent, passThroughData )
。
handleButtonClickSqEvent
方法负责处理事件,并将按钮的标签名与传入的参数比 较。
总结
本文介绍了Flash Builder 4和FlexUnit下进行单元测试和测试驱动开发的相关内容,包括FlexUnit 4框架的一些新特性。近年来,因为可让应用更易于扩展、维护,更少出现错误,TDD(以及一般意义上的单元测试)引起了越来越多人的关注。
在学会了如何创建FlexUnit测试套件和测试用例之后,我希望你能在自己的移动、Web或桌面等Flash应用中使用TDD技术,编写出更好、 更容易扩展、更可重用的代码来。
若想深入了解TDD和FlexUnit的相关内容,请阅读AdvancED Flash on Devices: Mobile Development with Flash Lite and Flash 10* 的 第14章和AdvancED Flex 4* 的第2章。关于FlexUnit和CI(Continuous Integration)服务器的集成 ,请参阅FlexUnit4AntTasks* 。
用ANT来实现自动构建自动化并且运行单元测试:
1. 参考:http://docs.flexunit.org/index.php?title=AntTasks
2. 下载最新的FlexUnit框架:http://opensource.adobe.com/wiki/display/flexunit /Downloads,它带着6个lib文件:flexunit.swc,flexunit-aircilistener.swc,flexunit- cilistener.swc,flexunit-flexcoverlistener.swc,flexunit- uilistener.swc,flexUnitTask.jar。把这些加到Flex工程的libs文件夹下
3. 关键的一点:在主MXML路径下加一个“MXML Application”类型的新文件,通常命名为***TestRunner.mxml,文件内容与老版本的相同:
4. ANT主文件build.xml中用<flexunit>标签可以run unittest(也与老版本的相同)