如何沿多个维度构建BDD单元测试?

时间:2012-05-08 21:25:49

标签: unit-testing bdd

考虑以下测试输出:

A passing tests spec illustrating my situation`

总结一下,不支持Word文档,PDF也是。所以我们立即拒绝Word文档。但是对于PDF来说,还有很多步骤需要测试,所以我们这样做。

问题是,假设我也想支持文本文件,它们的工作流程与PDF完全相同。我测试的代码基本上是这样的:

function uploadDocument(type, document) {
    if (type !== "application/pdf" && type !== "text/plain") {
        throw new UnsupportedMediaTypeError();
    }

    // do all the steps involving temp documents, hashing, ownership, etc.
}

我的问题是:如何构建我的测试?我不想将“上传PDF时”下面的整个树复制为“上传文本文件时”。

我觉得我经常遇到这个问题。正如您所看到的,我已经完成了一些重复(“删除临时文档成功”和“提交临时文档成功”下的条目是相同的。)

基本上,这是一个改变系统的多个维度并组合测试它们的问题。有人必须考虑如何构建这样的测试。

2 个答案:

答案 0 :(得分:1)

我似乎需要将其分解为2个测试(可能更多,但这是一个不同的主题)

Given A document of type <doc_type> 
Then it should have an allowed status of  <status>

Examples:
| doc_type | status  | 
| word      | fail   | 
| text      | accept | 
| pdf       | accept | 

然后你的测试会简化为

...
when uploading a valid file type
...

快乐测试, 卢埃林

答案 1 :(得分:0)

我通过以下方式了解您的示例:

  • 您可以区分受支持和不受支持的媒体类型。
  • 所有不受支持的媒体的行为都是相同的
  • 所有受支持媒体的行为都相同
  • 对于受支持的媒体,将使用内容,但仅将其用作原始字节(散列)

因此,对于不同类型的受支持媒体执行两次测试似乎没有什么价值。让我为您可能使用的不同开发过程进行解释:

可能a。如果您正在执行BDD,则选择测试来“驱动”您的实现。在为pdf实现所有功能之后,代码已经就位。您只需“驱动”一个额外的测试用例即可添加&& type !== "text/plain"分数。对于重复树中的所有其他测试,您将无需添加任何额外的代码。因此,来自重复树的测试没有“驱动”特性。

可能性b。您正在进行测试用例设计,仅使用BDD表示法来制定测试。在这种情况下,您的目标是定义一个测试套件,以查找可能的错误。您具有有关代码的白盒知识,这意味着您知道pdf和文本文件的处理相同。因此,您只需要为pdf文件和文本文件制作不同的测试用例,就可以发现其他错误。这里可能存在一些情况,例如,如果文件扩展名阻止了文件扩展名的存储,但很可能并非在所有情况下,区别都是相关的。

可能性c。最后,有一种可能类似于b的情况,但是您没有白盒知识。鉴于在您的示例测试用例内部如何进行讨论,这并不完全适合您的示例,因此,我将不对此进行详细说明。

在测试级别上进行了讨论,在设计级别上还需要提及:您的代码a)区分受支持和不受支持的媒体,并且b)处理所有受支持的媒体。它是在同一个函数中完成所有这些操作的,这甚至可能是您最初考虑重复测试的原因:由于在此大函数中,typedocument两个参数都可以访问,因此有人甚至可以使用{{1 }}中的部分,使其不那么常见。您可能考虑在单独的函数中处理不同的职责,然后分别测试这些函数:一个函数确定是否支持类型(仅使用type参数),一个函数处理受支持的文档(仅使用type参数。