在 上一篇文章 中我已经解释了为什么把所有编程问题当作一群丧尸一次性处理是错误的。我也解释了 ZOMBIES 方法中的第一条:最简场景。本文中我将进一步介绍接下来的两条:单元素场景和多元素场景。
创新互联是专业的上海网站建设公司,上海接单;提供网站制作、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行上海网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
ZOMBIES 表示以下首字母缩写:
在上一篇文章中,通过应用了最简场景,你在代码里构建了一条最简可行通路。这个代码里没有任何业务处理逻辑。现在是时候向系统中添加一个元素了。
最简场景表示系统中什么也没有,这是一个空的用例,我们什么也不用关心。单元素场景代表我们有一个元素需要关心考虑。这个单一元素可能是集合中的一个元素、一个访问着或者一个需要处理的事件。
对于多元素场景,我们需要处理更复杂的情况,比如两个或更多的集合元素或事件。
在上一篇文章的代码基础上,向虚拟购物筐里添加一些商品。首先,写一个伪测试:
[Fact]
public void Add1ItemBasketHas1Item() {
var expectedNoOfItems = 1;
var actualNoOfItems = 0;
Assert.Equal(expectedNoOfItems, actualNoOfItems);
}
不出所料,这个测试失败了,因为硬编码了一个错误的值:
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.57] tests.UnitTest1.NewlyCreatedBasketHas0Items [FAIL]
X tests.UnitTest1.NewlyCreatedBasketHas0Items [4ms]
Error Message:
Assert.Equal() Failure
Expected: 0
Actual: 1
[...]
现在是时候停止伪造了。现在你已经用 ArrayList
实现了购物筐。那么应该怎么实现商品呢?
简洁性应该一直是你的指导原则。在不了解商品的太多信息的情况下,你可以先用另一个集合来实现它。这个表示商品的集合应该包含些什么呢?由于你多半会关心计算购物筐中的商品总价,所以对商品的表示至少需要包含价格(可以是任意货币,为简单起见,不妨假设是人民币)。
(我们需要)一个简单的集合类型,它包含一个商品 ID(可以在系统中的其它地方使用 ID 来指向该商品)和这个商品的价格。
键值对类型的数据结构可以很容易满足这个需求。在 C# 中最先被想到的数据结构就是 Hashtable
。
在购物应用的代码中给 IShoppingAPI
增加一个新功能:
int AddItem(Hashtable item);
这个新功能以一个用 Hashtable
表示的商品为输入,返回购物筐中的商品数量。
将测试代码中硬编码的值提替换为对接口的调用:
[Fact]
public void Add1ItemBasketHas1Item() {
var expectedNoOfItems = 1;
Hashtable item = [new][3] Hashtable();
var actualNoOfItems = shoppingAPI.AddItem(item);
Assert.Equal(expectedNoOfItems, actualNoOfItems);
}
在上面的代码中实例化了一个 Hashtable
并命名为 item
,然后调用购物接口中的 AddItem(item)
方法,该方法会返回购物筐中实际的商品数量。
转到 ShoppingAPI
类中,实现这个方法:
public int AddItem(Hashtable item) {
return 0;
}
这里再次通过写假代码来检验测试的效果(测试是业务代码的第一个调用者)。如果测试失败,将硬编码值换成实际的代码:
public int AddItem(Hashtable item) {
basket.Add(item);
return basket.Count;
}
在上面的代码中,向购物筐里添加了一件商品,然后返回购物筐中的商品数量:
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 1.0633 Seconds
到目前为止,你通过了两个测试,同时也基本里解了 ZOMBIES 方法中的最简场景和单元素场景两部分。
回顾前面所做的工作,你会发现通过将注意力集中到处理最简场景和单元素场景上,你在构建接口的同时也定义了一些业务逻辑边界!这不是很棒吗?现在你已经部分地实现了最关键的抽象逻辑,并且能够处理什么也没有和只有一个元素的的情况。因为你正在构建的是一个电子交易 API,所以你不能对顾客的购物行为预设其它限制。总而言之,虚拟购物筐应该是无限大的。
ZOMBIES 提供的逐步优化思路的另一个重要方面(虽然不是很明显)是从大概思路到具体实现的阻力。你也许已经注意到了,要具体实现某个东西总是困难重重。倒不如先用硬编码值来构造一个伪实现。只有看到接口与测试之间以一种合理的方式交互之后,你才会愿意开始完善实现代码。
即便如此,你也应该采用简单直接的代码结构,尽可能避免条件逻辑分支。
通过定义顾客向购物筐里添加两件商品时的期望来拓展应用程序。首先构造一个伪测试。它的期望值为 2,但是现在将实际值硬编码为 0,强制让测试失败:
[Fact]
public void Add2ItemsBasketHas2Items() {
var expectedNoOfItems = 2;
var actualNoOfItems = 0;
Assert.Equal(expectedNoOfItems, actualNoOfItems);
}
执行测试,前两个测试用例通过了(针对最简场景和单元素场景的测试),而硬编码的测试不出所料地失败了:
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.57] tests.UnitTest1.Add2ItemsBasketHas2Items [FAIL]
X tests.UnitTest1.Add2ItemsBasketHas2Items [2ms]
Error Message:
Assert.Equal() Failure
Expected: 2
Actual: 0
Test Run Failed.
Tatal tests: 3
Passed: 2
Failed: 1
将硬编码值替换为实际的代码调用:
[Fact]
public void Add2ItemsBasketHas2Items() {
var expectedNoOfItems = 2;
Hashtable item = [new][3] Hashtable();
shoppingAPI.AddItem(item);
var actualNoOfItems = shoppingAPI.AddItem(item);
Assert.Equal(expectedNoOfItems, actualNoOfItems);
}
在这个测试中,你向购物筐中添加了两件商品(实际上是将同一件商品添加了两次),然后比较期望的商品数量和第二次添加商品后调用 shoppingAPI
返回的商品数量是否相等。
现在所有测试都能够通过!
现在你已经了解了最简场景、单元素场景和多元素场景。我将下一篇文章中介绍边界行为和接口定义。敬请期待!
标题名称:ZOMBIES:软件开发和测试中的构建与拓展(二)
转载来源:http://www.stwzsj.com/qtweb/news24/2474.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联