我的看法是,你们俩都有优势,而你们处于“劣势”(原文如此)。
好处是您拥有一个舒适的系统,并且可以为您工作。您很高兴它确认了您产品的有效性,并且尝试为使用不同框架的产品更改所有测试时,可能会发现没有商业价值。如果您可以重构代码,并且测试可以接受更改,或者更好,但是,如果您可以修改测试,并且现有代码在重构之前无法通过测试,那么您已经涵盖了所有基础。然而...
拥有设计良好的单元测试API的优点之一是,在大多数现代IDE中都有很多本机支持。这不会影响那些对Visual Studio用户冷嘲热讽的核心VI和emacs用户,但是对于那些使用良好IDE的使用者,您可以调试测试并在其中执行IDE本身。这样做很好,但是根据您使用的框架,还有一个更大的优势,那就是用来测试代码的语言。
当我说语言时,我不是在谈论编程语言,而是在谈论用流利的语法包装的丰富的单词,使测试代码读起来像个故事。特别是,我已经成为使用BDD框架的拥护者。我个人最喜欢的DotNet BDD API是StoryQ,但是还有其他几个具有相同的基本目的,那就是从需求文档中取出一个概念,并以与规范中的编写方式相似的方式将其编写为代码。然而,真正好的API可以走得更远,可以拦截测试中的每个单独的语句,并指示该语句是成功执行还是失败。这非常有用,因为您可以看到整个测试已执行而没有提前返回,这意味着调试工作变得非常高效,因为您只需要将注意力集中在测试失败的部分上,而无需解码整个调用顺序。另一个好处是,测试输出将向您显示所有这些信息,
作为我正在谈论的示例,请比较以下内容:
使用断言:
Assert(variable_A == expected_value_1); // if this fails...
Assert(variable_B == expected_value_2); // ...this will not execute
Assert(variable_C == expected_value_3); // ...and nor will this!
使用流畅的BDD API :(
假设斜体位基本上是方法指针)
WithScenario("Test Scenario")
.Given(*AConfiguration*) // each method
.When(*MyMethodToTestIsCalledWith*, variable_A, variable_B, variable_C) // in the
.Then(*ExpectVariableAEquals*, expected_value_1) // Scenario will
.And(*ExpectVariableBEquals*, expected_value_2) // indicate if it has
.And(*ExpectVariableCEquals*, expected_value_3) // passed or failed execution.
.Execute();
现在授予BDD语法更长,更单词,并且这些示例都非常人为,但是对于非常复杂的测试情况,由于给定的系统行为,系统中的许多事情都在变化,BDD语法为您提供了清晰的关于您正在测试的内容以及如何定义测试配置的描述,您可以将该代码显示给非程序员,他们将立即了解正在发生的事情。此外,如果“ variable_A”在两种情况下均未通过测试,则在您解决问题之前,Asserts示例将不会执行第一个断言,而BDD API会依次执行链中调用的每个方法,并指出语句的各个部分有误。
就我个人而言,我发现这种方法比更传统的xUnit框架要好得多,因为测试的语言与客户说出他们的逻辑要求的语言相同。即便如此,我还是设法以相似的样式使用xUnit框架,而无需发明一个完整的测试API来支持我的工作,尽管这些assert仍然可以有效地使自己短路,但是它们的阅读更加清晰。例如:
使用Nunit:
[Test]
void TestMyMethod()
{
const int theExpectedValue = someValue;
GivenASetupToTestMyMethod();
var theActualValue = WhenIExecuteMyMethodToTest();
Assert.That(theActualValue, Is.EqualTo(theExpectedValue)); // nice, but it's not BDD
}
如果您决定使用单元测试API进行探索,我的建议是在一段时间内尝试使用大量不同的API,并保持开放态度。虽然我本人主张使用BDD,但您自己的业务需求可能会因团队情况而有所不同。但是,关键是要避免对现有系统进行猜测。如果需要,您总是可以通过使用其他API的一些测试来支持现有的测试,但是我当然不建议为了使所有内容相同而进行大量的测试重写。由于遗留代码不再使用,您可以轻松地用新代码替换它及其测试,并使用替代API进行测试,而无需花费大量精力来投入,这不一定会给您带来真正的商业价值。至于使用单元测试API,