C#/ Visual Studio:生产和测试代码放置

时间:2010-05-26 05:57:14

标签: c# visual-studio unit-testing

在JavaLand中,我习惯于创建包含生产和测试代码的项目。我喜欢这种做法,因为它简化了内部代码的测试,而没有人为地暴露项目发布的API中的内部。

到目前为止,根据我使用C#/ Visual Studio / ReSharper / NUnit的经验,我为生产和测试代码创建了单独的项目(即单独的DLL)。这是成语,还是我不在基地?如果这个惯用正确,那么处理为测试目的公开类和方法的正确方法是什么?

谢谢,

-Patrick

4 个答案:

答案 0 :(得分:5)

测试内部代码很简单:使用[InternalsVisibleTo]使您的生产程序集“信任”您的测试程序集。然后,测试组件可以访问所有生产组件的内部成员。

上面链接的MSDN文档给出了一个示例。这很简单。

你应该把你的两个分开,尽管如此,IMO。您并不希望您的测试代码(或数据)最终出现在生产程序集中。

编辑:只是回应史蒂文关于测试内部结构的观点:我认为测试内部结构是完全合理的。我将单元测试视为白盒测试,而不是黑盒测试。肯定有一个地方只测试公共API - 尤其是集成测试 - 但我发现有很多地方测试内部成员是有意义的。哎呀,没有那种能力,你将如何测试内部的类型?有时,相对较小的公共API会在复杂的内部实现之上进行分层 - 并且仅通过公共API对该实现的单元进行测试可能会非常棘手。

确实使测试更加脆弱,因为内部实现更改可能需要测试更改,如果您只测试公共API,则不需要测试更改...但它也可以使生产代码更加健壮,因为你很容易为角落案例等编写大量的测试,如果这很容易的话。

基本上适应所有事情。

答案 1 :(得分:0)

生产代码中的测试代码?我不知道Java是如何处理的,但这对我来说听起来很可怕: - )

DotNetLand中的“常态”通常每个主程序集都有一个测试程序集,我认为这有几个原因:

  • 代码分离 - 我不确定Java如何处理这个问题,但是如果你在同一个项目中拥有测试代码,那么是什么阻止你在应用程序中意外地发送测试代码?希望这只是我对Java如何从测试角度而不是真正的关注点开始的无知。
  • 从“外部”进行测试 - 如果您被迫从代码外部进行测试,那么测试应该会让您更多地考虑是否要测试被测代码的行为,而不是实现。你可以使用诸如InternalsVisibleTo之类的东西来处理内部状态,但是当你达到类似的东西时,你可能正在测试实现细节,而不是外部可观察到的导致脆弱测试的行为。

第二点可能听起来像是“教你吮吸鸡蛋”,但这是一个陷阱,我看到很多开发者陷入其中。

答案 2 :(得分:0)

您可以在this post (how to unit test private methods)找到问题的答案。实质上,如果您无法将测试代码与生产代码分开,则应重新考虑您的设计(对于Java也是如此)。

答案 3 :(得分:0)

您认为创建单独的程序集/项目以将测试代码与生产代码隔离在.NET领域是正确的,这是正确的。在指导人们进行单元测试时,我真的很鼓励这种做法,因为我不想在我的生产代码中混合使用测试代码。

一般来说,我非常不愿意测试我的SUT的私有/受保护方法。关于TDD / UnitTesting的好处是你描述了外部行为,并使实现细节保持灵活和“黑盒子”。然后,您可以自由地进行尽可能多的重构,只要它们不破坏外部行为,就不需要更改测试。

如果您在某种程度上依赖于实现细节(继承,从生产程序集中访问privates / protected方法),那么您的测试将需要像类的内部细节更改一样频繁地重构。

有时,您可能有一个要测试的内部类/方法。在这种情况下,您可以在生产AssemblyInfo.cs文件中使用[assembly:InternalsVisibleTo(“Test Assembly Name”)]属性,并允许测试程序集查看生产程序集的内部。

MSDN上的

InternalsVisibleToAttribute

应该注意的是,如果您是.NET新手,则internal是与private和protected不同的访问限定符。内部类在装配它的程序集中是“公共的”。

希望这能回答你的问题。