TestNGJUnit đều là các framework dùng trong kiểm thử, đặc biệt là kiểm thử đơn vị (unit testing) và na ná nhau. TestNG có thêm nhiều tính năng giúp nó mạnh hơn khi so sánh với JUnit. Bài viết này tập trung chủ yếu phân tích một vài đặc điểm của JUnit4 và TestNG, giúp developer và tester lựa chọn framework phù hợp cho công việc kiểm thử.

Bảng so sánh chức năng giữa TestNG và JUnit4. Hiện nay JUnit đã phát hành phiên bản JUnit4 vượt trội hơn so với các bản cũ, JUnit4 có khá nhiều tính năng giống TestNG.

alt

Annotation

Các annotations sử dụng trong TestNG và Junit hầu hết tương tự nhau. Ví dụ như TestNG dùng @BeforeMethod , @AfterMethod giống như cách mà Junit dùng @Before , @After .

STTTính năngTestNGJUnit
1Test annotation@Test@Test
2Chạy trước method test đầu tiên trong class hiện tại@BeforeClass@BeforeClass
3Chạy trước tất cả method test trong class hiện tại@AfterClass@AfterClass
4Chạy trước mỗi method test@BeforeMethod@Before
5Chạy sau mỗi method test@AfterMethod@After
6Bỏ qua test@Test(enbale=false)@ignore
7Bắt ngoại lệ@Test(expectedExceptions = ArithmeticException.class)@Test(expected = ArithmeticException.class)
8Timeout@Test(timeout = 1000)@Test(timeout = 1000)
9Chạy trước tất cả test trong suite@BeforeSuite-
10Chạy trước tất cả test trong suite@AfterSuite-
11Chạy trước các @Test@BeforeTest-
12Chạy sau các @Test@AfterTest-
13Chạy trước test method đầu tiên bất kỳ trong test group@BeforeGroups-
14Chạy sacu last method cuối cùng bất kỳ trong test group@AfterGroups-

Có 2 điểm cần chú ý là:

  1. Trong JUnit4, chúng ta phải khai báo @BeforeClass@AfterClass là các phương thức tĩnh (static method), đối với TestNG thì không cần làm điều này.
  2. TestNG cung cấp thêm 3 mức độ Before/AfterSuite, Before/AfterTest, Before/AfterGroup cho phép linh hoạt hơn khi chạy test.

Suite Test - Chạy bộ test

Suite được dùng khi chạy gộp nhiều test và có thể được tạo bằng 2 framework trên.

Dùng Junit

JUnit sử dụng @RunWith@Suite để chạy các suite. Ví dụ dưới đây dùng để nhóm "JunitTest1" và "JunitTest2" chạy đồng thời.

@RunWith(Suite.class)
@Suite.SuiteClasses({
        JunitTest1.class,
        JunitTest2.class
})
public class JunitTest5 {
}

Dùng TestNG

TestNG sử dụng file XML để định nghĩa "TestNGTest1" và "TestNGTest2" sẽ chạy cùng nhau

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="My test suite">
  <test name="testing">
    <classes>
       <class name="com.trangvt.TestNGTest1" />
       <class name="com.trangvt.TestNGTest2" />
    </classes>
  </test>
</suite>

Ngoài chạy test suite, chúng ta có thể định nghĩa group, cũng trong file XML, để nhóm các method test.

Ignore Test - Bỏ qua test

Dùng Junit

@Ignore
public void method1()
{
    System.out.println("Using @Ignore , this execution is ignored");
}

Dùng TestNG

@Test(enabled=false)
public void TestWithException()
{
    System.out.println("Method should be ignored as it's not ready yet");
}

Parameterized Test - Truyền tham số test

Dùng Junit

Sử dụng @RunWith@Parameter để truyền giá trị tham số cho test. @Parameter trả về một mảng List[], các tham số (parameter) được truyền dưới dạng đối số (argument) vào hàm khởi tạo lớp.

@RunWith(value = Parameterized.class)
public class JunitTest6 {

     private int number;

     public JunitTest6(int number) {
        this.number = number;
     }

     @Parameters
     public static Collection<Object[]> data() {
       Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
       return Arrays.asList(data);
     }

     @Test
     public void pushTest() {
       System.out.println("Parameterized Number is : " + number);
     }
}

Dùng TestNG

Trong TestNG, sử dụng file XML hoặc @DataProvider để ra hiệu rằng ta đang cung cấp tham số cho test.

public class Test1 {

    @Test
    @Parameters(value="number")
    public void parameterTest(int number)
    {
        System.out.println("Parameterized Number is : " + number);
    }

}

Ở đây @Parameters được định nghĩa trong method test. Data được lưu tại file XML như bên dưới, mỗi lần chạy test thì giá trị number sẽ được truyền vào hàm test và in ra kết quả. Bằng cách này, chúng ta có thể tái sử dụng một test case với các tập dữ liệu khác nhau và cho ra kết quả khác nhau.

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="My test suite">
<test name="testing">

<parameter name="number" value="2"/>

<classes>
<class name="com.guru99.Test1" />
</classes>
</test>
</suite>

Timeout

JUnit dùng từ khóa "timeout" để truyền thời gian đợi vào hàm test trong khi TestNG dùng "timeOut", đơn vị đều là miliseconds.

Exception Test
JUnit dùng từ khóa "expected" để truyền thời gian đợi vào hàm test trong khi TestNG dùng "expectedExceptions", đơn vị đều là miliseconds.

Dùng Junit

@Test(expected = ArithmeticException.class)  
public void divideByZero() 
{  
    Int i = 1/0;
}

Dùng TestNG

@Test(expectedExceptions = ArithmeticException.class)  
public void divideByZero()
{  
Int i = 1/0;
}   

Dependency Test

Tham số test chỉ ra các test chạy phụ thuộc lẫn nhau. Nếu một hàm test chạy bị lỗi thì các hàm test khác phụ thuộc nó sẽ bị bỏ qua khi chạy. TestNG sử dụng tham số mang tên "dependOnMethods" để cài đặt các test phụ thuộc, JUnit chưa hỗ trợ tính năng này.

@Test
public void method1() {
   System.out.println("This is method 1");
}

@Test(dependsOnMethods={"method1"})
public void method2() {
    System.out.println("This is method 2");
}

Hàm “method2()” sẽ được chạy khi và chỉ khi hàm “method1()” chạy ok, nếu không “method2()” bỏ qua.

Kết luận

Về cơ bản TestNG và JUnit khá là giống nhau, theo tôi bạn nên sử dụng TestNG testing framework cho dự án, vì TestNG cung cấp nhiều tính năng hỗ trợ mạnh mẽ như đưa tham số vào hàm test, dependency testing hoặc test theo suite. TestNG thích hợp cho kiểm thử ở mức độ trừu tượng (high-level) và kiểm thử tích hợp phức tạp. Ngoài ra, TestNG cũng bao gồm toàn bộ các chức năng cốt lõi Junit và nó có thể kết hợp với các framwork như Selenium hỗ trợ cho công việc kiểm thử được hoàn thiện hơn.

Tham khảo
TestNG
Compare JUnit & TestNG