Thông thường một class test sẽ sử dụng để test cho một chức năng, một unit. Nếu chúng ta có một vài test class, và mong muốn có thể kết hợp chúng thành một nhóm/ bộ kiểm tra. Chúng ta có thể làm được điều này bằng cách sử dụng Test Suite hoặc Categories Test.
JUnit Test Suite Class
Test Suite sẽ thực thi tất cả các class test trong test suite theo thứ tự được chỉ định. Một Test Suite cũng có thể chứa các Test Suite khác.
Để sử dụng Test Suite, chúng ta sẽ đánh dấu một annotation @RunWith và @SuiteClasses ở mức class. Chẳng hạn @RunWith(Suite.class) và @SuiteClasses(TestClass1.class, …). Khi chạy lớp này, nó sẽ chạy tất cả các test method trong tất cả các test class được chỉ định.
Ví dụ @Suite Test
Giả sử chúng ta có các test class sau:
public class Test1 { @Test public void test1() { assertTrue(true); } } public class Test2 { @Test public void test2() { assertTrue(true); } } public class Test3 { @Test public void test3() { assertTrue(true); } } public class Test4 { @Test public void test4() { assertTrue(true); } }
Tạo bộ TestSuite1 gồm 2 class test là Test1.java và Test2.java
package com.gpcoder.junit.suite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ Test1.class, Test2.class }) public class TestSuite1 { // the class remains empty, used only as a holder for the above annotations }
Chạy TestSuite1, chúng ta có kết quả sau:
Như bạn thấy, chúng ta chỉ chạy TestSuite1, nhưng tất cả các phương thức trong Test1, và Test2 đều được chay, rất đơn giản và tiện lợi.
Bây giờ chúng ta sẽ thử với trường hợp tạo một TestSuite chứa các TestSuite khác. Chẳng hạn, tạo bộ TestSuite2 gồm 2 class test là Test3.java và Test4.java
package com.gpcoder.junit.suite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ Test3.class, Test4.class }) public class TestSuite2 { // the class remains empty, used only as a holder for the above annotations }
Tạo bộ TestSuiteExample gồm 2 test suite là TestSuite1 và TestSuite2
package com.gpcoder.junit.suite; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ TestSuite1.class, TestSuite2.class }) public class TestSuiteExample { // the class remains empty, used only as a holder for the above annotations }
Chạy TestSuiteExample, chúng ta có kết quả sau:
Như bạn thấy, chúng ta chỉ chạy TestSuiteExample nhưng tất cả các class test trong TestSutie1 và TestSuite2 đều được thực thi.
JUnit Categories Test Class
JUnit Categories cho phép nhóm các phương thức test/ class test lại với nhau để chúng ta có thể chạy chúng trong các test suite khác nhau.
Từ một nhóm các test class, Categories runner chỉ chạy các lớp và phương thức được đánh dấu với @Category và được khai báo với @IncludeCategory. Chúng ta cũng có thể loại trừ các Categories bằng cách sử dụng chú thích @ExcludeCategory.
Sự khác biệt giữa Test Suite và Categories là: Test Suite chạy tất cả các phương thức được chỉ định trong class test (ngoại trừ được chỉ định Ignore), trong khi đó Categories cho phép chúng ta có thể đánh dấu trên từng phương thức và chỉ chạy với các phương thức được đánh dấu.
Để sử dụng một Categories chúng ta sẽ thực hiện theo các bước sau:
- Marker Interface: Tạo một class/ interface để đánh dấu.
- @Category : sử dụng annotation @Category để đánh dấu phân loại, có thể đánh dấu ở mức method hoặc mức class.
- Test Suite : tạo một test suite và đánh dấu annotation @Categories.IncludeCategory để thực thi tất cả các phương thức test có category được chỉ định hoặc @Categories.ExcludeCategory để thực thi tất cả các phương thức test không có category được chỉ định.
Ví dụ @Categories Test
Tạo Marker Interface: chúng ta sẽ tạo 2 marker là PerformanceTests và RegressionTests.
package com.gpcoder.junit.categories; /** * Category marker interface for performance test. */ public interface PerformanceTests { } /** * Category marker interface for regression test. */ public interface RegressionTests { } /** * Category marker interface for integration test (3rd test). */ public interface IntegrationTest { }
Tạo các Test class và đánh dấu @Category.
package com.gpcoder.junit.categories; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; public class ClassA { @Category(PerformanceTests.class) @Test public void test_A1() { Assert.assertTrue(true); } @Category({ PerformanceTests.class, RegressionTests.class }) @Test public void test_A2() { Assert.assertTrue(true); } @Test public void test_A3() { Assert.assertTrue(true); } } @Category({ PerformanceTests.class }) public class ClassB { @Test public void test_B1() { Assert.assertTrue(true); } @Test public void test_B2() { Assert.assertTrue(true); } } @Category({ PerformanceTests.class, RegressionTests.class }) public class ClassC { @Test public void test_C1() { Assert.assertTrue(true); } @Category(IntegrationTest.class) @Test public void test_C2() { Assert.assertTrue(true); } }
Tạo các Test Suite để kiểm tra:
Tạo Test Suite chỉ thực thi các phương thức hoặc class được đánh dấu với Categories PerformanceTests bằng cách sử dụng @Categories.IncludeCategory.
package com.gpcoder.junit.categories; import org.junit.experimental.categories.Categories; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Categories.class) @Categories.IncludeCategory(PerformanceTests.class) @Suite.SuiteClasses({ ClassA.class, ClassB.class, ClassC.class }) public class PerformanceTestSuite_IncludeCategoryExample { // the class remains empty, used only as a holder for the above annotations }
Kết quả class test trên:
Bây giờ chúng ta sẽ tạo một TestSuite khác chỉ thực thi các phương thức hoặc class KHÔNG được đánh dấu với Categories PerformanceTests bằng cách sử dụng @Categories.ExcludeCategory.
@RunWith(Categories.class) @Categories.ExcludeCategory({ RegressionTests.class }) @Suite.SuiteClasses({ ClassA.class, ClassB.class, ClassC.class }) public class PerformanceTestSuite_ExcludeCategoryExample { // the class remains empty, used only as a holder for the above annotations }
Kết quả class test trên:
Tạo Test Suite chỉ thực thi các phương thức hoặc class được đánh dấu với Categories RegressionTests bằng cách sử dụng @Categories.IncludeCategory và KHÔNG được đánh dấu với Categories IntegrationTest bằng cách sử dụng @Categories.ExcludeCategory.
package com.gpcoder.junit.categories; import org.junit.experimental.categories.Categories; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Categories.class) @Categories.IncludeCategory(RegressionTests.class) @Categories.ExcludeCategory(IntegrationTest.class) @Suite.SuiteClasses({ ClassA.class, ClassB.class, ClassC.class }) public class RegressionTestSuite { // the class remains empty, used only as a holder for the above annotations }
Kết quả class test trên:
Tài liệu tham khảo:
- https://github.com/junit-team/junit4/wiki/Aggregating-tests-in-suites
- https://github.com/junit-team/junit4/wiki/Categories