我正在测试一个包含三个不同模块的网页。在我的测试框架中,每个页面模块都由自己的测试类表示:Module1Tests
、Module2Tests
、Module3Tests
。此外,为了满足每个模块的特定条件,我在每个测试类中使用Assume.That
。 通过此设置,如果我只是测试单独的模块,一切正常。 但是,当我为整个页面创建一个测试类并使用如下所示Assert.Multiple
时:
public class HomePageTests
{
public Module1Tests Module1Tests { get; } = new Module1Tests();
public Module2Tests Module2Tests { get; } = new Module2Tests();
public Module3Tests Module3Tests { get; } = new Module3Tests();
[Test]
public void HomePage()
{
Assert.Multiple(() =>
{
Module1Tests.Module1TestMethod();
Module2Tests.Module2TestMethod();
Module3Tests.Module3TestMethod();
});
}
我收到错误消息,指出我无法在Assert.Multiple
块中使用具有Assume.That
的方法。
我还尝试在没有Assert.Multiple
块的情况下调用模块测试方法,但整个页面测试在第一次失败时停止执行。
有没有办法解决这个问题?基本上,我只想对页面进行测试,如果所有底层模块测试都通过,该页面就会通过。
正如已经指出的,并且正如消息所示,您不能在多重断言块中使用假设。如果您查看文档"假设"页面上注释 6 中的排除项列表,您会发现它们都是旨在立即终止测试执行的项目。
当然,Assert.Fail 以及失败的断言也旨在立即终止测试。多个断言是一个例外...记录失败,但测试不会终止,直到所有嵌套的 Assert.Multiple 块结束。
我考虑过对列表中的每个项目进行一些例外,这需要为每个项目定义新的行为。目前尚不清楚最好的替代行为是什么,所以我决定等待用户反馈。这个SO问题实际上是我在任何地方看到的第一个反馈,所以谢谢!
在通常的使用中,假设放在所有断言之前,有时甚至在 SetUp 方法中也是如此。在这种情况下,它们的含义基本上是:"如果这个假设失败了,那么运行测试就没有意义了。有时,它们被放置在几个断言之后,这意味着"如果失败,则不再运行任何测试是没有意义的。
如果我理解正确,您希望一个失败的假设意味着我们应该在您的一个模块测试中跳过以下所有断言,但继续任何其他模块测试。但是,至少在今天,在 NUnit 中不存在模块测试的概念。NUnit 中可用的结构由层次结构表示: * 命名空间(可能是嵌套的) *夹具 * 测试用例 * 多个断言块(可能嵌套) *断言
如果您的模块测试本身使用多个断言块,那么我们可以考虑将多断言块中的假设行为映射到"在此块中运行更多的测试代码是没有意义的"。如果你想要这个,你需要在github上提交一个功能请求。我可以预先告诉你,这不是一个微不足道的变化,所以不能保证我们会这样做,但可能值得做一些分析,看看它是如何工作的。基本上,我们希望在不混淆其他用户的情况下为您提供所需的内容。:-)
使用当前功能,我看到两种解决方法:
-
使每个模块测试成为夹具中的单独测试方法,基本上取代了当前的测试方法。如果执行顺序对您很重要,请将 Order 属性放在每个测试上。换句话说,具有 n 个测试的现有夹具将成为 n 个单独的夹具。我不知道这对你来说是否可行,因为我还没有看到你的代码,但这是利用 NUnit 的现有设施来构建测试的一种方法。
-
将模块测试封装为一组类,而不是一组方法。使用一种方法运行所有假设,使用另一种方法运行所有断言。在 Assert.Multiple 块之前预先调用所有假设。如果您不希望失败的假设停止整个测试,则必须从假设条目中返回一个布尔值,并记住是否运行每个模块。
-
可能是最简单的:在每个模块测试方法中将您的假设变成条件。如果假设失败,则不要运行测试。
我真的希望我能提供作为结构的替代方案的是嵌套夹具。在许多方面,这将比其他选项更适合您尝试做得更好的事情。遗憾的是,即使 NUnit 允许在语法上嵌套夹具,在运行测试时也会完全忽略嵌套。我们有一个出色的功能要求来改变这一点,但它相当具有未来感。
- reprac(英语:ol start="2">
- reprac)