【问题标题】:First TDD test with no assert/expected exception. Is it worth it?第一次没有断言/预期异常的 TDD 测试。这值得么?
【发布时间】:2010-07-31 22:18:59
【问题描述】:

假设我开始使用 TDD 制作游戏。这是一个好的第一次测试吗?

[TestMethod]
public void Can_Start_And_End_Game()
{
    Tetris tetris = new Tetris();
    tetris.Start();
    tetris.End();
}

它基本上迫使我定义 3 件事:Tetris 类及其 Start()End() 方法,但除此之外它几乎没用。它可能会立即引起人们的兴趣,因为我可以定义该类和那些方法,但稍后它可能不会用于任何目的。它的唯一目的可能是表明必须可以开始和结束游戏而不会在中间出现异常。

您对此有何看法?

【问题讨论】:

  • 在 Java 中,方法不大写。因此tetris.start()tetris.end()
  • 从技术上讲,这是一个集成测试,因为您要测试的不仅仅是一件事。您应该有 Start 测试、End 测试和这个集成测试。

标签: c# java unit-testing tdd


【解决方案1】:

它基本上迫使我定义三件事:俄罗斯方块类及其 Start() 和 End() 方法,

是的。

但除此之外它毫无用处。

错误。

以后它可能不会有任何用途

假的,也是。

它的......目的[是]表明必须可以开始和结束游戏而不会在中间出现异常

这是巨大的。史诗。不朽的。

确实,该测试会经常失败,以至于您会越来越讨厌它。来自程序中各种随机位置的每个未处理、未捕获的异常都将无法通过此测试。由于此测试,您将构建仔细的日志记录和调试。

这个测试是 EPIC。

【讨论】:

  • 哇,我没想到。
  • 我一直都知道我是一个编程天才。现在我有证据了。
  • @devoured elysium:对不起,你不是天才。你只是按照天才告诉你的去做。好消息是你在追随天才。
【解决方案2】:

你并没有真正通过这个测试来推动俄罗斯方块类的开发——你已经决定了它的 API 应该是什么,这很好,但是为什么不编写一个测试来测试它实际上应该做的事情呢?

测试应该通知 API,而不是相反(恕我直言)。

【讨论】:

  • 我认为你成功了。但也可以看看 S. Lott 的回答。
  • @devoured - 谢谢。我实际上更喜欢 S. Lott's :)
【解决方案3】:

我不是这个测试的忠实粉丝。是的,它有助于定义接口,但它对于定义(和测试)行为并不是很强大。

我认为最好有一个测试来处理启动。它可能会断言默认设置或评分值。然后我会进行额外的测试,看看你是否可以结束游戏。

最好让每个测试方法执行一个行为。

【讨论】:

  • +1。一个好的测试只有一个断言;这个没有。
【解决方案4】:

我认为通过捕获任何异常并在发生异常时明确地使测试失败,可以使测试的目的更加明确:

[TestMethod]
public void Can_Start_And_End_Game()
{
    try
    {
        Tetris tetris = new Tetris();
        tetris.Start();
        tetris.End();
    }
    catch (Exception ex)
    {
        Assert.Fail("Unexpected exception thrown: " + ex.ToString());
    }
}

【讨论】:

  • 有一个Assert.DoesNotThrow 方法可以做到这一点。
  • 说“让 x = x”或“如果 (true == true)”不是多余的吗?我认为这是 xunit 的约定,无论方法的名称如何,“DoesNotThrow”的想法总是隐含和理解的,无论有没有任何类型的断言。
【解决方案5】:

是的,测试确认在构造函数Start()Stop()方法中没有抛出异常。

我在测试中发现额外的 try/catch 块以捕获异常的价值不大。执行测试的工具将捕获并报告这些。使用 TSTTCPW 原理,测试可以在没有 try/catch 块的情况下进行。

您可以通过在末尾添加断言来使测试更有意义,例如验证 tetris 对象的属性值。

请注意编写单元测试和使用 TDD 之间的区别。价值来自于对这种差异的理解。

【讨论】:

    【解决方案6】:

    正如 S. Lott 所说,这项测试涵盖了很多方面。它是如此“值得”,值得将其分解为至少 3 个测试并为每个测试添加适当的断言:

    [TestMethod]
    public void Test_Contructor()
    {
        Tetris tetris = new Tetris();
        // make assertions
    }
    
    [TestMethod]
    public void Test_Start()
    {
        // setup
        Tetris tetris = new Tetris();
    
        // exercise
        tetris.Start();
    
        // make assertions
    }
    
    [TestMethod]
    public void Test_End()
    {
        // setup
        Tetris tetris = new Tetris();
        tetris.Start();
    
        // exercise
        tetris.End();
    
        // make assertions
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 1970-01-01
      • 2018-11-21
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 2020-08-04
      • 1970-01-01
      相关资源
      最近更新 更多