Nội dung bài học

Annotation là tính năng giúp add thêm thông tin vào 1 object. Nó có thể được dùng cho class, method, variable, và parameters. TestNG cung cấp rất nhiều loại annotation cho các mục đích khác nhau, trong đó có các annotation phục vụ cho mục đích: xử lý trước và sau method Test. Vì sao cần xử lý trước và sau Test:

  • Cần tạo môi trường trước khi thực hiện test.
  • Cần xóa hết các trạng thái sau khi thực hiện test hoặc cần phải thực hiện các hành động không liên quan đến method Test nhưng cần thiết như screenshot, delete session hoặc close connection…

TestNG cung cấp 5 annotation ở dạng Before/After và 1 annotation dạng Test

  • @BeforeSuite/@AfterSuite
  • @BeforeTest/@AfterTest
  • @BeforeGroups/@AfterGroups
  • @BeforeClass/@AfterClass
  • @BeforeMethod/@AfterMethod


Chú thích (Annotation) trong TestNG

@BeforeSuite: Phương thức chú thích sẽ được chạy trước khi tất cả các kiểm tra trong bộ phần mềm này đã chạy.
@AfterSuite: Phương thức chú thích sẽ được chạy sau khi tất cả các kiểm tra trong bộ phần mềm này đã chạy.
@BeforeTest: Phương pháp chú thích sẽ được chạy trước khi bất kỳ phương pháp thử nào thuộc các lớp bên trong thẻ được chạy.
@AfterTest: Phương pháp chú thích sẽ được chạy sau khi tất cả các phương pháp thử nghiệm thuộc các lớp bên trong thẻ đã chạy.
@BeforeGroups: Danh sách các nhóm mà phương pháp cấu hình này sẽ chạy trước.
Phương pháp này được đảm bảo chạy ngay trước khi phương pháp thử đầu tiên thuộc bất kỳ nhóm nào được gọi ra.
@AfterGroups: Danh sách các nhóm mà phương pháp cấu hình này sẽ chạy sau.
Phương pháp này được đảm bảo chạy ngay sau khi phương pháp kiểm tra cuối cùng thuộc về bất kỳ nhóm nào được gọi ra.
@BeforeClass: Phương thức chú thích sẽ được chạy trước khi phương pháp thử đầu tiên trong lớp hiện tại được gọi.
@AfterClass: Phương thức chú thích sẽ được chạy sau khi tất cả các phương pháp kiểm tra trong lớp hiện tại đã được chạy.
@BeforeMethod: Phương pháp chú thích sẽ được chạy trước mỗi phương pháp thử.
@AfterMethod: Phương pháp chú thích sẽ được chạy sau mỗi phương pháp thử.
@Test: Phương pháp chú thích là một phần của một test case.


Lợi ích của việc sử dụng chú thích

  1. Nó xác định các phương pháp nó quan tâm bằng cách tìm kiếm các chú thích. Do đó tên phương thức không bị hạn chế trong bất kỳ mẫu hoặc định dạng nào.
  2. Chúng ta có thể truyền các thông số bổ sung cho các chú thích.
  3. Chú thích được đánh máy mạnh mẽ, do đó, trình biên dịch sẽ đánh dấu lỗi sai ngay lập tức.
  4. Các lớp kiểm tra không còn cần phải mở rộng bất cứ điều gì (như Test Case, cho JUnit 3).


I. Khai báo annotation trên 1 class

Thứ tự chạy của chúng sẽ được thể hiện qua ví dụ sau:

public class TestAnnotation {
     
    @BeforeSuite
    public void beforeSuite() {
        System.out.println("Before Suite");
    }

    @AfterSuite
    public void afterSuite() {
        System.out.println("After Suite");
    }

    @BeforeTest
    public void beforeTest() {
        System.out.println("Before Test");
    }

    @AfterTest
    public void afterTest() {
        System.out.println("After Test");
    }

    @BeforeClass
    public void beforeClass() {
        System.out.println("Before Class");
    }

    @AfterClass
    public void afterClass() {
        System.out.println("After Class");
    }

    @BeforeGroups(groups = { "testOne" })
    public void beforeGroupOne() {
        System.out.println("Before Group testOne");
    }

    @AfterGroups(groups = { "testOne" })
    public void afterGroupOne() {
        System.out.println("After Group testOne");
    }

    @BeforeGroups(groups = { "testTwo" })
    public void beforeGroupTwo() {
        System.out.println("Before Group testTwo");
    }

    @AfterGroups(groups = { "testTwo" })
    public void afterGroupTwo() {
        System.out.println("After Group testTwo");
    }

    @BeforeMethod
    public void beforeMethod() {
        System.out.println("Before Method");
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println("After Method");
    }

    @Test(groups = { "testOne" })
    public void testOneMethod() {
        System.out.println("Test method One");
    }

    @Test(groups = { "testTwo" })
    public void testTwoMethod() {
        System.out.println("Test method Two");
    }

}​

Và ta cần thêm 1 config cho file testng.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="First Suite" verbose="1">
    <test name="First Test">
        <classes>
            <class name="testannotation.TestAnnotation">
                <methods>
                    <include name="testOneMethod" />
                </methods>
            </class>
        </classes>
    </test>
    <test name="Second Test">
        <classes>
            <class name="testannotation.TestAnnotation">
                <methods>
                    <include name="testTwoMethod" />
                </methods>
            </class>
        </classes>
    </test>
</suite>​

Và đây là kết quả:

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester

Từ đây, ta có thể hiểu được thứ tự chạy chúng:

  • Khi bắt đầu thì mở từ Suite > Test > Group > Class > Method
  • Khi kết thúc thì đóng từ Method > Class > Group > Test > Suite


II. Khai báo annotation khi có kế thừa (Extends)

Ở phía trên, chúng ta đã xem về cách sử dụng annation trên 1 class, chúng ta sẽ băn khoăn là thế nhưng chúng ta viết theo dạng POM thì có cả BaseTest, không biết thứ tự run annotation sẽ như thế nào?

Hãy xem ví dụ dưới đây:

Ta có class BaseTest:

public class BaseTest {
     
    @BeforeClass
    public void beforeBaseClass() {
        System.out.println("Parent Before Class method");
    }

    @AfterClass
    public void afterBaseClass() {
        System.out.println("Parent After Class method");
    }

    @BeforeMethod
    public void beforeBaseMethod() {
        System.out.println("Parent Before method");
    }

    @AfterMethod
    public void afterBaseMethod() {
        System.out.println("Parent After method");
    }

}​

Class Test:

public class TestClass extends BaseTest {
     
    @BeforeClass
    public void beforeChildClass() {
        System.out.println("Child Before Class method");
    }

    @AfterClass
    public void afterChildClass() {
        System.out.println("Child After Class method");
    }

    @BeforeMethod
    public void beforeChildMethod() {
        System.out.println("Child Before method");
    }

    @AfterMethod
    public void afterChildMethod() {
        System.out.println("Child After method");
    }

    @Test
    public void testMethod() {
        System.out.println("Test method under TestClass");
    }

}​

Và file testng.xml:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Inheritance Suite" verbose="1">
    <test name="Inheritance Test">
        <classes>
            <class name="testannotation.TestClass" />
        </classes>
    </test>
</suite>​

Đây là kết quả:

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester

Thứ tự chạy khi có kế thừa (extends) sẽ là:

  • Khi bắt đầu: Parent Before > Child Before
  • Khi kết thúc: Child After > Parent After
Trong một project, không nhất thiết phải sử dụng hết tất cả các annotation này, nhưng ta cần phải biết thứ tự để từ đó điều khiển code của mình chạy theo thứ tự mình mong muốn, ví dụ như chụp screentshot hay screen video record ở cuối mỗi test, khởi tạo connection để đọc file Excel


III. Annotation @Test

Đây là annotation đánh dấu method hoặc Class là 1 phần của TestNG Test. Nếu nó được đánh dấu cho Class thì tất cả các Method mà Public thì sẽ được run, các Method không phải public sẽ không được run.

Ví dụ:

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester

IV. Các attribute của annotation @Test

  • alwaysRun: có giá trị mặc định là false, nó sẽ bị ignore nếu nó không có dependency method (phụ thuộc) . Nếu đặt là true thì Method sẽ được run kể cả khi các dependency method fail.
    VD: @Test(alwaysRun=true)
  • enabled: giá trị mặc định là true. Dùng để đánh dấu method run hoặc không run. Nếu false, method đó sẽ được bỏ qua, không run. Nếu true, method đó sẽ được run.
    VD: @Test(enabled=true)

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester
  • description: dùng để thêm thông tin cho test. Attribute này khá hiệu quả khi chúng ta muốn thêm mô tả các test case khi mà method Name không thể diễn tả được hết.
    VD: @Test(description=”Print the second test method”)

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester
  • expectedExceptions: dùng để xác định exception mà Method có thể gặp phải.
    VD:  @Test(expectedExceptions={IOException.class})
    [Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester
  • timeOut: xác định thời gian tối đa mà test có thể run, nếu thời gian run lớn hơn thời gian đã định sẵn thì kết quả test là fail. Đơn vị là mili giây.
    VD: @Test(timeOut=500)

[Selenium Java] Lesson 10: Cách sử dụng chú thích (Annotation) trong TestNG | Anh Tester
  • dataProvider: điền data vào cho test method, phục vụ cho data-driven testing (sẽ viết ở bài khác)
  • dataProviderClass: điền tên class mà TestNG sẽ tìm kiếm data-provider method được nhắc đến ở attribute dataProvider. Mặc định thì nó sẽ tìm ở chính class đó hoặc class base. 
  • dependsOnGroups: điền list các group mà test phụ thuộc.
  • dependsOnMethods: điền list các method mà test phụ thuộc. (sẽ viết ở bài khác)
  • groups: điền tên group, những test mà có chung tên group sẽ tạo thành 1 tập hợp. Tập hợp này có thể được run từ file testng.xml

NOTE:

  • Trong 1 @Test có thể áp dụng nhiều annotation cùng với nhau.
Ví dụ:
@Test(enabled=true, description="Anh Tester - Automation Testing")
public void TestMethod() {
    System.out.println("Anh Tester");
}​

Độ ưu tiên để chạy Test trong TestNG

package TestNG;
import org.testng.annotations.*;
public class SettingPriority {
 
@Test(priority=1)
public void method1() {
     System.out.println("Run method 1");
 }
 
@Test(priority=0)  //độ ưu tiên đầu tiên -> chạy method2() đầu tiên
public void method2() {
     System.out.println("Run method 2");
 }
 
@Test(priority=2)
public void method3() {
     System.out.println("Run method 3");
 }
}

Đoạn mã set độ ưu tiên sẽ được đặt trong annotation @Test , với cú pháp @Test(priority={expected_order}) (expected_order : 0 .... N , số càng nhỏ thì độ ưu tiên càng lớn). Trong ví dụ trên thì trình tự thực hiện sẽ là :

  • Method2
  • Method1
  • Method3

Cộng đồng Automation Testing Việt Nam:


🌱 Zalo
Automation Testing:   https://zalo.me/g/lsxswc560
🌱 Facebook Group: Cộng đồng Automation Testing Việt Nam (Website, Desktop, Mobile)
🌱 Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium

About the author

  • Anh Tester

    Đường dẫu khó chân vẫn cần bước đi
    Đời dẫu khổ tâm vẫn cần nghĩ thấu



Cộng đồng Automation Testing Việt Nam:


🌱 Zalo
Automation Testing:   https://zalo.me/g/lsxswc560
🌱 Facebook Group: Cộng đồng Automation Testing Việt Nam (Website, Desktop, Mobile)
🌱 Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium

Chia sẻ kiến thức lên trang

Bạn có thể đăng bài để chia sẻ kiến thức, bài viết của chính bạn lên trang Anh Tester Blog

Danh sách bài học