6

我是单元测试的新手,并且已经多次阅读我们应该先编写单元测试然后再编写实际代码。截至目前,我正在编写我的方法,然后对代码进行单元测试。

如果您先编写测试...

您倾向于编写代码以适应测试。这鼓励了“解决问题的最简单的事情”类型的开发,并使您专注于解决问题而不是解决元问题。

如果你先写代码...

您会很想编写适合代码的测试。实际上,这相当于编写问题以适合您的答案,这是一种倒退,并且通常会导致价值较小的测试。

听起来不错。但是,即使在我的代码到位之前,我如何编写单元测试?我是按字面意思接受建议吗?这是否意味着我应该准备好我的 POCO 类和接口,然后编写单元测试?

谁能用一个简单的例子来解释我是如何做到这一点的,比如两个数字相加?

4

4 回答 4

7

真的很简单。红色,绿色,重构。

红色意味着 - 你的代码完全被破坏了。语法高亮显示为红色,测试未通过。为什么?你还没有写任何代码。

绿色意味着 - 您的应用程序构建并且测试通过。您已添加所需的代码。

重构意味着 - 清理它并确保测试通过。

您可以先编写一个类似这样的测试:

[TestMethod]
public void Can_Create_MathClass() {
    var math = new MathClass();
    Assert.IsNotNull(math);
}

这将失败(红色)。你如何解决它?创建类。

public class MathClass {
}

就是这样。它现在通过(绿色)。下一个测试:

[TestMethod]
public void Can_Add_Two_Numbers() {
    var math = new MathClass();
    var result = math.Add(1, 2);
    Assert.AreEqual(3, result);
}

这也失败了(红色)。创建Add方法:

public class MathClass {
    public int Add(int a, int b) {
        return a + b;
    }
}

运行测试。这将通过(绿色)。

重构是清理代码的问题。这也意味着您可以删除多余的测试。我们知道我们MathClass现在拥有.. 所以您可以完全删除Can_Create_MathClass测试。一旦完成......你已经通过了REFACTOR,并且可以继续。

重要的是要记住重构步骤不仅仅意味着您的普通代码。这也意味着测试。你不能让你的测试随着时间的推移而恶化。您必须将它们包含在重构步骤中。

于 2013-09-25T11:50:31.820 回答
2

当您首先在代码之前创建测试时,您会发现创建代码更加容易和快捷。创建单元测试并创建一些代码以使其通过所花费的总时间与直接编写代码所花费的时间大致相同。但是,如果您已经拥有单元测试,则不需要在代码之后创建它们,从而节省您现在和以后的很多时间。

创建单元测试有助于开发人员真正考虑需要做什么。需求通过测试牢固地确定下来。不能误解以可执行代码形式编写的规范。

您将创建的代码简单明了,只实现您想要的功能。其他开发人员可以通过浏览测试了解如何使用此新代码。结果未定义的输入将在测试套件中明显缺失

系统设计也有好处。对某些软件系统进行单元测试通常非常困难。这些系统通常首先构建代码,然后进行测试,通常完全由不同的团队完成。通过首先创建测试,您的设计将受到测试对客户有价值的一切的渴望的影响。您的设计将通过更容易测试来反映这一点。

于 2013-09-25T11:48:07.683 回答
1

让我们举一个稍微高级一点的例子:你想写一个从序列中返回最大数的方法。

首先,为要测试的方法编写一个或多个单元测试:

int[] testSeq1 = {1, 4, 8, 120, 34, 56, -1, 3, -13};

Assert.That(MaxOf(testSeq1) == 120);

并重复一些更多的序列。还包括一个空参数、一个包含一个元素的序列和一个空序列,并决定一个空序列或空参数是否应该引发异常(如果是这种情况,请确保单元测试期望空序列出现异常)。

在此过程中,您需要确定方法的名称及其参数的类型。

此时,它不会编译。

然后为该方法编写一个存根:

public int MaxOf(IEnumerable<int> sequence)
{
    return 0;
}

此时它可以编译,但单元测试失败。

然后实施MaxOf(),以便这些单元测试现在通过。

这样做可以确保您立即关注该方法的可用性,因为您尝试做的第一件事就是使用它 - 甚至在开始编写它之前。此时您可能会决定根据使用模式稍微更改方法的声明。

一个真实世界的示例会将这种方法应用于使用整个类,而不仅仅是一个方法。为简洁起见,我省略了上面示例中的类。

于 2013-09-25T11:50:37.273 回答
0

可以在编写任何代码之前编写单元测试 - Visual Studio 确实具有从您在单元测试中编写的代码生成方法存根的功能。这样做也可以帮助理解对象需要支持的方法 - 有时这可以帮助以后的增强(如果你有一个保存到磁盘,你也重载保存到Stream,这更可测试并有助于假脱机网络(如果以后需要)

于 2013-09-25T11:51:01.620 回答