65.9K
CodeProject 正在变化。 阅读更多。
Home

使用测试驱动开发来开发阶乘应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (9投票s)

2012年1月27日

CPOL

4分钟阅读

viewsIcon

51138

downloadIcon

347

本文旨在通过测试驱动开发来开发阶乘应用程序

TDD Cycle

引言

在本文中,我们将通过一个例子来了解测试驱动开发。 该示例是阶乘计算器应用程序。 这个简单的应用程序向我们展示了如何通过测试驱动开发来开发应用程序。 我将在文章中将“测试驱动开发”写为“TDD”。

背景

当我第一次接触测试驱动开发时,我认为“这是不必要的”。 但后来,我阅读了有关它的文章,我发现 TDD 可以防止在交付项目之前出现错误和问题。 它还创建可靠的产品,显示代码覆盖率。 这些好处足以让我开始 TDD。

在本文中,我们将使用 Visual Studio 默认的单元测试框架。 但如果您不想使用默认框架,您可以在单元测试市场中有更多选择。

开始之前

在编写代码之前,您应该确定应用程序的需求。 在本文中,我们将开发一个阶乘应用程序。 因此,我们应该确定阶乘要求。 之后,我们可以确定测试方法。 如果您愿意,您可以直接开始编写测试并跳过这些步骤。 但这样做是值得的。

要求

  1. 阶乘计算小于或等于目标数字 (n) 的所有正数的乘积。
  2. 目标数字 (n) 是一个非负整数。

单元测试

  1. 零的阶乘是 1,即 0! = 1
  2. 一的阶乘是 1,即 1! = 1*0! = 1
  3. 二的阶乘是 2,即 2! = 2*1! = 2
  4. 三的阶乘是 6,即 3! = 3*2! = 6

第一步是创建一个名为 FactorialApplication 的解决方案。 并在解决方案中添加一个名为 FactorialCalculatorTests 的测试项目和一个名为 FactorialCalculator 的类库。

Solution

现在创建一个新类并编写第一个测试方法。

测试 1:零的阶乘是 1

[TestMethod]
public void ZeroFactorialIsOne()
{
    Factorial calculator = new Factorial();
}

如您所见,我创建了一个类型为 Factorialcalculator 对象,但没有名为 Factorial 的类。 您将在 Factorial 单词下看到很多红色波浪线。

让我们使用 Factorial 单词下的选项菜单创建一个类。

[TestMethod]
public void ZeroFactorialIsOne()
{
    Factorial calculator = new Factorial();
    float result = calculator.GetFactorialOf(0);

    Assert.AreEqual(1, result);
} 

是的,现在我添加了一个新的 result 变量,并将 calculator.GetFactorialOf(0) 方法的结果赋值给它。 但在 Factorial 中没有这样的方法。 并且我在 Factorial 类中创建了一个方法。

现在我们可以看看 Factorial 类。

public class Factorial
{
    public float GetFactorialOf(int p)
    {
        throw new NotImplementedException();
    }
}

现在让我们运行测试方法并查看结果。

Test Failed

测试失败,因为我们创建了方法 GetFactorialOf(int p) 但没有像上面看到的那样实现它。 现在我们应该进行最小干预以通过测试。

public class Factorial
{
    public float GetFactorialOf(int p)
    {
        return 1;
    }
}

测试方法现在可以通过了。 因为断言已经验证。

Test Passed

测试 2:一的阶乘是 1

现在,我们可以创建我们的第二个方法。 新的断言是“一的阶乘是 1”。 新的测试方法如下

[TestMethod]
public void OneFactorialIsOne()
{
    Factorial calculator = new Factorial();
    float result = calculator.GetFactorialOf(1);

    Assert.AreEqual(1, result);
}

此方法也已通过,因为 GetFactorialOf(int p) 方法仍然支持我们的断言。

测试 3:二的阶乘是 2

第三个断言是“二的阶乘是 2”。

[TestMethod]
public void TwoFactorialIsTwo()
{
    Factorial calculator = new Factorial();
    float result = calculator.GetFactorialOf(2);

    Assert.AreEqual(2, result);
}

此方法失败,如下所示

Test Failed

显示断言异常,预期值为 2,但方法返回 1。 现在我们应该对 GetFactorialOf(int p) 方法进行最小修改以通过该方法。 该修改不应影响其他测试结果。

public class Factorial
{
    public float GetFactorialOf(int p)
    {
        if (p < 2)
            return 1;

        return p;
    }
}

Test Passed

测试 4:三的阶乘是 6

[TestMethod]
public void ThreeFactorialIsSix()
{
    Factorial calculator = new Factorial();
    float result = calculator.GetFactorialOf(3);

    Assert.AreEqual(6, result);
}    

但现在这个断言失败了。

Test Failed

需要在 GetFactorialOf(int p) 方法上进行新的修改。

public float GetFactorialOf(int p)
{
    if (p < 2)
        return 1;

    return p * GetFactorialOf(p-1);
}    

Test Passed

解决方案如下。 现在我们可以在任何地方使用这个 FactorialCalculator 库。 我在一个名为 Calculator 的类库中使用了它。

Solution

class Program
{
    static void Main(string[] args)
    {
        Factorial calculator = new Factorial();

        for (int i = 0; i < 14; i++)
        {
            Console.WriteLine(calculator.GetFactorialOf(i));
        }
    }
}    

Console Application

关注点

对我来说,TDD 最令人印象深刻的方面是,最初没有代码,在测试方法开发的同时,会自动创建所需的代码。 无需计划类,无需计划变量等等。 不会实现不必要的操作。 我们只根据需要实现需求规范。 一切都在测试期间确定。

另一点是任何测试都不应影响任何其他测试。 并且方法实现不应影响测试结果。 例如,如果一个方法对于一个测试工作正常,但对于其他方法工作错误,那么这是一个不希望的结果。

产品方法的任何更改都需要运行测试。 我们在应用程序期间做到了这一点。

历史

本文向我们展示了如何创建单元测试以及单元测试的简单步骤。 我们开发了一个阶乘应用程序。 在测试方法之后,生成了主类,并且可以使用它。 如果您能看到应用程序的缺点,您可以修改这些方法。 但应用程序的任何更改都需要运行测试才能开启。

© . All rights reserved.