Oha*_*der 8 c# language-agnostic unit-testing
假设我正在尝试测试一个简单的Set类
public IntSet : IEnumerable<int>
{
Add(int i) {...}
//IEnumerable implementation...
}
Run Code Online (Sandbox Code Playgroud)
并且假设我正在尝试测试集合中不存在重复值.我的第一个选择是将一些样本数据插入到集合中,并使用我对所用数据的了解来测试重复项,例如:
//OPTION 1
void InsertDuplicateValues_OnlyOneInstancePerValueShouldBeInTheSet()
{
var set = new IntSet();
//3 will be added 3 times
var values = new List<int> {1, 2, 3, 3, 3, 4, 5};
foreach (int i in values)
set.Add(i);
//I know 3 is the only candidate to appear multiple times
int counter = 0;
foreach (int i in set)
if (i == 3) counter++;
Assert.AreEqual(1, counter);
}
Run Code Online (Sandbox Code Playgroud)
我的第二个选择是通常测试我的状况:
//OPTION 2
void InsertDuplicateValues_OnlyOneInstancePerValueShouldBeInTheSet()
{
var set = new IntSet();
//The following could even be a list of random numbers with a duplicate
var values = new List<int> { 1, 2, 3, 3, 3, 4, 5};
foreach (int i in values)
set.Add(i);
//I am not using my prior knowledge of the sample data
//the following line would work for any data
CollectionAssert.AreEquivalent(new HashSet<int>(values), set);
}
Run Code Online (Sandbox Code Playgroud)
当然,在这个例子中,我方便地有一个要检查的set实现,以及比较集合的代码(CollectionAssert).但如果我没有呢?这段代码肯定比以前的选项更复杂!当您测试现实生活中的自定义业务逻辑时,就会出现这种情况.
当然,对预期条件的测试通常会涵盖更多情况 - 但它变得非常类似于再次实现逻辑(这既乏味又无用 - 您不能使用相同的代码来检查自己!).基本上我问的是我的测试是否应该看起来像"插入1,2,3然后检查一下3"或"插入1,2,3并检查一般情况"
编辑 - 为了帮助我理解,如果您更喜欢选项1或选项2(或两者都没有,或者它取决于案例等),请在答案中说明.只是为了澄清,很明显,在这种情况下(IntSet),选项2在所有方面都更好.但是,我的问题与您没有替代实现进行检查的情况有关,因此选项2中的代码肯定比选项1复杂.
基本上我问的是我的测试是否应该类似于“插入 1, 2, 3 然后检查有关 3 的内容”或“插入 1, 2, 3 并检查一般内容”
我不是 TDD 纯粹主义者,但似乎人们说,如果您尝试测试的条件被破坏,测试就应该被破坏。ei 如果您实施检查一般条件的测试,那么您的测试将在多种情况下中断,因此它不是最佳的。
如果我正在测试无法添加重复项,那么我只会测试它。所以在这种情况下,我会说我会先选择。
好的,现在您已经更新了代码,我需要更新我的答案。
我会选择哪一个?这取决于 的实施CollectionAssert.AreEquivalent(new HashSet<int>(values), set);。例如,IEnumerable<T>确实保持顺序,HashSet<T>而不保持顺序,因此即使这可能会破坏测试,但不应该破坏测试。对我来说,第一仍然是优越的。
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |