12/08/2018, 00:42

Part 2: Giới thiệu về mã nguồn mở TestNG dành cho kiểm thử phần mềm

Tạo lớp kiểm thử (TestClass) bằng TestNG Trong phần này chúng tôi sẽ hướng dẫn cách tạo các lớp kiểm thử bằng TestNG. Chúng ta sẽ bắt đầu từ List1 là lớp đối tượng Test "TartgetClass". Lớp này sẽ define phương thức add() cộng đơn thuần và phương thức throwException() cho phát sinh Exception. ...

Tạo lớp kiểm thử (TestClass) bằng TestNG

Trong phần này chúng tôi sẽ hướng dẫn cách tạo các lớp kiểm thử bằng TestNG. Chúng ta sẽ bắt đầu từ List1 là lớp đối tượng Test "TartgetClass". Lớp này sẽ define phương thức add() cộng đơn thuần và phương thức throwException() cho phát sinh Exception.

public class Target {
    public int add(int a, int b) {
        return a + b;
    }
    public void throwException() {
        throw new RuntimeException("Exception occurred ");
    }
}

List 1 TargetClass: Đối tượng test

Tiếp theo là List2 là lớp kiểm thử để kiểm chứng đối tượng test.

import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class TestNGSample {
    private Target target;
    public TestNGSample() {
        System.out.println(
            "★Called contractor của TestNGSample★");
    }
    @Test
    public void verifyAdd1() {
        System.out.println("★★★Called verifyAdd1()★★★");
        int result = target.add(1, 2);
        assertEquals(result, 3);
    }
    @Test
    public void verifyAdd2() {
        System.out.println("★★★Called verifyAdd2()★★★");
        int result = target.add(3, 3);
        assertEquals(result, 6);
    }
    @BeforeMethod
    public void init() {
        System.out.println("★★Called init()★★");
        target = new Target();
    }
    @Test(expectedExceptions
        = { java.lang.RuntimeException.class })
    public void exceptionTest() {
        System.out.println(
            "★★★ Called exceptionTest()★★★");
        target.throwException();
    }
}

List 2 TestClass: Lớp kiểm thử

TestNGSample bên trên chính là một lớp kiểm thử TestClass của TestNG. TestClass này không cần phải kế thừa bất kì lớp kiểm thử nào cả. Và ở trong TestClass này, các bạn có thể thấy tôi đã define ra 3 phương thức test là verifyAdd1(), verifyAdd2() và exceptionTest().

TestNG sẽ gắn chỉ dẫn @Test vào phương thức test. Các Method name không cần thiết phải bắt đầu bằng chữ "test" mà có thể đặt tên tùy biến theo ý thích.

Cái mà các bạn cần quan tâm nhất chính là phương thức exceptionTest(). Trong khi test, nếu muốn kiểm thử xem có phát sinh Exception hay không thì cần phải chỉ định lớp exception (ExceptionClass) mà sẽ throw vào thuộc tính expectedExceptions của chỉ dẫn @Test. Khi chạy kiểm thử, nếu phát sinh Exception đã chỉ định tức là kiểm thử thành công, còn ngược lại tức là thất bại. So sánh với cách kiểm thử Exception của JUnit3 thì thấy rằng mục đích kiểm thử rõ ràng hơn và số lượng code cũng ít hơn nhiều.

Ở TestNGSample trên, tôi cũng đã định nghĩa thêm 1 phương thức nữa là init() có chỉ dẫn @BeforeMethod. Cái này không phải là lớp kiểm thử. Theo đúng như nghĩa tiếng anh của từ BeforeMethod, chúng ta sẽ gắn @BeforeMethod vào method mà bạn muốn gọi trước khi chạy TestMethod. Hoạt động này tương tự với phương thức setUp() của JUnit3. Các Method name không cần thiết phải bắt đầu bằng chữ "test" mà có thể đặt tên tùy biến theo ý thích.

Còn nếu muốn thực hiện xử lý tương tự với tearDown() của JUnit3 thì gắn thêm chỉ dẫn @AfterMethod. Vậy ngoài @BeforeXXX và @AfterXXX thì TestNG còn cung cấp thêm những phương thức nào khác nữa? Điều này sẽ được giải thích chi tiết và cụ thể ở phần sau của bài viết này.

Quay lại TestNGSample bên trên, sau khi chạy test này thì sẽ cho ra output như bên dưới. Nhìn vào đó chúng ta có thể hiểu được rằng phương thức init() đang được gọi trước TestMethod.

★ Called constructor của TestNGSample★
★★ Called init()★★
★★★Call verifyAdd2()★★★
★★ Called init()★★
★★★ Called exceptionTest()★★★
★★ Called init()★★
★★★ Called verifyAdd1()★★★

Kết quả chạy kiểm thử

Về cách chạy kiểm thử, chúng tôi sẽ giới thiệu ở phần cuối của bài viết này cùng với hướng dẫn sử dụng Eclipse Plug-in.

TestNG và JUnit4?

JUnit4 cũng là Testing framework sử dụng chỉ dẫn Annotation-based tương tự với TestNG. Vậy hai công cụ này có điểm gì khác nhau? Chúng ta hãy thử cùng làm một phép so sánh xem sao? Trước tiên là JUnit4. Các lớp kiểm thử của JUnit4 như bên dưới:

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
public class JUnit4Sample {
    public JUnit4Sample() {
        System.out.println(
            "★Called contractor của JUnit 4Sample★");
    }
    private Target target;
    @Test
    public void verifyAdd1() {
        System.out.println("★★★Called verifyAdd1()★★★");
        assertEquals(target.add(1, 2), 3);
    }
    @Test
    public void verifyAdd2() {
        System.out.println("★★★Called verifyAdd2()★★★");
        assertEquals(target.add(3, 3), 6);
    }
    @Before
    public void init() {
        System.out.println("★★Called init()★★");
        target = new Target();
    }
    @Test(expected = java.lang.RuntimeException.class)
    public void exceptionTest() {
        System.out.println(
            "★★ Called exceptionTest()★★");
        target.throwException();
    }
}

List 3 Lớp kiểm thử của JUnit4

Thoạt nhìn thì thấy khá giống với các lớp kiểm thử của TestNG. Ngoài tên gọi @BeforeMethod đổi thành @Before và thuộc tính expectedExceptions của @Test đổi thành thuộc tính expected ra thì hoàn toàn không có gì khác nhau cả. Thậm chí, cả vai trò kiểm thử cũng giống hệt nhau.

Tuy nhiên, cho dù là chỉ dẫn @Test giống nhau đi chăng nữa thì cần phải lưu ý rằng các lớp chỉ dẫn Annotation ở JUnit4 và TestNG là khác nhau, điển hình như trong câu lệnh import.

Vậy tại sao chỉ dẫn Annotation của JUnit4 và TestNG lại giống nhau như vậy? Đơn giản đó là vì JUnit4 sinh sau đẻ muộn hơn so với TestNG nên chịu không ít ảnh hưởng của TestNG. Nói cách khác thì chúng ta có thể dễ dàng chuyển nhiều tính năng sang TestNG hơn so với JUnit4. Và, nếu chạy test này bằng JUnit4 sẽ cho ra kết quả như sau.

(※Các yêu cầu hệ thống và cài đặt môi trường cho JUnit, các bạn có thể tham khảo tại đây: http://junit.org/)

1.jpg

★Called contractor của JUnit 4Sample★
★★Called init()★★
★★★Called verifyAdd1()★★★
★Called contractor của JUnit 4Sample★
★★Called init()★★
★★★Call verifyAdd2()★★★
★Called contractor của JUnit 4Sample★
★★Called init()★★
★★Called exceptionTest()★★

Kết quả chạy kiểm thử

Đến đây thì chỉ cần nhìn bằng mắt, các bạn cũng có thể thấy một điểm khác nhau khá lớn trong kết quả chạy kiểm thử giữa JUnit4 và TestNG rồi phải không?

TestNG thì chỉ gọi contractor một lần còn JUnit4 phải gọi tới 3 lần. Đó chính là một trong những hạn chế của Junit, chỉ tạo 1 instance cho mỗi phương thức test. TestNG thì chỉ tạo một instance rồi chia sẻ trạng thái đó suốt trong quá trình kiểm thử.

(tobe continued...)

Refer Part 1: https://viblo.asia/tran.thi.kim.thuy/posts/N0bDM6N1M2X4

0