如果必要的单元测试失败,我可以使单元测试不确定吗? [英] Can I make a unit test inconclusive if a requisite unit test fails?

查看:27
本文介绍了如果必要的单元测试失败,我可以使单元测试不确定吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑对字典对象进行单元测试.您可能编写的第一个单元测试是一些简单地将项目添加到字典并检查异常的单元测试.下一个测试可能类似于测试计数是否准确,或者字典返回正确的键或值列表.

然而,后面的每一种情况都要求字典首先能够可靠地添加项目.如果添加项目的测试失败,我们不知道我们后面的测试失败是因为他们测试的内容执行不正确,还是因为我们可以可靠地添加项目的假设不正确.

我是否可以声明一组单元测试,如果它们中的任何一个失败,它们会导致给定的单元测试是不确定的?如果没有,我应该如何最好地解决这个问题?我是否设置了错误的单元测试,以至于我遇到了这种困境?

解决方案

这并不像看起来那么难.让我们重新表述一下这个问题:

<块引用>

如果我测试我的一段需要 System.Collections.Generic.List.Add 才能工作的代码,当有一天微软决定打破 .Add 时我该怎么办List 上?我是否会根据此进行测试以得出结论?

以上答案显而易见;你没有.你让它们失败的原因很简单——你的假设已经失败,并且测试应该失败.这里也是一样.一旦您的添加测试开始工作,从那时起您假设添加工作.您不应该以与第 3 方测试代码不同的方式对待您的测试代码.一旦它被证明有效,你就认为它确实有效.

另一方面,您可以利用称为保护断言的概念.在您的删除测试中,在安排阶段之后,您引入了额外的断言阶段,这将验证您的初始假设(在这种情况下 - 添加正在工作).可以在此处找到有关此技术的更多信息.

举个例子,NUnit 使用了上面伪装的概念 理论.这完全符合您的建议(但它似乎与数据驱动测试而不是通用实用程序更相关):

<块引用>

理论本身负责确保提供的所有数据都符合其假设.它通过使用 Assume.That(...) 构造来实现这一点,它的工作方式与 Assert.That(...) 类似,但不会导致失败.如果特定测试用例不满足假设,则该用例返回不确定结果,而不是成功或失败.

但是,我认为 Mark Seemann 在回答中对我链接的问题所说的话最有道理:><块引用>

对于给定的测试用例,可能需要满足许多先决条件,因此您可能需要不止一个 Guard Assertion.无需在所有测试中重复这些,而是​​对每个前提条件进行一个(且仅一个)测试可以让您的测试代码更易于维护,因为这样重复的次数会更少.

Consider unit testing a dictionary object. The first unit tests you might write are a few that simply adds items to the dictionary and check exceptions. The next test may be something like testing that the count is accurate, or that the dictionary returns a correct list of keys or values.

However, each of these later cases requires that the dictionary can first reliably add items. If the tests which add items fail, we have no idea whether our later tests fail because of what they're testing is implemented incorrectly, or because the assumption that we can reliably add items is incorrect.

Can I declare a set of unit tests which cause a given unit test to be inconclusive if any of them fail? If not, how should I best work around this? Have I set up my unit tests wrong, that I'm running into this predicament?

解决方案

It's not as hard as it might seem. Let's rephrase the question a bit:

If I test my piece of code which requires System.Collections.Generic.List<T>.Add to work, what should I do when one day Microsoft decides to break .Add on List<T>? Do I make my tests depending on this to work inconclusive?

Answer to the above is obvious; you don't. You let them fail for one simple reason - your assumptions have failed, and test should fail. It's the same here. Once you get your add tests to work, from that point on you assume add works. You shouldn't treat your tested code any differently than 3rd party tested code. Once it's proven to work, you assume it indeed does.

On a different note, you can utilize concept called guard assertions. In your remove test, after the arrange phase you introduce additional assert phase, which verifies your initial assumptions (in this case - that the add is working). More information about this technique can be found here.

To add an example, NUnit uses the concept above disguised under the name Theory. This does exactly what you proposed (yet it seems to be more related to data driven testing rather than general utility):

The theory itself is responsible for ensuring that all data supplied meets its assumptions. It does this by use of the Assume.That(...) construct, which works just like Assert.That(...) but does not cause a failure. If the assumption is not satisfied for a particular test case, that case returns an Inconclusive result, rather than a Success or Failure.

However, I think what Mark Seemann states in an answer to the question I linked makes the most sense:

There may be many preconditions that need to be satisfied for a given test case, so you may need more than one Guard Assertion. Instead of repeating those in all tests, having one (and one only) test for each precondition keeps your test code more mantainable, since you will have less repetition that way.

这篇关于如果必要的单元测试失败,我可以使单元测试不确定吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆