【问题标题】:How to write unit tests in spec form?如何以规范形式编写单元测试?
【发布时间】:2009-10-05 19:33:05
【问题描述】:

在许多情况下,我很难为类和方法想出一个好的单元测试名称。通常,我会尝试遵循以下形式:

public class TestContext
{
    [Fact]
    public void WhenThis_DoThat()
    {
    }
}

有些人会在要明确的部分上使用 Given、When 和 Then 等词。我喜欢它,因为它似乎使单元测试更清楚地表明它正在测试什么。 除了考虑 BDD 工具包之外,我还需要一些关于如何使用普通旧 xUnit 工具的建议。

我在处理这样的场景时特别困难:

当应用程序启动时,主窗体加载并且用户看到一个列表 用户可以点击的链接。

或者更好的用例场景是:

用户可以从列表中选择一个链接 链接。

我不确定,但我试图描述一种行为,即您运行应用程序并加载带有可点击链接列表的表单。并将其转化为单元测试。

什么是 Given、When 和 Then?

【问题讨论】:

  • IMO,这与单元测试无关。请称之为验收测试或功能测试,而不是单元测试。
  • @Pascal Thivent:我所有的单元测试都是用那种风格写的。

标签: unit-testing tdd coding-style bdd


【解决方案1】:

以下是我以 BDD 规范风格编写测试的方式:http://github.com/orfjackal/tdd-tetris-tutorial

需要的是在一个类中拥有多个测试装置的能力。然后可以组织测试,每个夹具都是“Given/When”部分,每个测试方法都是“Then”部分。 JUnit不支持,所以写了a simple test runner

@RunWith(NestedJUnit4.class)
public class WerewolfTest extends Assert {
    public class Given_the_moon_is_full {
        @Before public void When_you_walk_in_the_woods() {
            ...
        }
        @Test public void Then_you_can_hear_werewolves_howling() {
            ...
        }
        @Test public void Then_you_wish_you_had_a_silver_bullet() {
            ...
        }
    }
    public class Given_the_moon_is_not_full {
        @Before public void When_you_walk_in_the_woods() {
            ...
        }
        @Test public void Then_you_do_not_hear_any_werewolves() {
            ...
        }
        @Test public void Then_you_are_not_afraid() {
            ...
        }
    }
}

【讨论】:

  • 您好 Esko,您可以使用 @RunWith(Suite.class) 获得相同的行为。它更详细一点,因为您还必须添加一个 @Suite.SuiteClasses({MyClass.MySubclass, MyClass.MyOtherSubclass}) 但您不需要依赖 JUnit 以外的任何东西。一个例子是thecleancoder.blogspot.com/2010/10/craftsman-62-dark-path.html
【解决方案2】:

我引用 Dan North 的 Introducing BDD

测试方法名称应该是句子

我的第一个“啊哈!”当我发生的那一刻 被展示了一个看似简单的 名为agiledox 的实用程序,由我编写 同事克里斯·史蒂文森。它需要一个 JUnit 测试类并打印出 方法名称作为简单的句子,所以 看起来像这样的测试用例:

public class CustomerLookupTest extends TestCase { testFindsCustomerById() { ... } testFailsForDuplicateCustomers() { ... } ... }

呈现如下内容:

CustomerLookup – finds customer by id – fails for duplicate customers – ...

“测试”一词已从两者中删除 类名和方法名, 骆驼案例方法名称是 转换为常规文本。那是 它所做的一切,但它的效果是 太棒了。

开发人员发现它可以在 至少他们的一些文件 他们,所以他们开始写测试 方法是真正的句子。 更重要的是,他们发现当他们 用语言写了方法名 业务领域,生成 对企业有意义的文件 用户、分析师和测试人员。

整篇论文实际上都值得一读。热烈推荐!

【讨论】:

    【解决方案3】:

    【讨论】:

    • 那么,举个例子,你会给 OP 中作为示例给出的测试命名什么?
    • 我也喜欢 Roy 的风格——我顺便买了他的《单元测试艺术》这本书,非常好——但是像 ChrisW,你能用 Roy 的方法试试我的例子吗?
    【解决方案4】:

    在您的场景中会出现什么问题?单元测试需要测试一些东西,那么你在测试什么。

    FormHasLinks?

    加载表格? //然后检查链接

    也许如果你说你的测试而不是你做什么,你可能会发现它更容易。

    【讨论】:

    • 我在示例中测试的是应用启动时链接列表是否显示在表单上。
    【解决方案5】:

    我在输入之后命名我的测试,而不是在输出之后。我描述了正在测试的场景:我不想以测试用例的名义定义该场景中所需的输出。

    例如,以下测试文本编辑器中退格键在各种情况下的行为:

    • 空格后退格
    • 内联文本运行边缘周围的退格键
    • 段落开头的退格
    • 行尾附近的退格键
    • 段落内的退格规范化
    • 退格选择的单词和两个空格
    • 退格选择的单词和空格
    • 退格选择的单词
    • 退格选择跨越两个段落
    • 退格几个单词
    • 退格空格和所选单词
    • 退格到其他块的远边缘

    因此,您可以或多或少地看到正在测试的场景(但它也不会试图告诉您每个场景中的预期行为)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2014-02-26
      • 2012-02-03
      • 2019-01-28
      相关资源
      最近更新 更多