单元测试与生产代码有不同的要求。例如,单元测试可能不必像生产代码那样高效。
或许有时候用更适合编写单元测试的语言编写单元测试有意义吗?我想到的具体示例是使用C#编写应用程序,但使用IronRuby或IronPython编写测试。
正如我所看到的,使用IronPython和IronRuby比C#代码作为测试语言有几个优点:
在测试和生产代码中使用两种不同语言的权衡是什么?
答案 0 :(得分:11)
我想到的缺点:
答案 1 :(得分:7)
一个明显的潜在问题是令人困惑的调试体验。我个人并没有尝试在.NET中跨语言进行调试 - 如果你从IronPython进入C#代码会发生什么?
另一个问题是,任何想要在代码库上开发的人都必须知道这两种语言。
答案 2 :(得分:3)
我是Iron语言的忠实粉丝,但使用它们测试静态编译的代码存在明显的缺点。使用Ruby / Python测试Ruby / Python效果很好,即您可以通过多种方式伪造对象。但是使用Ruby / Python测试C#会导致比所希望的更复杂。
考虑一个您正在编写ASP MVC项目的场景,您希望伪造出向控制器发出请求的浏览器类型。在C#中,你可以像这样模拟它(使用Moq):
var fakeRequest = new Moq.Mock<System.Web.HttpRequestBase>();
fakeRequest.Setup(request => request.Browser.Type).Returns("Fake");
在IronRuby中,它看起来像这样:
class FakeBrowser < HttpBrowserCapabilitiesBase
def type
"Fake"
end
end
class FakeRequest < HttpRequestBase
def browser
FakeBrowser.new
end
end
需要伪造的背景越深,它就越复杂。在C#中,模拟框架会自动为您执行子类型操作,但是在动态语言中,您将会有很多工作要做。像PyMock或Mocha这样的模拟库不能用于这样的测试,因为测试中的代码具有强大的类型依赖性,而Ruby / Python框架生成的虚假对象将不符合这些依赖项。随着IronRuby和IronPython的成熟,我希望看到情况有所改善,但现在测试C#的故事并不是那么好。
如果我认为这是错误的,我很乐意纠正。 =)
答案 3 :(得分:2)
我认为它的主要缺点是可维护性。如果您使用C#编写代码,那么您的开发团队就能胜任该语言,新员工也是如此。你需要一个多功能的开发团队。
我认为值得注意的是,您可能不希望人们用可能不是最强的语言编写测试。您的测试代码需要健壮。
您还需要在编写代码/测试时切换语法 - 这有点令人讨厌。
答案 4 :(得分:2)
我认为这是一个很好的问题和一个值得考虑的想法 - 特别是在像Visual Studio / .NET这样容易支持的环境中
正如你所建议的那样,优点是你可以选择使用一种语言/工具来创建更适合创建测试的测试,而不是用于创建代码的代码,仅此一点,它值得一个思想。
正如建议的那样,缺点是您的开发人员 - 那些创建测试的人(我们必须记住不要将单元测试与测试驱动设计混淆)可能应该能够流利使用多种语言(我建议对于一个优秀的开发人员来说,这样做的能力是相当重要的,但我有偏见!) - 更重要的是,您可能不得不担心两者之间的结构差异(尽管如果您正在谈论.NET语言应该如此为你承保。)
如果您超越“单元”测试,在各个级别的测试中,特定语言的特定功能可能有助于构建测试用例,那么它会变得更加有趣。
最终的问题是优势是否超过了劣势......这可能在某种程度上与案例有关。
答案 5 :(得分:1)
最大的权衡是,如果某人正在考虑使用单元测试来确定如何执行某项操作,那么用不同的语言编写会使其更难使用。此外,您必须使您的C#代码符合CLS。
答案 6 :(得分:1)
在构建API或库时,我经常提供单元测试作为最佳使用API或库的文档形式。大多数时候我构建了一个C#库,我正在交付一个客户端,他将编写C#代码来使用该库。
为了便于记录,至少我的一些测试将始终用目标语言编写。
答案 7 :(得分:1)
最大的缺点是您还在单元测试中测试编译器依赖项。从某种意义上说,这也使它们成为集成测试。如果您希望您的代码可以从多种语言中使用,那么这可能会使它们更受欢迎,但如果您的代码仅在生产中使用它所开发的语言,那么它会增加一些您可能不需要的复杂性。
我可以看到的一个优点是它进一步隔离了从测试本身开发的代码。通过将编写测试的行为与开发中的实际代码分开,它迫使您真正考虑如何编写代码以通过测试,而不是简单地将代码的初始开发移动到测试本身。
答案 8 :(得分:1)
我同意其他有缺点的答案,但我很惊讶很少有人谈到优势。
答案 9 :(得分:0)
在过去的一年里,我参与了一个有两个主要部分的项目:
我们使用Groovy编写了Java单元测试,结果很好。使用groovy的单元测试花费了更少的冗长时间,并且还可以伪造静态方法等等。虽然有几个地方由于Groovy的动态类型而遇到了意想不到的结果,但总的来说这是一种积极的体验。
我最近的另一个项目是一个C#ASP.NET MVC 3 Web应用程序,我用F#编写了所有单元测试。我为网络应用程序选择了C#,因为我认为它在MVC 3中效果更好。我选择F#进行单元测试,因为它是我最喜欢的语言。我遇到的唯一问题是对null
与option
等类型的轻微烦恼。
当我们有两种语言针对相同的运行时(分别是CL#和JRE上的C#/ F#和Java / Groovy),其中一种用于生产代码,一种用于单元测试,没有太多担心关于兼容性至少。然后我认为这是一个问题,你和你的团队是否在这两种语言中都感觉足够舒服(我想你也可以考虑未来的维护者)。实际上,我认为你被迫使用不同语言进行单元测试的时候,单元测试语言实际上是你的生产语言的舒适或选择语言。
我承认这种自由态度有一些例外。如果您正在设计一个由语言X使用的库,那么用X语言编写单元测试可能是个明智之举(至少有一些)。但对于应用程序代码,我从未发现使用与生产代码相同的语言编写单元测试特别有利。