您的位置: 首页 > 技术文档 > 网络编程 > 单元测试和事先测试开发
如何定时运行ASP文件 回到列表 vbscript 错误代码对应解释大全
 单元测试和事先测试开发

作者:Eric Gunnerson 时间: 2003-05-28 文档类型:转载 来自:Microsoft

第 1 页 发现软件错误
第 2 页 事先测试开发
第 3 页 示例

下面我将编写一个 IntegerList 类来介绍事先测试开发的工作原理。IntegerListArrayList 类的变体,用于在本地存储整数,因此不存在装箱和取消装箱的开销。

第一步是创建一个控制台项目,并向其中添加一个 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]);
        }

在此测试中,我选择同时测试两个操作:

  • 列表正确维护 Count 属性。
  • 列表可以包含两个项。

某些测试驱动开发的倡议者提倡测试应尽可能只测试数目,但是如果只测试数目而不测试项目,这对于我而言有些不可思议,因此我所选择的是两者一起测试。

编译这段代码时,由于 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)

只需少许改动,列表即可在两种情况下正常运行。请查看代码样例以获取更多细节和更多测试。

出处:Microsoft
责任编辑:蓝色

上一页 事先测试开发 下一页

◎进入论坛网络编程版块参加讨论

作者文章
单元测试和事先测试开发
关键字搜索 常规搜索 推荐文档
热门搜索:CSS Fireworks 设计比赛 网页制作 web标准 用户体验 UE photoshop Dreamweaver Studio8 Flash 手绘 CG
站点最新 站点最新列表
周大福“敬•自然”设计大赛开启
国际体验设计大会7月将在京举行
中国国防科技信息中心标志征集
云计算如何让安全问题可控
云计算是多数企业唯一拥抱互联网的机会
阿里行云
云手机年终巨献,送礼标配299起
阿里巴巴CTO王坚的"云和互联网观"
1499元买真八核 云OS双蛋大促
首届COCO桌面手机主题设计大赛
栏目最新 栏目最新列表
浅谈JavaScript编程语言的编码规范
如何在illustrator中绘制台历
Ps简单绘制一个可爱的铅笔图标
数据同步算法研究
用ps作简单的作品展示页面
CSS定位机制之一:普通流
25个最佳最闪亮的Eclipse开发项目
Illustrator中制作针线缝制文字效果
Photoshop制作印刷凹凸字体
VS2010中创建自定义SQL Rule
>> 分页 首页 前页 后页 尾页 页次:3/31个记录/页 转到 页 共3个记录

蓝色理想版权申明:除部分特别声明不要转载,或者授权我站独家播发的文章外,大家可以自由转载我站点的原创文章,但原作者和来自我站的链接必须保留(非我站原创的,按照原来自一节,自行链接)。文章版权归我站和作者共有。

转载要求:转载之图片、文件,链接请不要盗链到本站,且不准打上各自站点的水印,亦不能抹去我站点水印。

特别注意:本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有,文章若有侵犯作者版权,请与我们联系,我们将立即删除修改。

您的评论
用户名:  口令:
说明:输入正确的用户名和密码才能参与评论。如果您不是本站会员,你可以注册 为本站会员。
注意:文章中的链接、内容等需要修改的错误,请用报告错误,以利文档及时修改。
不评分 1 2 3 4 5
注意:请不要在评论中含与内容无关的广告链接,违者封ID
请您注意:
·不良评论请用报告管理员,以利管理员及时删除。
·尊重网上道德,遵守中华人民共和国的各项有关法律法规
·承担一切因您的行为而直接或间接导致的民事或刑事法律责任
·本站评论管理人员有权保留或删除其管辖评论中的任意内容
·您在本站发表的作品,本站有权在网站内转载或引用
·参与本评论即表明您已经阅读并接受上述条款
推荐文档 | 打印文档 | 评论文档 | 报告错误  
专业书推荐 更多内容
网站可用性测试及优化指南
《写给大家看的色彩书1》
《跟我去香港》
众妙之门—网站UI 设计之道
《Flex 4.0 RIA开发宝典》
《赢在设计》
犀利开发—jQuery内核详解与实践
作品集 更多内容

杂⑦杂⑧ Gold NORMANA V2