JUnit ParentRunner 应该捕获 AssertionError 吗?
Should JUnit ParentRunner catch AssertionError?
我已经实现了一个基于 BlockJUnit4ClassRunner
的自定义 TestRunner。
我的假设是任何失败的断言(表示 product/requirement 问题)将通过 addFailedAssumption()
报告给通知者,而其他异常将通过 addFailure()
报告,表明单元中的错误测试自己。
查看结果,addFailedAssumption()
从未被调用。在ParentRunner
.runLeaf()
的源代码中,我看到
try {
statement.evaluate();
} catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
} catch (Throwable e) {
eachNotifier.addFailure(e);
} finally {
eachNotifier.fireTestFinished();
}
我得到的异常都是java.lang.AssertionError
.
类型
应该ParentRunner
赶上AssertionError
还是我这边有误会?
阅读有关此主题的更多信息,这似乎是我这边的语言/翻译问题,因为我不是母语人士。
找到 class Assume 帮助我做对了(我希望),我将用一个例子来解释它:
AssumtionViolatedException 的用法
测试可以例如运行在不同的环境下,比方说不同的操作系统。也许产品的行为或需要在不同的操作系统上表现略有不同,例如因为它可以在较新的 OS 上使用 API 调用,而旧版本的 OS 中不存在。这可能会导致类似
的代码
if(isApiPresent())
SimpleAPICall();
else
// Do some crazy stuff here, potentially slower than the API call
isApiPresent()
调用将 return 不同的结果取决于 OS,因此您编写 2 个单元测试并添加一个关于环境的假设:
@Test
public void isApiPresent_returns_true_on_Win8()
{
assumeTrue(System.getProperty("os.version").equals("6.2"));
assertTrue(isApiPresent());
}
@Test
public void isApiPresent_returns_false_on_Win7()
{
assumeTrue(System.getProperty("os.version").equals("6.1"));
assertFalse(isApiPresent());
}
如果没有给出关于操作系统的假设,由于 @Test
注释,测试仍然会执行,但实际上应该忽略它。 assume...()
语句负责:它们抛出一个 AssumptionViolatedException
可用于忽略测试。
Eclipse 用忽略图标标记一个违反假设的测试(尝试 assumeFalse(true);
):
断言错误的用法
我想通过 TestRunner 的自定义实现实现的目标有点不同。我想找出哪些单元测试由于需求问题而失败,哪些测试由于其他异常而失败,这些异常可能表明单元测试本身存在错误,从而在 Eclipse 中重建图标。 Eclipse 已经区分了这两种问题:AssertionError
标有蓝色图标,而 Exception
标有红色图标。
对我来说,这意味着我必须执行 fireTestFailure()
中的决定:
public void fireTestFailure(Failure failure) {
originalNotifier.fireTestFailure(failure);
if (failure.getException().getClass() == AssertionError.class) {
// Requirement issue
} else {
// Unit test issue
}
}
我已经实现了一个基于 BlockJUnit4ClassRunner
的自定义 TestRunner。
我的假设是任何失败的断言(表示 product/requirement 问题)将通过 addFailedAssumption()
报告给通知者,而其他异常将通过 addFailure()
报告,表明单元中的错误测试自己。
查看结果,addFailedAssumption()
从未被调用。在ParentRunner
.runLeaf()
的源代码中,我看到
try {
statement.evaluate();
} catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
} catch (Throwable e) {
eachNotifier.addFailure(e);
} finally {
eachNotifier.fireTestFinished();
}
我得到的异常都是java.lang.AssertionError
.
应该ParentRunner
赶上AssertionError
还是我这边有误会?
阅读有关此主题的更多信息,这似乎是我这边的语言/翻译问题,因为我不是母语人士。
找到 class Assume 帮助我做对了(我希望),我将用一个例子来解释它:
AssumtionViolatedException 的用法
测试可以例如运行在不同的环境下,比方说不同的操作系统。也许产品的行为或需要在不同的操作系统上表现略有不同,例如因为它可以在较新的 OS 上使用 API 调用,而旧版本的 OS 中不存在。这可能会导致类似
的代码if(isApiPresent())
SimpleAPICall();
else
// Do some crazy stuff here, potentially slower than the API call
isApiPresent()
调用将 return 不同的结果取决于 OS,因此您编写 2 个单元测试并添加一个关于环境的假设:
@Test
public void isApiPresent_returns_true_on_Win8()
{
assumeTrue(System.getProperty("os.version").equals("6.2"));
assertTrue(isApiPresent());
}
@Test
public void isApiPresent_returns_false_on_Win7()
{
assumeTrue(System.getProperty("os.version").equals("6.1"));
assertFalse(isApiPresent());
}
如果没有给出关于操作系统的假设,由于 @Test
注释,测试仍然会执行,但实际上应该忽略它。 assume...()
语句负责:它们抛出一个 AssumptionViolatedException
可用于忽略测试。
Eclipse 用忽略图标标记一个违反假设的测试(尝试 assumeFalse(true);
):
断言错误的用法
我想通过 TestRunner 的自定义实现实现的目标有点不同。我想找出哪些单元测试由于需求问题而失败,哪些测试由于其他异常而失败,这些异常可能表明单元测试本身存在错误,从而在 Eclipse 中重建图标。 Eclipse 已经区分了这两种问题:AssertionError
标有蓝色图标,而 Exception
标有红色图标。
对我来说,这意味着我必须执行 fireTestFailure()
中的决定:
public void fireTestFailure(Failure failure) {
originalNotifier.fireTestFailure(failure);
if (failure.getException().getClass() == AssertionError.class) {
// Requirement issue
} else {
// Unit test issue
}
}