动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 软件工程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ 软件工程 ]的信息

本月文章推荐
.SOA对集中数据的作用.
.微软事务处理服务介绍.
.使用UDDI的Web服务描述和发现之一.
.利用代间差分遗传算法优化分形图.
.BEA服务:让SOA实施更快捷.
.优秀软件文档的必备要素.
.移动没有标题条的窗口.
.XAML开发入门之XAML核心语法.
.XAML开发入门之附加属性和绑定属.
.软件项目管理中的风险管理研究.
.VS2005(c#)项目调试问题解决方案.
.面向对象软件开发的十大原则.
.你是我冬天的巧克力,夏天的冰淇.
.Sun 正式进入ESB市场 发布了新的.
.注册储存 SOA的核心问题.
.如何对软件质量进行评估(1).
.ADO.NET实现应用程序数据访问层.
.实现SOA的两个案例.
.需求管理详解.
.获取用户需求的十大沟通技巧.

单元测试和事先测试开发

发表日期:2008-3-23 |


摘要:Eric Gunnerson 介绍了事先测试开发的思想,并提供了一个实用实例来演示如何在您自己的应用程序中应用它。
  本专栏末尾有我的简介,假如您读过的话,就会知道我在担任程序经理之前曾出任 C# 编译器的测试组长,而在此之前是 C++ 编译器的测试组长。这些工作经历使我对分析和尽量避免软件错误非凡感爱好。   要减少软件中的错误数目,方法之一就是拥有一个专业的测试组,其工作就是尽一切可能使软件崩溃。不幸的是,假如拥有测试组,那么即使是经验丰富的开发人员,也会倾向于花费较少的时间来保证代码的可靠性。   软件界有一句俗语:“开发人员不应该测试他们自己的代码”。这是因为开发人员对自己的代码了如指掌,他们很清楚如何采用适当的方法对代码进行测试。尽管这句俗语很有道理,但却忽略了非常重要的一点 - 假如开发人员不对自己的代码进行测试,又如何知道代码能否按照预期的方式运行?   简单说来,他们根本无从得知。开发人员编写那种运行不正常或只在某些情况下运行正常的代码是一个严重的问题。他们通常只测试代码能否在很少的情况下正常运行,而不是验证代码能够在所有情况下均正常运行。   发现软件错误

  发现软件错误的情况有很多:   1、由首次编写代码的开发人员发现。
  2、由尝试运行代码的开发人员发现。
  3、由组中的其他开发人员或测试人员发现。
  4、作为产品大规模测试的一部分。
  5、由最终用户发现。

  假如在第一种情况下发现软件错误,则修复错误比较轻易,成本也很低。情况越靠后,修复软件错误的成本就越高;修复一个由最终用户发现的软件错误可能要耗费 100 或 1000 倍的成本。更不用说用户通常因为软件错误导致工作无法继续,而一直等到下一个版本才能解决问题。   假如开发人员能够在编写代码期间发现所有的软件错误,那就再好不过了。为此,您必须编写能在编写代码时运行的测试。有一种很不错的方法,它恰好可以做到这一点。   事先测试开发

  所谓的事先测试开发是指在编写代码前编写测试。假如所有测试均正常运行,便可以断定代码运行正常;添加新功能时,这些测试会继续验证您是否破坏了代码的任何部分。   此概念于 20 世纪 90 年代初诞生于 Smalltalk 世界,Kent Beck 在当时编写了 SmalltalkUnit。在过去的几年中,大部分环境都具备了单元测试工具,其中有一个很出色的适用于 .NET Framework 领域的工具,即 nUnit(英文)。   示例

  下面我将编写一个 IntegerList 类来介绍事先测试开发的工作原理。IntegerList 是 ArrayList 类的变体,用于在本地存储整数,因此不存在装箱和取消装箱的开销。   第一步是创建一个控制台项目,并向其中添加一个 IntegerList.cs 源文件。要连接 nUnit 框架,需要添加对 nUnit 框架的引用。在我的系统中,它们位于 d:\program files\nUnit v2.0\bin。   第二步是花些时间考虑如何对该类进行测试。这与确定类应该具备哪些功能的过程类似,但重点放在功能的特定用途(将值 1 添加到列表并检查是否成功),而不是功能本身(将一个项目添加到列表)。要生成此类,我们首先要提供一个要使用的测试列表:   1、测试该类可以构造
  2、将两个整数添加到列表,并确保数目和项目都正确。
  3、执行同一操作,但针对更多的项目。
  4、将此列表转换为一个字符串。
  5、使用 foreach 枚举此列表。

  此示例从某种程度上代表了我开始时的想法,即希望这个类执行的操作。多数类一次只会创建一小部分,测试应随着类的增长而添加。   现在我可以开始了。我创建一个名为 IntegerListTest.cs 的新 C# 类文件,用于存放所有测试。下面是包含第一个测试的文件: using System;
using System.Collections;
using NUnit.Framework; namespace IntegerList
{
/// <summary>
/// IntegerClassTest 的摘要说明。
/// </summary>
[TestFixture]
public class IntegerClassTest
{
[Test]
public void ListCreation()
{
IntegerList list = new IntegerList();
Assertion.AssertNotNull(list);
}
}
}   [TestFixture] 属性将此类标记为测试类,[Test] 属性将 ListCreation() 方法标记为测试方法。在此方法中,我创建了一个列表,然后使用 Assertion 类测试对象 gets 已经创建。
  我启动 nUnit GUI 测试程序,打开可执行文件,并执行这些测试。将获得如下显示。 单元测试和事先测试开发

图 1:显示测试结果的 nUnit GUI   这表明所有测试都已通过。现在我想添加一些真实功能。第一个操作就是向列表中添加一个整数。此测试如下所示: [Test]
public void TestSimpleAdd()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
Assertion.AssertEquals(2, list.Count);
Assertion.AssertEquals(5, list[0]);
Assertion.AssertEquals(10, list[1]);
}   在此测试中,我选择同时测试两个操作:   1、列表正确维护 Count 属性。
  2、列表可以包含两个项。

  某些测试驱动开发的倡议者提倡测试应尽可能只测试数目,但是假如只测试数目而不测试项目,这对于我而言有些不可思议,因此我所选择的是两者一起测试。   编译这段代码时,由于 IntegerList 类中没有方法,因此编译失败,为此我加上以下代码进行编译: public int Count
{
get
{
return -1;
}
} public void Add(int value)
{
} public int this[int index]
{
get
{
return -1;
}
}   然后我返回并运行测试,这时它们显示为红色,表示测试失败。这很好,因为它意味着测试实际上已测试出程序错误。现在我可以执行此实现。我可以做些简单的工作,尽管这样做效率不是很高: public int Count
{
get
{
return elements.Length;
}
} public void Add(int value)
{
int newIndex;
if (elements != null)
{
int[] newElements = new int[elements.Length + 1];
for (int index = 0; index < elements.Length;
index++)
{
newElements[index] = elements[index];
}
newIndex = elements.Length;
elements = newElements;
}
else
{
elements = new int[1];
newIndex = 0;
}
elements[newIndex] = value;
} public int this[int index]
{
get
{
return elements[index];
}
}   我现在已经完成类的一小部分,并已经编写了可确保其正常工作的测试,但我仅仅测试了项目中很少的一部分。接下来,我要编写一个用于检查 1000 个项的测试: [Test]
public void TestOneThousandItems()
{
list = new IntegerList(); for (int i = 0; i < 1000; i++)
{
list.Add(i);
} Assertion.AssertEquals(1000, list.Count);
for (int i = 0; i < 1000; i++)
{
Assertion.AssertEquals(i, list[i]);
}
}   此测试运行正常,因此无须进行任何更改。   添加 ToString() 方法

  接下来,我将添加测试代码,以测试 ToString() 能否正常运行: [Test]
public void TestToString()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
string t = list.ToString();
Assertion.AssertEquals("5, 10", t.ToString());
} 失败了,没关系。以下代码可以使其通过: public override string ToString()
{
string[] items = new string[elements.Length];
for (int index = 0; index < elements.Length; index++)
{
items[index] = elements[index].ToString();
}
return String.Join(", ", items);
}进入讨论组讨论。
启用 Foreach

  许多用户希望能够使用 foreach 遍历我的列表。为此,我需要在类中实现 Ienumerable,并定义一个单独的用于实现 Ienumerable 的类。第一步,测试:
[Test]
public void TestForeach()
{
IntegerList list = new IntegerList();
list.Add(5);
list.Add(10);
list.Add(15);
list.Add(20); ArrayList items = new ArrayList(); foreach (int value in list)
{
items.Add(value);
} Assertion.AssertEquals("Count", 4, items.Count);
Assertion.AssertEquals("index 0", 5, items[0]);
Assertion.AssertEquals("index 1", 10, items[1]);
Assertion.AssertEquals("index 2", 15, items[2]);
Assertion.AssertEquals("index 3", 20, items[3]);
} 我还通过 IntegerList 实现 IEnumerable: public IEnumerator GetEnumerator()
{
return null;
}   运行测试时,此代码生成异常。为了正确地实现此功能,我将使用一个嵌套类作为枚举器。 class IntegerListEnumerator: IEnumerator
{
IntegerList list;
int index = -1; public IntegerListEnumerator(IntegerList list)
{
this.list = list;
}
public bool MoveNext()
{
index++;
if (index == list.Count)
return(false);
else
return(true);
}
public object Current
{
get
{
return(list[index]);
}
}
public void Reset()
{
index = -1;
}
}   此类将一个指针传递给 IntegerList 对象,然后只返回此对象中的元素。   这样,便可以对列表执行 foreach 操作,但遗憾的是 Current 属性属于对象类型,这意味着每个值将被装箱才能将其返回。此问题可采用一种基于模式的方法加以解决,此方法酷似当前方法,但它通过 GetEnumerator() 返回一个真正的类(而非 IEnumerator),且此类中的 Current 属性为 int 类型。   然而执行此操作后,我要确保在不支持该模式的语言中仍然可以使用这种基于接口的方法。我将复制编写的上一个测试并修改 foreach 以转换为接口:   foreach (int value in (IEnumerable) list)   只需少许改动,列表即可在两种情况下正常运行。请查看代码样例以获取更多细节和更多测试。   几点说明

  为本月的专栏文章编写代码和文字大约花了我一个小时的时间。事先编写测试的优点就是您可以对在类中添加哪些内容以使测试通过有一个清楚的熟悉,从而简化代码的编写。   假如要进行小型、递增的测试,则使用此方法最合适。我鼓励您在小型项目中使用此方法。事先测试开发是所谓的“灵敏方法”的一部分。进入讨论组讨论。

上一篇:软件测试与可靠性评估方法研究 人气:319
下一篇:UML的三大“硬伤” 人气:279
浏览全部软件工程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-28 LDV个人相册系统 v1.6.1
2008-8-28 讯时网站管理系统CMS v3.5
2008-8-28 迅易评选管理系统 v9.3
2008-8-28 OpenX(广告管理系统) v2.6.1 多国
2008-8-28 雨点单用户免费留言板 v2.0 Buil
2008-8-28 APJE私服发布系统 v2.1 ASP版
2008-8-28 酷维CMS企业网站程序 v1.0
2008-8-27 风讯dotNETCMS v1.0 SP3 SQL/ACC
2008-8-27 风讯dotNETCMS v1.0 SP3 源码
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号