C#进行单元测试实例_第1页
C#进行单元测试实例_第2页
C#进行单元测试实例_第3页
C#进行单元测试实例_第4页
C#进行单元测试实例_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2003-2010年中国汽车市场预测1. "十五"前三年汽车市场发展概况1.1 需求快速增长,提前三年达到"十五"规划目标(1 "十五"前三年汽车总需求连续快速增长,已经提前三年达到"十五"规划目标"十五"前三年,我国汽车市场保持了连续的快速增长势头,2001年汽车市场增长14.3%,2002年更是高达38.6%,年均增长25.8%,2003年前4个月增长40.6%,远高于"九五"时期年均7.8%的增长速度。继"九五"末期,市场需求达到200万辆后,200

2、2年突破300万辆,达到337.5万辆,提前3年完成"十五"规划目标,同时超过了英国、法国、意大利的汽车市场需求,成为市场第四大汽车市场。"十五"前三年的快速增长主要缘于近年来经济持续增长,人民收入稳定提高,汽车产品的日益丰富,汽车价格的逐年下降,汽车消费成为一些主要城市的消费热点。表1-1 中国汽车市场需求增长态势(1995-2003年4月 单位:万辆年份总需求国产汽车进口汽车需求量增长速度需求量增长速度需求量增长速度1995146.4-142.4-4.05-1996151.53.5%143.91.1%7.5987.3%1997161.76.7%156

3、.78.9%4.90-35.4%1998164.31.7%160.32.3%4.02-18.0%1999186.813.7%183.214.3%3.52-12.5%2000213.114.1%208.914.0%4.2721.3%2001243.514.3%236.413.2%7.1467.2%2002337.538.6%324.837.4%12.7478.5%2003-14142.140.6%136.038.4%6.1114.2%资料来源:汽车市场年鉴、汽车市场快讯图1-1 汽车市场总需求变化(1995-2002年(2入世后,进口车需求比重并未显著上升进口车在经历80年代中后期和90年代初期

4、的大量进口后,随着引进车型和技术的速度加快,国产汽车快速发展,进口车市场需求在1996-1999呈现下降态势。近年来,随着中国关税的下调,进口汽车的数量保持了较高的增长速度,但总体上进口汽车的数量并不大,市场份额只有不到5%,仍为我国汽车市场需求的重要补充。表1-2 国产进口汽车市场份额变化(1995-2003年4月年份国产汽车销量(万辆市场份额(%进口汽车进口量(万辆市场份额(%1995年142.497.2%4.052.8%1996年143.995.0%7.595.0%1997年156.797.0%4.903.0%1998年160.397.6%4.022.4%1999年183.298.1%3

5、.521.9%2000年208.998.0%4.272.0%2001年236.497.1%7.142.9%2002年324.896.2%12.743.8%2003年1-4月136.095.7%6.14.3%资料来源:汽车工业年鉴、汽车市场快讯十五"前三年商用车的增长速度远高于"九五"时期的年均2.3%的增长速度,但要远远低于乘用车市场增长。主要原因在于乘用车需求的私人化特征明显,保证了乘用车市场的增长,也减少了需求的波动性;而商用车作为生产资料的用途明显,集团购买比重仍然较大,部分车型受到扩大内需、加强基础建设、交通设施改善等因素的影响保持较快的发展,但部分车型受

6、到车型内部的结构调整处于下降或平稳发展,总体上商用车的增长速度远远小于乘用车。表1-3 乘用车、商用车需求变化情况(1995-2002年 单位:万辆,%1995年1996年1997年1998年1999年2000年2001年2002年2003年1-4月需求数量乘用车55.065.175.378.990.9110.8136.0200.992.2商用车91.486.486.385.495.9102.4107.5136.749.9增长速度乘用车-18.3%15.7%4.8%15.2%21.9%22.8%47.7%60.0%商用车-5.5%-0.1%-1.0%12.2%6.7%5.0%27.1%14.8

7、%资料来源:国家信息中心资料库图1-2 乘用车、商用车需求增长对比(1996-2003年4月随着乘用车快速增长, 乘用车在市场中的地位提高。自"九五"以来,乘用车比重持续上升,在2000年首次超过50%,在2002年达到59.5%,成为汽车市场需求的主体。根据国际汽车市场发展经验,成熟汽车市场上,乘用车是汽车市场需求的主体,我国乘用车比重的提高,说明整体的结构正在逐步得到优化。表1-4 乘用车、商用车需求结构1995年1996年1997年1998年1999年2000年2001年2002年2003年1-4月需求比重乘用车37.6%43.0%46.6%48.0%48.6%52.

8、0%55.9%59.5%64.9%商用车62.4%57.0%53.4%52.0%51.4%48.0%44.1%40.5%35.1%资料来源:国家信息中心资料库图1-3 乘用车、商用车结构变化表1-5 中国乘用车市场需求变化(1995-2003年4月年份1995年1996年1997年1998年1999年2000年2001年2002年2003年1-4月市场需求量(万辆SUV8.17.15.13.73.24.66.111.25.6MPV0.10.10.10.30.21.12.16.32.7轿车32.041.448.851.558.264.281.1123.659.3微型客车14.816.421.22

9、3.429.340.946.759.824.6需求结构SUV14.7%11.0%6.8%4.7%3.5%4.1%4.5%5.6%6.1%MPV0.2%0.2%0.2%0.4%0.2%1.0%1.5%3.1%3.0%轿车58.1%63.7%64.8%65.2%64.1%58.0%59.6%61.5%64.3%微型客车26.9%25.2%28.2%29.7%32.3%36.9%34.3%29.8%26.7%增长速度SUV-12.1%-27.9%-27.3%-15.4%45.3%32.6%83.4%143.0%MPV-28.9%0.6%106.4%-32.3%491.0%84.2%202.2%186

10、.5%轿车-29.5%17.8%5.5%13.1%10.3%26.4%52.4%75.0%微型客车-10.5%29.6%10.2%25.2%39.4%14.3%28.0%19.9%资料来源:汽车工业年鉴、汽车市场快讯图1-4 乘用车各车型全面增长(3 商用车内部结构优化,重型载货汽车成为发展最快的品种商用车中,大型化、重型化发展趋势明显。重型货车受国家采取积极财政政策、加大基础建设力度等一系列宏观政策和交通道路等硬件条件改善的影响,需求比较旺盛,"十五"前两年保持71.6%的增长速度,从2000年的8.6万辆增加到2002年的25.3万辆,远高于"九五"

11、时期年均20.8%的增长速度,已经成为商用车中仅次于轻型货车的第二大类车型;大中型客车随着交通道路条件的改善,高速公路的发展,市场需求持续增长,"十五"前两年保持33.8%的发展速度,是"九五"时期15.1%的增长速度的2倍,远高于商用车整体发展速度;中型货车的份额持续下降;轻型货车始终是商用车中第一大车型,在经历了"九五"时期的调整后,又有较快的发展,轻客和微货的需求比较稳定,但市场需求有一定的波动。表1-6 中国商用车市场需求变化情况(1995-2003年4月 kn chón )马路 一( )电脑 一( )牙齿 一( )

12、骆驼 匆匆地( ) 好奇地( ) ( )田野 ( 辽阔的( ) 美妙的( ) 茂密的( 4.9%五、把下面的句子补充完整(7分)、聪明在于学习。 _ 。 2、萧萧梧叶_,江上秋风_。的任何实现之前,我们遵循 TDD 实践的规则,首先编写测试。 TDD 在 Team Test 中并不是必需的,但最好在本文的剩余部分遵循 TDD 。右键单击( ) 随意 和 C+ 测试项目。在本文中,我们选择 Visual C# ,然后单击 19.2%年份1995日子就这样一天天过去了。现在,苏珊常常忘了自己还戴着一顶帽子;而同学们呢,似乎也忘了。1、写出本文中你最想积累的一个词(语):2、这篇课文叙述了苏珊因做化

13、疗,失去了一头美丽的(      ),班上的老师得知后,以研究(      )为名,安排全班的同学戴着帽子来(     ),从而避免了尴尬,使苏珊在相互尊重的环境中愉快地生活。3、从哪些词语(一个即可)可以看出苏珊在教室门口和走进教室后的不同心情?。(友情提示:从三、四自然段找)教室门口:走进教室:4、通过这篇文章我们明白的道理是什么?请把正确答案的序号填在(    )里。     我们

14、上学都要带帽子;2003年     老师的话我们要听;     生活中要学会友善地对待别人。六、作文(25大客车0.40.60.81.80.51.9 dài s xn 3.1yáo yun3.9(5.1 ( ( ( ( cn zhunko chá zhn bèi chì bn shu zhn( ( ( ( ( 3.33.9 shèn() ji( ) huàn( )盛 假 晃 chén( ) jià( ) span hun( )

15、 zho ( ) jiào( ) zhào ( )21.118.9 ) jué( ) cáo ( )三、比一比,再组词。(8分)演练:使用 Visual Studio Team Test 进行单元测.)推( ) 坑( ) 辨(Mark MichaelisItron Corporation准( ) 抗( )后编码 (test-then-code 蜜( )四、在括号里填上适当的词语。(运行测试 13.71.0%3.9%轻型客车16.7%17.6%3、独在异乡23.8%在 IDE 中运行测试。 4、红红的枫叶像_,飘哇飘哇,邮来了_。另外,Team Test

16、包含了一套测试功能,可以同时支持开发人员和测试人员。在本文中,我们准备演练如何创建Team Test 的单元测试。我们从一个简单的示例程序集开始,然后在该程序集中生成单元测试方法存根。这样可以为 告别 道别45.2%44.3%1、在烈士追悼会上,举行了图 1. 最终的 LogonInfo 类 请注意所有的测试代码位于一个单独的项目。这是有道理的,产品代码应该尽可能少的受测试代码影响,所以我们不想在产品代码的程序集中嵌入测试代码。47.0%返回页首 开始首先,我们创建一个名为“VSTSDemo”的类库项目。默认情况下,为方案创建目录 ( 连续1、科学家们已经( )工作了两天两夜。2、这些花在二十

17、四小时内( )开放。3、在这次比赛中我国女排取得了优异成绩,希望她们能( )努力。七、按要法语写句子。(10分)1、李教师送晶晶进了医院。改成“把的解决方案资源管理器将字句_改成“被”字句:_39.3%图 2. LongonInfo 构造函数的上下文菜单的“创建测试 ” ( Create Tests. 菜单项 返回页首 18.4%中型客车52.4%创建测试”菜单项(如图 2 所示。这样会出现一个对话框,可以在不同的项目中生成单元测试(如图 3 所示)。默认情况下,项目设置的输出 (Output 30.7%分)时 间: 轻型客车第二天早上草地颜色:( -2.7%2.8%按钮,接着输入项目名 VS

18、TSDemo.Test。测试项目名称。14.2%32.7%花的形状:( )( )-1.2%目的)提供关于创建测试的说明,包括向项目增加其他测试的说明。67.7%分)九、作文。(20分)秋天的美丽的秋天来了,你观察到了什么?请你抓住某一处秋天的美景,详细描写下来。ManualTest1.mht1、把题目补充完整;一个空的单元测试类架构,用于放入另外的单元测试。-29.0% ManualTest1.mht 轻型载货车-语文三 年级(上)期中检测 试卷 项目的引用。前者是测试引擎运行单元测试需要依赖的测试框架程序集,后者是对我们需要测试的目标程序集的项目引用。默认情况下,生成的测试方法是包含以下实现

19、的占位符:-2.6%1. 生成的测试方法: ConstructorTest(, 位于 / /This is a test class for VSTTDemo.LogonInfo and is intended/to contain all VSTTDemo.LogonInfo Unit Tests/TestClass(public class LogonInfoTest/ ./ -11.9%-3.2%TestMethod(4.6%-20.4%LogonInfo target = new LogonInfo(userId, password;/ TODO: Implement code to

20、verify target1"TODO: Implement code to verify target"确切的生成代码会根据测试目标的方法类型和签名不同而有所不同。例如,向导会为私有成员函数的测试生成反射代码。在这种特别的情况下,我们需要专门用于公有构造函数测试的代码。关于Team Test ,有两个重要的特性。首先,作为测试的方法由 TestMethodAttribute 属性指定,另外,包含测试方法的类有 TestClassAttribute 属性。这些属性都可以在ji命名空间中找到。Team Test 使用反射机制在测试程序集中搜索所有由 TestClass 修饰的

21、类,然后查找由 TestMethodAttribute 修饰的方法来决定执行的内容。另外一个重要的由执行引擎而不是编译器验证的标准是,测试方法的签名必须是无参数的实例方法。因为反射搜索 TestMethodAttribute,所以测试方法可以使用任意的名字。测试方法 ConstructorTest( 首先实例化目标 LongonInfo 类,然后断言测试是非决定性的(使用Assert.Inconclusive(。当测试运行时,Assert.Inconclusive( 说明了它可能缺少正确的实现。在我们的示例中,我们更新 ConstructorTest( 方法,让它检查用户名和密码的初始化,如下

22、所示。清单 (         )  (           )  (          )     Assert.AreEqual (password, logonInfo.Password, "The Password was not correctly initialized."(请注意我们的检查使用 Asser

23、t.AreEqual (             )    zhù  míng    bài  fng       yáo  yun       zhn  què wú  wù    

24、60;( CLR 支持泛型前,这种错误在单元测试框架中非常普遍。因为 UserID 和 Password 的实例域还没有创建,我们需要回头将其添加到 LogonInfo 类中,以便VSTTDemo.Test 项目可以编译。即使我们还没有一个有效的实现,让我们开始运行测试。如果我们遵循 TDD 方法,我们就应该直到测试证明我们需要这样的代码时才去编写产品代码。我们仅在建立项目结构时违背此原则,但是一旦项目建立后,就可以容易地始终遵循 TDD 方法。返回页首 运行测试要运行项目中的所有测试,只需要运行测试项目。要实现这一点,我们需要右键单击解决方案资源管理器的VSTSDemo.Test 项目,选择

25、设置为启动项目 (Set as StartUp Project 。接着,使用菜单项调试 -> 启动 ( F5 或者调试 -> 开始执行(不调试) ( Ctrl+F5 开始运行测试。这时出现测试结果窗口,列出项目中的所有测试。因为我们的项目只包含一个测试,因此只列出了一个测试。开始的时候,测试会处于挂起的状态,但是一旦测试完成,结果将是我们意料中的失败(如图 4 所示)。图 4. 执行所有测试后的测试结果窗口 图 4 显示了测试结果 (Test Results 窗口。这个特别的屏幕快照除了默认的列外,还显示了错误信息。您可以在列头上单击右键并选择菜单项增加 / 删除列以增加或者删除列

26、。如果要查看测试的额外细节,我们可以选定测试并双击,打开“ConstructorTestResults”窗口,如图 5 所示。图 5. 详细的测试 ConstructorTest Results 窗口 另外,我们可以右键单击单个测试,然后选择打开测试 (Open Test 菜单项,进入测试代码。因为我们已经知道问题在于 LogonInfo 构造函数的实现,我们可以去那里编写初始化 UserID 和 Password 字段的代码,使用传入的参数对它们进行初始化。重新运行测试以验证测试现在可以通过。返回页首 检查异常下一步是创建 LongonInfo 类,以提供对 UserID 和 passwor

27、d 的一些验证。不幸的是,UserID和 Password 字段是公共的,这意味着它们没有提供任何封装来确保它们有效。但是在我们将其转换为属性并提供验证前,让我们编写一些测试来验证任何实现的结果都是正确的。我们首先来编写一个测试,防止空值 (null 或空字符串赋值给 UserID。预期结果是,如果空值传送给构造函数,会引发一个 ArgumentException 异常。测试代码如清单 3 所示。清单 3. 使用 ExpectedExceptionAttribute 对异常情况进行测试 TestMethodExpectedException(typeof(ArgumentException,&

28、quot;A userId of null was inappropriately allowed."public void NullUserIdInConstructor(LogonInfo logonInfo = new LogonInfo(null, "Pss0word"TestMethodExpectedException(typeof(ArgumentException,"A empty userId was inappropriately allowed."public void EmptyUserIdInConstructor(L

29、ogonInfo logonInfo = new LogonInfo("", "Pss0word"请注意对于 ArgumentException 没有 try-catch 代码块的显式测试。不过,两个测试都包含另外一个属性 ExpectedException,它接受一个类型参数,以及一个可选的错误信息,用于在没有引发异常时显示。当这个单元测试执行时,测试框架会显式地监视引发的 ArgumentException 异常,如果方法没有引发这个异常,测试将失败。运行这些测试会证明我们还没有对 UserID 做任何验证检查;因此,测试会失败,因为没有引发预期的异

30、常。有了失败的测试,现在可以回到产品代码进行更新来提供测试需要检查的功能。在这个例子中,我们将 UserID字段转换为属性,并提供验证检查(清单 4)。清单 4. 在 LogonInfo 类中验证 UserId public class LogonInfopublic LogonInfo(string userId, string passwordprivate string _UserId;public string UserIdget return _UserId; private setif (value = null | value.Trim( = string.Emptythrow

31、new ArgumentException("Parameter userId may not be null or blank."_UserId = value;/ .属性的实现使用了 C# 2.0 的功能,其中 getter 和 setter 的访问权限不一致。setter的实现标识为私有,而 getter 实现为公有。这样 UserID 就不能在 LogonInfo 类外被修改了(除非通过反射机制)。一旦增加了验证,我们可以重新运行测试来验证实现是正确的。我们运行所有的三个测试来验证 UserID 字段转换为属性的重构过程没有产生任何意外的错误。单元测试的真正价值在代

32、码修改的时候才真正有所体现。一套单元测试可以保证我们在维护和改进代码的时候没有破坏代码。返回页首 从数据库中加载测试数据对于 LogonInfo 类的下一次修改,我们将提供一个方法来改变密码。该方法接受旧密码和新密码作为参数。另外,我们会验证密码符合某种复杂性需求。确切的说,我们将保证密码符合 Windows Active Directory 的默认需求,即包含以下四种类型字符中的三种: 大写字母 小写字母 标点符号 数字另外,我们将检查密码最少包含 6 个字符,最多包含 255 个字符。和之前一样,我们在编写实现前先为密码复杂性需求编写测试。但是显然,我们需要提供一个测试值的大集合用于验证实

33、现。我们不是为每个测试用例创建一个单独的测试,也不是创建一个循环来调用一系列的测试用例,我们将创建一个数据驱动测试,它从数据库中取出所需的数据。返回页首 测试视图 (Test View 窗口首先我们定义一个名为 ChangePasswordTest( 的新测试。定义后,从菜单项测试 -> 查看和创建测试 ( Test->View and Author Tests 为测试方法打开测试视图窗口,如图 6 所示:图 6. 测试视图 ( Test view 窗口 测试视图窗口可用来运行指定的测试和浏览测试的特定属性。通过增加额外的列(右键单击列头并选择添加/删除列),我们可以排序并根据偏好

34、查看测试。有些列来自修饰测试的属性。例如,添加 OwnerAttribute 将在所有者列显示测试的所有者。其它元数据属性(如 DescriptionAttribute )TestPropertyAttribute 来为特别的测试方法增加名值对。没有对应列的属性可以在一个测试的属性窗口中显示(选择一个测试,在右键上下文菜单中单击属性)。它包含了指定数据连接字符串和用于载入测试数据的表名的属性。显然,为了指定有效值,我们需要一个数据库连接。返回页首 增加一个测试数据库从服务器资源管理器窗口,我们可以使用创建新的 SQL Server 数据库 (Create new SQL Server Data

35、base 菜单项。但是要小心这种方法,如果我们要在其它计算机上执行测试的话,我们要保证在一台服务器上创建数据库,其它可能执行测试的计算机必须能够访问该服务器 例如一台用于构建的计算机。另外一个选择是仅仅增加一个数据库文件。使用项目 -> 增加新项 (Project->Add new item. 允许向项目插入一个 SQL 数据库文件。这种方法使测试数据和测试项目保持在一起。缺点是如果数据库变得很大,我们就不想这么做,而宁可提供全局的数据源。对于本项目中的数据,我们创建一个名为 VSTSDemo.mdf 的本地项目数据库文件。为了向文件加入测试数据,我们使用菜单工具 -> 连接

36、到数据库 ( Tools->Connect to Database ,然后指定 VSTSDemo.mdf 文件。然后,从服务器资源管理器窗口我们可以使用设计器加入一个新的表 LongonInfoTest。清单 5 显示了该表的定义。清单 5. LogonInfoTestData SQL 脚本 CREATE TABLE dbo.LogonInfoTest(UserId nchar(256 NOT NULL PRIMARY KEY CLUSTERED,Password nvarchar(256 NULL,IsValid bit NOT NULLON PRIMARYGO保存表后,我们可以将其打

37、开,然后输入不同的非法密码,如下表所示。UserIdPasswordIsValidHumperdinkPw0dFalseIMontoyapsswordFalseInigo.MontoyaPssw0rdFalseWesleyPasswordFalse返回页首 将数据与测试关联一旦完成表的创建,我们需要将其与测试 InvalidPasswords( 联系起来。从测试 InvalidPasswords的属性窗口,我们填写数据连接字符串 ( Data Connection String 和数据表名 ( Data Table Name 属性。这样做将使用附加的属性 DataSourceAttribute

38、 和 DataTableNameAttribute 更新测试。最终的方法 ChangePasswordTest( 在清单 6 中显示。清单 6. 用于数据驱动测试的测试代码 enum ColumnUserId,Password,IsValidprivate TestContext testContextInstance;/ /Gets or sets the test context which provides/information about and functionality for the /current test run./public TestContext TestConte

39、xtgetreturn testContextInstance;settestContextInstance = value;TestMethodOwner("Mark Michaelis"TestProperty("TestCategory", "Developer", "Data Source=.SQLEXPRESS;AttachDbFilename=" "Integrated Security=True", "LogonInfoTest", DataAccessMeth

40、od.Sequentialpublic void ChangePasswordTest(string userId = (stringTestContext.DataRow(intColumn.UserId;string password = (stringTestContext.DataRow(intColumn.Password;bool isValid = (boolTestContext.DataRow(intColumn.IsValid;LogonInfo logonInfo = new LogonInfo(userId, "Pssw0rd"if (!isVali

41、dException exception = null;trylogonInfo.ChangePassword("Pssw0rd", password;catch (Exception tempExceptionexception = tempException;Assert.IsNotNull(exception,"The expected exception was not thrown."Assert.AreEqual ( typeof(ArgumentException, exception.GetType(,"The exceptio

42、n type was unexpected."elselogonInfo.ChangePassword("Pssw0rd", password;Assert.AreEqual (password, logonInfo.Password, "The password was not changed."清单 6 第一个需要注意的地方是增加了 DataSourceAttribute 属性,它指明了连接字符串、表名和访问顺序。在这个清单中,我们使用数据库文件名标识数据库。这样的优点是该文件和测试项目一起迁移,假设它可能会被移动到一个相对的路径。第二个注

43、意的地方是 TestContext.DataRow 调用。TestContext 是在我们运行创建测试向导时由生成器提供的属性,它在运行时由测试执行引擎自动赋值,这样我们就可以在测试中访问跟测试环境关联的数据。如图 7 所示。图 7. TestContext 关联 如图 7 所示,TestContext 提供了 TestDirectory 和 TestName 数据,以及 BeginTimer( 和EndTimer( 方法。对 ChangePasswordTest( 方法最有意义的是 DataRow 属性。因为 ChangePasswordTest( 方法由 DataSourceAttribu

44、te 修饰,该属性指定的表返回每个记录时,该方法都会被调用一次。这就使测试代码使用运行中的测试的数据,而且对插入 LongonInfoTest 表的每条记录重复执行测试。如果表包含四条记录,那么测试将会分别执行四次。使用这样的数据驱动测试方法,可以很容易的提供额外的测试数据,而不需要编写任何代码。一旦需要额外的测试用例,我们需要做的就是向 LongonInfoTest 表增加关联的数据。尽管我们可以创建两个独立的测试来使用单独的表分别测试有效和无效数据,这个特定的例子合并了这些测试来显示稍微复杂的数据测试实例。返回页首 实现和重构目标方法现在我们已经有了测试,是时候为测试编写实现了。使用 C#

45、 重构工具,我们可以右键单击 ChangePassword(方法调用,选择菜单项 GenerateMethodStub,然后对于生成的方法提供实现,一旦我们成功地运行了使用所有测试数据的测试,我们也可以开始重构代码了,LogonInfo 类的最终实现如清单 7 所示。清单 7. LogonInfo 类 using System;namespace VSTTDemopublic class LogonInfopublic LogonInfo(string userId, string passwordthis.UserId = userId;this.Password = password;pr

46、ivate string _UserId;public string UserIdget return _UserId; private setif (value = null | value.Trim( = string.Emptythrow new ArgumentException("Parameter userId may not be null or blank."_UserId = value;private string _Password;public string Passwordget return _Password; private setstrin

47、g errorMessage;if (!IsValidPassword(value, out errorMessagethrow new ArgumentException(errorMessage;_Password = value;public static bool IsValidPassword(string value, out string errorMessageconst string passwordSizeRegex = "(?=.6,255$"const string uppercaseRegex = "(?=.*A-Z"const

48、 string lowercaseRegex = "(?=.*a-z"const string punctuationRegex = "(?=.*d"const string upperlowernumericRegex = "(?=.*A-Za-z0-9"bool isValid;Regex regex = new Regex(passwordSizeRegex +"(" + punctuationRegex + uppercaseRegex + lowercaseRegex +"|" + p

49、unctuationRegex + upperlowernumericRegex + lowercaseRegex +"|" + upperlowernumericRegex + uppercaseRegex + lowercaseRegex +"|" + punctuationRegex + uppercaseRegex + upperlowernumericRegex +".*"if (value = null | value.Trim( = string.EmptyisValid = false;errorMessage = &

50、quot;Password may not be null or blank."elseif (regex.Match(value.SuccessisValid = true;errorMessage = ""elseisValid = false;errorMessage = "Password does not meet the complexity requirements."return isValid;public void ChangePassword(string oldPassword, string newPasswordif

51、 (oldPassword = PasswordPassword = newPassword;elsethrow new ArgumentException("The old password was not correct."返回页首 代码覆盖单元测试的一个关键度量是决定在单元测试运行时测试了多少代码。该度量称为代码覆盖,Team Test 包含了一个代码覆盖工具,可以详细解释被执行代码的百分率,并突出显示哪些代码被执行,那些没有被执行。该功能如图 8 所示。图 8. 突出显示代码覆盖 图 8 显示了运行所有单元测试后的代码覆盖的突出显示情况。红色突出显示说明了我们有产品

52、代码没有运行任何单元测试,这说明我们编写这些代码时未遵循 TDD 原则,即在编写实现前先提供测试。返回页首 初始化和清除测试一般来说,测试类不仅包含独立的测试方法,还包含了不同的对测试进行初始化和清除的方法。实际上,创建测试向导在创建 VSTSDemo.Test 项目时,将一些这样的方法添加到类 LongonInfoTest 中,见清单 8。清单 8. 最终的 LogonInfoTest 类 using VSTTDemo;using System;namespace VSTSDemo.Test/ /This is a test class for VSTTDemo.LogonInfo and

53、is intended/to contain all VSTTDemo.LogonInfo Unit Tests/TestClass(public class LogonInfoTestprivate TestContext testContextInstance;/ /Gets or sets the test context which provides/information about and functionality for the /current test run./public TestContext TestContextgetreturn testContextInsta

54、nce;settestContextInstance = value;/ /Initialize( is called once during test execution before/test methods in this test class are executed./TestInitialize(public void Initialize(/ TODO: Add test initialization code/ /Cleanup( is called once during test execution after/test methods in this class have executed unless/this test class' Initialize( method throws an exception./TestCleanup(public void Cleanup(/ TODO: Add test cleanup code/ .TestMethod/ .public void ChangePasswordTest( / .用于对测试进行设置和清除的方法分别由属性 TestInitializeAttribute 和 TestCle

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论