Pav*_*nin 5 c# tdd autofixture
对于那些不确定"受限制的非决定论"是什么意思的人,我推荐Mark Seeman的帖子.
该想法的本质是仅对影响SUT行为的数据具有确定性值的测试.不"相关"数据在某种程度上可以是"随机的".
我喜欢这种方法.抽象的数据越多,预期就会变得越清晰和富有表现力,实际上,无意识地将数据纳入测试变得更加困难.
我正试图将这种方法(以及AutoFixture)"推销" 给我的同事,昨天我们就此进行了长时间的辩论.
他们提出了一个有趣的论点,即由于随机数据而不能稳定地进行调试.
起初看起来有点奇怪,因为我们都同意影响数据的流量不能是随机的,这种行为是不可能的.尽管如此,我还是休息一下,彻底思考这个问题.我终于遇到了以下问题:
但我的一些假设首先是:
考虑同一测试的这两个变体:
[TestMethod]
public void DoSomethig_RetunrsValueIncreasedByTen()
{
// Arrange
ver input = 1;
ver expectedOutput = input+10;
var sut = new MyClass();
// Act
var actualOuptut = sut.DoeSomething(input);
// Assert
Assert.AreEqual(expectedOutput,actualOutput,"Unexpected return value.");
}
/// Here nothing is changed besides input now is random.
[TestMethod]
public void DoSomethig_RetunrsValueIncreasedByTen()
{
// Arrange
var fixture = new Fixture();
ver input = fixture.Create<int>();
ver expectedOutput = input+10;
var sut = new MyClass();
// Act
var actualOuptut = sut.DoeSomething(input);
// Assert
Assert.AreEqual(expectedOutput,actualOutput,"Unexpected return value.");
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,上帝,一切正常,生活是美好的,然后需求改变并DoSomething改变其行为:现在只有当它低于10时才增加输入,否则增加10.这里发生了什么?使用硬编码数据的测试通过(实际上是意外),而第二次测试有时会失败.而且他们都是错误的欺骗测试:他们检查不存在的行为.
看起来无论数据是硬编码还是随机数都无关紧要:它只是无关紧要.然而,我们没有可靠的方法来检测这种"死"的测试.
所以问题是:
有没有什么好建议如何以这种情况出现的方式编写测试?
答案实际上隐藏在这句话中:
[..]然后需求变化,DoSomething改变其行为[..]
如果你这样做会不会更容易:
expectedOutput,以满足新的要求.DoSomething根据新要求进行修改- 让测试再次通过.此方法与AutoFixture等特定工具无关,它只是测试驱动开发.
那么AutoFixture 真的有用吗?使用AutoFixture,您可以最小化测试的编配部分.
这是原始测试,使用AutoFixture.Xunit以惯用方式编写:
[Theory, InlineAutoData]
public void DoSomethingWhenInputIsLowerThan10ReturnsCorrectResult(
MyClass sut,
[Range(int.MinValue, 9)]int input)
{
Assert.True(input < 10);
var expected = input + 1;
var actual = sut.DoSomething(input);
Assert.Equal(expected, actual);
}
[Theory, InlineAutoData]
public void DoSomethingWhenInputIsEqualsOrGreaterThan10ReturnsCorrectResult(
MyClass sut,
[Range(10, int.MaxValue)]int input)
{
Assert.True(input >= 10);
var expected = input * 10;
var actual = sut.DoSomething(input);
Assert.Equal(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)
此外,除xUnit.net外,还支持NUnit 2.
HTH
"然后需求变化,DoSomething改变其行为"
真的吗?如果DoSomething改变行为,则违反了开放/封闭原则(OCP).您可能决定不关心这一点,但它与我们信任测试的原因密切相关.
每次更改现有测试时,都会降低其可信度.每次更改现有生产行为时,您都需要查看触及该生产代码的所有测试.理想情况下,您需要访问每个此类测试,并简要地更改实现,以确定如果实现错误,它仍然会失败.
对于微小的变化,这可能仍然是实用的,但即使是适度的变化,坚持OCP也会更明智:不要改变现有的行为; 并排添加新行为,让旧行为萎缩.
在上面的例子中,可能很清楚AutoFixture测试可能是非确定性的错误,但在更概念的层面上,完全有可能的是,如果你在不审查测试的情况下改变生产行为,一些测试可能会默默地变成假阴性.这是与单元测试相关的一般问题,并非特定于AutoFixture.
| 归档时间: |
|
| 查看次数: |
529 次 |
| 最近记录: |