Cách sử dụng thực tế của 'fail' trong trường hợp thử nghiệm JUnit là gì?


Câu trả lời:


138

Một số trường hợp mà tôi thấy nó hữu ích:

  • đánh dấu một bài kiểm tra chưa hoàn thành, vì vậy nó không thành công và cảnh báo bạn cho đến khi bạn có thể hoàn thành nó
  • đảm bảo rằng một ngoại lệ được ném ra:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Ghi chú:

Kể từ JUnit4, có một cách thanh lịch hơn để kiểm tra xem có ngoại lệ nào đang được ném ra hay không: Sử dụng chú thích @Test(expected=IndexOutOfBoundsException.class)

Tuy nhiên, điều này sẽ không hoạt động nếu bạn cũng muốn kiểm tra ngoại lệ, thì bạn vẫn cần fail().


5
Xem xét bài viết trên blog này về giá trị tương đối của thất bại vs chú thích mong đợi: blog.jooq.org/2016/01/20/...
lbalazscs

4
@sleske "nếu bạn cũng muốn kiểm tra ngoại lệ, thì bạn vẫn cần fail ()" - nope. Dự kiến, ngoại lệ là cách, hãy xem github.com/junit-team/junit4/wiki/exception-testing
kraxor

@kraxor: Đúng, tôi không biết về điều đó khi tôi viết câu trả lời (có lẽ lúc đó còn chưa xuất hiện).
sleske

14

giả sử bạn đang viết một trường hợp thử nghiệm cho luồng a -ve trong đó mã đang được thử nghiệm sẽ tạo ra một ngoại lệ

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

10

Tôi nghĩ rằng trường hợp sử dụng thông thường là gọi nó khi không có ngoại lệ nào được đưa ra trong một bài kiểm tra âm tính.

Một cái gì đó giống như mã giả sau:

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
    }
}

3
Nếu bạn không kiểm tra điều gì đó trong khối bắt, bạn có thể sử dụng chú thích phương thức @EprisException (NullNullPointerException.class) để khai báo rằng bạn mong đợi một ngoại lệ (thuộc một loại đặc biệt).
FrVaBe

8

Tôi đã sử dụng nó trong trường hợp có điều gì đó không ổn trong phương thức @Before của tôi.

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
}

1
Có, điều kiện tiên quyết là tốt. Tuy nhiên, nếu bạn muốn chắc chắn rằng @Beforephương pháp đã thành công, tốt hơn hết là bạn nên kiểm tra trực tiếp trong phương pháp đó. Như một phần thưởng, ít nhất JUnit và TestNG thậm chí sẽ báo cáo một lỗi khác đối với các lỗi từ @Before/ @Aftermethod, vì vậy có thể thấy rằng vấn đề không nằm trong chính bài kiểm tra.
sleske

4

Đây là cách tôi sử dụng phương pháp Fail.

Có ba trạng thái mà trường hợp thử nghiệm của bạn có thể kết thúc bằng

  1. Đạt: Hàm đang được kiểm tra được thực thi thành công và trả về dữ liệu như mong đợi
  2. Không đạt: Hàm đang kiểm tra được thực thi thành công nhưng dữ liệu trả về không như mong đợi
  3. Không thành công: Hàm không thực thi thành công và đây không phải là

dự định (Không giống như các trường hợp kiểm tra tiêu cực mong đợi một ngoại lệ xảy ra).

Nếu bạn đang sử dụng nhật thực, ba trạng thái được biểu thị bằng điểm đánh dấu Xanh lục, Xanh lam và đỏ tương ứng.

Tôi sử dụng thao tác thất bại cho trường hợp thứ ba.

ví dụ: public Integer add (integer a, Integer b) {return new Integer (a.intValue () + b.intValue ())}

  1. Trường hợp đã qua: a = new Interger (1), b = new Integer (2) và hàm trả về 3
  2. Trường hợp không đạt: a = new Interger (1), b = new Integer (2) và hàm trả về giá trị soem khác 3
  3. Trường hợp không thành công: a = null, b = null và hàm ném một NullPointerException

1
Nếu bạn nhìn vào mã nguồn của JUnit, bạn sẽ thấy rằng các xác nhận sử dụng fail().
Daniel C. Sobral

3

Tôi, ví dụ, sử dụng fail()để chỉ ra các bài kiểm tra chưa kết thúc (nó xảy ra); nếu không, chúng sẽ hiển thị là thành công.

Điều này có lẽ là do tôi không biết về một số loại chức năng không hoàn chỉnh () tồn tại trong NUnit.


2

Trong cài đặt đồng thời và / hoặc không đồng bộ, bạn có thể muốn xác minh rằng một số phương thức nhất định (ví dụ: đại biểu, trình nghe sự kiện, trình xử lý phản hồi, bạn đặt tên cho nó) không được gọi. Bỏ qua các khuôn khổ chế nhạo, bạn có thể sử dụng fail()các phương pháp đó để thất bại trong các bài kiểm tra. Hết thời gian chờ là một điều kiện thất bại tự nhiên khác trong các tình huống như vậy.

Ví dụ:

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");
}

0

Trường hợp sử dụng quan trọng nhất có lẽ là kiểm tra ngoại lệ.

Trong khi junit4 bao gồm phần tử được mong đợi để kiểm tra xem có ngoại lệ xảy ra hay không, có vẻ như nó không phải là một phần của junit5 mới hơn. Một ưu điểm khác của việc sử dụng fail()over the expectedlà bạn có thể kết hợp nó với finallyviệc cho phép dọn dẹp test-case.

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);
}

Như đã lưu ý trong một bình luận khác. Có một thử nghiệm thất bại cho đến khi bạn có thể hoàn thành việc thực hiện nó cũng có vẻ hợp lý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.