JUnit 测试用例中“失败”的实际用途是啥?

Posted

技术标签:

【中文标题】JUnit 测试用例中“失败”的实际用途是啥?【英文标题】:What's the actual use of 'fail' in JUnit test case?JUnit 测试用例中“失败”的实际用途是什么? 【发布时间】:2011-04-21 15:52:53 【问题描述】:

JUnit 测试用例中“失败”的实际用途是什么?

【问题讨论】:

【参考方案1】:

我发现它有用的一些情况:

标记一个不完整的测试,所以它会失败并警告你,直到你完成它 确保抛出异常:
try
  // do stuff...
  fail("Exception not thrown");
catch(Exception e)
  assertTrue(e.hasSomeFlag());

注意:

从 JUnit4 开始,有一种更优雅的方法可以测试是否抛出了异常: 使用注解@Test(expected=IndexOutOfBoundsException.class)

但是,如果您还想检查异常,这将不起作用,那么您仍然需要fail()

【讨论】:

考虑这篇关于失败与预期注释的相对优点的博客文章:blog.jooq.org/2016/01/20/… @sleske “如果你还想检查异常,那么你仍然需要 fail()”——不。 ExpectedException 是办法,见github.com/junit-team/junit4/wiki/exception-testing @kraxor:是的,我写答案时并不知道(当时可能还不知道)。【参考方案2】:

假设您正在为负流编写一个测试用例,其中被测试的代码应该引发异常。

try
   bizMethod(badData);
   fail(); // FAIL when no exception is thrown
 catch (BizException e) 
   assert(e.errorCode == THE_ERROR_CODE_U_R_LOOKING_FOR)

【讨论】:

【参考方案3】:

我认为通常的用例是在否定测试中没有抛出异常时调用它。

类似于下面的伪代码:

test_addNilThrowsNullPointerException()

    try 
        foo.add(NIL);                      // we expect a NullPointerException here
        fail("No NullPointerException");   // cause the test to fail if we reach this            
      catch (NullNullPointerException e) 
        // OK got the expected exception
    

【讨论】:

如果您不检查 catch 块中的某些内容,您可以使用 @ExpectedException(NullNullPointerException.class) 方法注释来声明您期望异常(特殊类型)。 @FrVaBe 我可能不正确,但这不是 2010 年 Junit 的一部分。【参考方案4】:

我在 @Before 方法中可能出现问题的情况下使用了它。

public Object obj;

@Before
public void setUp() 
    // Do some set up
    obj = new Object();


@Test
public void testObjectManipulation() 
    if(obj == null) 
        fail("obj should not be null");
     

    // Do some other valuable testing

【讨论】:

是的,测试前提条件很好。但是,如果您想确保 @Before 方法成功,最好直接在该方法中进行检查。作为奖励,至少 JUnit 和 TestNG 甚至会针对来自 @Before/@After 方法的错误报告不同的失败,因此可以看出问题不在测试本身。【参考方案5】:

这就是我使用 Fail 方法的方式。

您的测试用例最终会处于三种状态

    Passed : 被测函数成功执行并返回 数据符合预期 未通过:被测函数成功执行,但 返回的数据不符合预期 失败:函数没有成功执行,这不是

有意(与期望异常的负面测试用例不同) 发生)。

如果您使用的是 eclipse,则三个状态分别由绿色、蓝色和红色标记表示。

我将失败操作用于第三种情况。

例如: public Integer add(integer a, Integer b) return new Integer(a.intValue() + b.intValue())

    通过案例:a = new Interger(1), b= new Integer(2) 并且函数返回 3 未通过案例:a = new Interger(1), b= new Integer(2) 并且函数返回非 3 的 soem 值 失败案例:a =null , b= null 并且函数抛出 NullPointerException

【讨论】:

如果您查看 JUnit 的源代码,您会发现断言使用 fail()【参考方案6】:

例如,我使用fail() 表示尚未完成的测试(它发生了);否则,它们将显示为成功。

这可能是因为我不知道 NUnit 中存在某种不完整() 功能。

【讨论】:

【参考方案7】:

在并发和/或异步设置中,您可能想要验证某些方法(例如委托、事件侦听器、响应处理程序,您可以命名)是否被调用。除了模拟框架,您可以在这些方法中调用 fail() 以使测试失败。在这种情况下,超时超时是另一种自然故障条件。

例如:

final CountDownLatch latch = new CountDownLatch(1);

service.asyncCall(someParameter, new ResponseHandler<SomeType>() 
    @Override
    public void onSuccess(SomeType result) 
        assertNotNull(result);
        // Further test assertions on the result
        latch.countDown();
    

    @Override
    public void onError(Exception e) 
        fail(exception.getMessage());
        latch.countDown();
    
);

if ( !latch.await(5, TimeUnit.SECONDS) ) 
    fail("No response after 5s");

【讨论】:

【参考方案8】:

最重要的用例可能是异常检查。

虽然 junit4 包含用于检查是否发生异常的 expected element,但它似乎不是较新的 junit5 的一部分。与expected 相比,使用fail() 的另一个优点是您可以将其与finally 结合使用,从而进行测试用例清理。

dao.insert(obj);
try 
  dao.insert(obj);
  fail("No DuplicateKeyException thrown.");
 catch (DuplicateKeyException e) 
  assertEquals("Error code doesn't match", 123, e.getErrorCode());
 finally 
  //cleanup
  dao.delete(obj);

如另一条评论所述。在您完成实施之前让测试失败听起来也很合理。

【讨论】:

以上是关于JUnit 测试用例中“失败”的实际用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 JUnit 测试用例按顺序运行?

事务回滚在 JUnit5 的 @Nested 类的测试用例中不起作用

在Spring Boot Junit测试用例中使用contextLoads方法有什么用?

测试用例失败:参数不同!通缉:

如何在 android 的 JUnit 测试用例中获取 MainActivity 的上下文和活动?

即使使用 Junit 4 框架在 selenium 中断言语句失败也继续执行 [重复]