测试脚本示例
在我的文章突变测试是TDD的发展中 ,我暴露了迭代的力量,以确保在可测量的测试可用时提供解决方案。 在该文章中,一种迭代方法有助于确定如何实现计算给定数字平方根的代码。
我还演示了最有效的方法是找到可衡量的目标或测试,然后以最佳猜测开始迭代。 正确答案的第一个猜测很可能会按预期失败,因此需要完善失败的猜测。 必须根据可衡量的目标或测试来验证精确的猜测。 根据结果,猜测将得到验证或必须进一步完善。
在此模型中,学习如何获得解决方案的唯一方法是反复失败。 这听起来似乎违反直觉,但令人惊讶的是,它确实有效。
遵循该分析的脚步,本文探讨了在构建包含某些依赖项的解决方案时使用DevOps方法的最佳方法。 第一步是编写一个可能会失败的测试。
依赖关系的问题是您不能依赖它们
正如迈克尔·尼加德(Michael Nygard)在《 建筑学》中无休止地巧妙表达的那样,依赖问题是一个巨大的话题,最好留给另一篇文章。 在这里,您将研究依赖项往往会给项目带来的潜在陷阱,以及如何利用测试驱动的开发(TDD)来避免这些陷阱。
首先,提出现实生活中的挑战,然后看看如何使用TDD解决它。
谁把猫放出来了?
在敏捷开发环境中,通过定义所需的结果开始构建解决方案会很有帮助。 通常,在用户故事中描述所需的结果:
使用我的家庭自动化系统(HAS),
我想控制猫什么时候可以出去
因为我想让猫整夜安全。
现在您已经有了一个用户故事,您需要通过提供一些功能要求(即通过指定接受标准 )来对其进行详细说明。 从伪代码中描述的最简单的场景开始:
方案1:在夜间禁用猫陷阱门
- 鉴于时钟检测到是晚上
- 时钟通知HAS时
- 然后HAS禁用支持物联网(IoT)的猫陷阱门
分解系统
您必须先分解正在构建的系统(HAS),然后分解为依赖项,然后才能对其进行操作。 您必须做的第一件事是识别任何依赖项(如果幸运的话,您的系统没有依赖项,这会使构建起来很容易,但是可以说它不是一个非常有用的系统)。
从上面的简单场景中,您可以看到所需的业务成果(自动控制猫门)取决于检测夜间情况。 这种依赖性取决于时钟。 但是时钟无法确定是白天还是晚上。 由您来提供这种逻辑。
您正在构建的系统中的另一个依赖项是能够自动访问猫门并启用或禁用它。 这种依赖性很可能取决于具有IoT功能的猫门提供的API。
无法快速进行依赖项管理
为了满足一种依赖性,我们将构建确定当前时间是白天还是晚上的逻辑。 本着TDD的精神,我们将从一个小小的失败开始。
请参阅我以前的文章,以获取有关如何设置此练习所需的开发环境和支架的详细说明。 我们将重用相同的NET环境,并依赖xUnit.net框架。
接下来,创建一个名为HAS(用于“家庭自动化系统”)的新项目,并创建一个名为UnitTest1.cs的文件。 在此文件中,编写第一个失败的单元测试。 在此单元测试中,描述您的期望。 例如,当系统运行时,如果时间是晚上7点,则负责确定是白天还是晚上的组件将返回值“ Nighttime”。
这是描述这种期望的单元测试:
using
System
;
using
Xunit
;
namespace unittest
{
public
class UnitTest1
{
DayOrNightUtility dayOrNightUtility
=
new DayOrNightUtility
(
)
;
[ Fact
]
public
void Given7pmReturnNighttime
(
)
{
var expected
=
"Nighttime"
;
var actual
= dayOrNightUtility
.
GetDayOrNight
(
)
;
Assert
.
Equal
( expected, actual
)
;
}
}
}
至此,您可能已经熟悉了单元测试的形状和形式。 快速回顾 :在此示例中,通过给单元测试一个描述性名称Given7pmReturnNighttime来描述期望。 然后,在单元测试的主体中,创建一个名为Expected的变量,并为其分配期望值(在这种情况下,值为“ Nighttime”)。 此后,将为实际变量分配一个实际值(在组件或服务处理一天中的时间之后可用)。
Assert.Equal(预期的,实际的) 。您还可以在上面的列表中看到名为dayOrNightUtility的组件或服务。 该模块能够接收消息GetDayOrNight ,并且应该返回字符串类型的值。
同样,本着TDD的精神,尚未构建所描述的组件或服务(仅为了以后说明而仅对其进行描述)。 构建它是由所描述的期望驱动的。
在app文件夹中创建一个新文件,并将其命名为DayOrNightUtility.cs 。 将以下C#代码添加到该文件并保存:
using
System
;
namespace app
{
public
class DayOrNightUtility
{
public
string GetDayOrNight
(
)
{
string dayOrNight
=
"Undetermined"
;
return dayOrNight
;
}
}
}
现在转到命令行,将目录更改为unittests文件夹,然后运行测试:
[Xunit.net 00:00:02.33] unittest.UnitTest1.Given7pmReturnNighttime [FAIL]
Failed unittest.UnitTest1.Given7pmReturnNighttime
[...]
恭喜,您已经编写了第一个失败的单元测试。 单元测试期望DayOrNightUtility返回字符串值“ Nighttime”,但相反,它接收的是字符串值“ Undetermined”。
修复失败的单元测试
修复失败的测试的一种快速而肮脏的方法是将值“ Undetermined”替换为值“ Nighttime”并保存更改:
using
System
;
namespace app
{
public
class DayOrNightUtility
{
public
string GetDayOrNight
(
)
{
string dayOrNight
=
"Nighttime"
;
return dayOrNight
;
}
}
}
现在,当我们运行测试时,它通过了:
Starting test execution, please wait...
Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2.6470 Seconds
但是,对值进行硬编码基本上是在作弊,因此最好为DayOrNightUtility赋予一些智能。 修改GetDayOrNight方法以包括一些时间计算逻辑:
public string GetDayOrNight
(
)
{
string dayOrNight =
"Daylight" ;
DateTime
time = new DateTime
(
) ;
if
( time.Hour
<
7
)
{
dayOrNight =
"Nighttime" ;
}
return dayOrNight;
}
该方法现在从系统获取当前时间,并比较“ 小时”值以查看它是否小于7am。 如果是,则逻辑将dayOrNight字符串值从“ Daylight”转换为“ Nighttime”。 单元测试现在通过。
测试驱动解决方案的开始
现在,我们有了一个基本案例单元测试的开始,并为我们的时间依赖性提供了可行的解决方案。 还有更多的案例需要解决。
在下一篇文章中,我将演示如何在白天进行测试以及如何在整个过程中利用故障。
翻译自: https://opensource.com/article/19/9/mutation-testing-example-tdd
测试脚本示例