Tải bản đầy đủ (.doc) (24 trang)

Báo cáo: Junit công cụ Test Driven Development

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (412.65 KB, 24 trang )

MỤC LỤC
Trang
I.Giới thiệu đề tài…………………………………………………….3
I.1.Giải quyết vấn đề……………………………………………… 3
II.1 Cách thức giải quyết và trình bày vấn đề…………………… 3
II.1.1.Phân chia công việc…………………………………………3
II.1.2.Hình thức tìm hiểu………………………………………… 4
II.1.3.Hình thức báo cáo………………………………………… 4
II.2.Kết quả nghiên cứu…………………………………………… 4
II.2.1.xUnit framework? 4
II.2.2.Lịch sử phát triển Junit…………………………………… 5
II.2.3.Kiến trúc tổng quan…………………………………………5
II.2.4.Tại sao phải viết 1 test suit? ……………………………… 7
II.2.5.Các viết 1 TestCase…………………………………………7
II.2.6.Các phương thức Assert()………………………………… 9
II.2.7.Set Up và Tear Down……………………………………….11
II.2.8.Test các exception………………………….……………….14
II.2.8.1.Xây dựng một test exception………… ………………14
II.2.8.2.Kiểm tra sâu hơn các ngoại lệ………… …………….15
II.2.9.Junit trong Eclipse………………………………………… 16
II.2.9.1.Thêm thư viện Junit vào một project………………… 16
II.2.9.2.Viết một TestCase trong Eclipse………………………16
II.2.9.3.Chạy một testcase trong Eclipse…………………….20
II.2.10.Giới thiệu một số công cụ testing khác………………….21
1
II.2.10.1.Cactus………………………………………………21
II.2.10.2.HTTPUnit………………………………………… 21
II.2.10.3.Nunit……………………………………………… 22
III.Kết luận………………………………………………………… 23
III.1.Kết quả đề tài:……………………………………………… 23
III.2.Hướng nghiên cứu phát triển……………………………….23


IV.Tài liệu tham khảo…………………………………………….23
2
I.Giới thiệu đề tài
-Tên đề tài: ”Junit-công cụ Test-Driven-Development”
Giới thiệu tổng quát về Junit
JUnit là một framework đơn giản dùng cho việc tạo các unit testing tự động, và
chạy các test có thể lặp đi lặp lại. Nó chỉ là một phần của họ kiến trúc xUnit cho
việc tạo các unit testing. JUnit là một chuẩn trên thực tế cho unit testing trong
Java. JUnit về nguồn gốc được viết bởi 2 tác giả Erich Gamma và Kent Beck
JUnit có thể được tải xuống từ địa chỉ .
JUnit có những đặc điểm đáng lưu tâm như sau:
• Xác nhận (assert) việc kiểm tra kết quả được mong đợi
• Các Test Suite cho phép chúng ta dễ dàng tổ chức và chạy các test
• Hỗ trợ giao diện đồ họa và giao diện dòng lệnh
Các test case của JUnit là các lớp của Java, các lớp này bao gồm một hay nhiều
các phương thức unit testing, và những test này lại được nhóm thành các Test
Suite.
Mỗi phương thức test trong JUnit phải được thực thi nhanh chóng. Tốc độ là điều
tối quan trọng vì càng nhiều test được viết và tích hợp vào bên trong quá trình xây
dựng phần mềm, cần phải tốn nhiều thời gian hơn cho việc chạy toàn bộ Test
Suite. Các lập trình viên không muốn bị ngắt quãng trong một khoãng thời gian dài
trong khi các test chạy, vì thế các test mà chạy càng lâu thì sẽ có nhiều khả năng là
các lập trình viên sẽ bỏ qua bước cũng không kém phần quan trọng này.
Các test trong JUnit có thể là các test được chấp nhận hay thất bại, các test này
được thiết kế để khi chạy mà không cần có sự can thiệp của con người. Từ những
thiết kế như thế, bạn có thể thêm các bộ test vào quá trình tích hợp và xây dựng
phần mềm một cách liên tục và để cho các test chạy một cách tự động
II.Giải quyết vấn đề
II.1 Cách thức giải quyết và trình bày vấn đề
II.1.1.Phân chia công việc

3
Nguyễn Khánh Thiện
1.xUnit framework?
2.Lịch sử phát triển Junit
3.Kiến trúc tổng quan
4.Tại sao phải tạo 1 test suit?
Vũ Đức Luận:
5.Cách viết 1 Testcase
6.Các phương thức Assert
7.Set Up và Tear Down
Nguyễn Tiến Đạt:
8.Test Exception
9.Junit in Eclipse
10.Các công cụ Testing khác
Viết báo cáo: Vũ Đức Luận
II.1.2.Hình thức tìm hiểu
-Thao khảo các tài liệu trên các diễn đàn: testing.vn
-Thao khảo sách viết về Junit
-Xây dựng các demo mô tả các vấn đề đã trình bày
II.1.3.Hình thức báo cáo:
-Thuyết trình bằng slide: theo phân công cho 3 thành viên trong nhóm
-Viết báo cáo và nộp ngay sau khi thuyết trình
II.2.Kết quả nghiên cứu
II.2.1xUnit framework?
 Khi chúng ta phát triển một phần mềm nào đó thì giai đoạn kiểm thử
phần mềm là một trong những giai đoạn bắt buộc . Và một trong
những loại testing đó là Unit testing , nó liên quan đến việc kiểm tra
các đơn vị cơ bản của phần mềm . Những đoạn code của unit testing
hướng tới mục tiêu là các đơn vị đối tượng cụ thể nào đó , kiểm tra
đầu vào đầu ra , một chi tiết một thời điểm cụ thể .

 xUnit framework là họ kiến trúc xUnit framwork với những ngôn
ngữ lập trình và các nền tảng lập trình khác nhau . Hay nói cách khác
xUnit framework là họ của các unit testing frameworks với những
ngôn ngữ và các nền tảng lập trình khác nhau .
4
 Danh sách unit testing framework :
Java Junit framework .
ASP ASPUnit framework .
MATLAB mlunit framework .
Objective-C ObjcUnit framework .
PHP PHP Unit Testing Framework .
C++ CPUnit framework .
Shell ShUnit framework .
SQL SQLUnit framework
……
II.2.2.Lịch sử phát triển Junit
 JUnit là một framework đơn giản dùng cho việc tạo các unit testing tự động,
và chạy các test có thể lặp đi lặp lại. Nó chỉ là một phần của họ kiến trúc
xUnit cho việc tạo các unit testing. JUnit là một chuẩn trên thực tế cho unit
testing trong Java. JUnit về nguồn gốc được viết bởi 2 tác giả Erich Gamma
và Kent Beck.
 Vào giữa những năm 90 của thế kỷ 20 , Kent Beck đã phát triển một bộ
test xUnit đầu tiên cho Smalltalk .
 Beck và Gamma phát triển JUnit trên một chuyến bay từ Zurich đến
Washington, DC.
 Từ đó Junit trở thành công cụ chuẩn cho Test-Driven Development trong
Java .
 Ngày nay , jUnit được tích hợp sẵn trong các Java IDEs (Eclipse, BlueJ,
Jbuilder, DrJava) .
 Ngày nay , jUnit được tích hợp sẵn trong các Java IDEs (Eclipse, BlueJ,

Jbuilder, DrJava) .
II.2.3.Kiến trúc tổng quan
5
• JUnit test framework cung cấp cho chúng ta các gói lớp có sẵn cho
phép chúng ta viết các phương thức test một cách dễ dàng .
• TestRunner sẽ chạy các test và trả về kết quả là các Test Results
• Các lớp của chương trình test chúng ta sẽ được kế thừa các lớp trừu
tượng TestCase .
• Khi viết các Test Case chúng ta cần biết và hiểu lớp
Assert class .
• Một số định nghĩa trong mô hình tổng quát :
 Test case : test case định nghĩa môi trường mà nó có thể sử
dụng để chạy nhiều test khác nhau
 TestSuite : testsuite là chạy một tập các test case và nó cũng có
thể bao gồm nhiều test suite khác . test suite chính là tổ hợp các
test .
II.2.4.Tại sao phải tạo 1 test suit?
6
 Hiển nhiên là bạn phải kiểm tra xem đoạn code của bạn có đúng hay
không ?
o Bạn có thể xây dựng một bộ kiểm thử bao gồm nhiều các test
khác nhau có thể chạy trong bất cứ thời gian nào .
 Nhược điểm của việc viết 1 test suite :
o Đó là rất nhiều chương trình được lập trình thêm .
 Đúng , nhưng chúng ta có thể sử dụng những framework
có sẵn giúp chúng ta giảm bớt trong quá trình lập trình .
o Có nhiều ý kiến cho rằng đó là công việc không cần thiết tốn
thời gian , không có thời gian làm những công việc thêm đó .
 Đó là ý kiến sai lầm , Những thực nghiệm chỉ ra rằng
những test suites sẽ giảm thời gian sửa lỗi nhiều hơn thời

gian dành cho việc xây dựng những test suites đó .
 Lợi ích của việc viết 1 test suite .
o Làm giảm tổng số lỗi trong quá trình code .
o Làm cho dòng code của bạn trở lên dễ bảo trì và tái sử dụng
hơn .
II.2.5.Cách viết 1 TestCase
Bạn muốn viết các unit test với JUnit. Việc đầu tiên bạn phải tạo một lớp con thừa
kế từ lớp junit.framework.TestCase. Mỗi unit test được đại diện bởi một phương
thức testXXX() bên trong lớp con của lớp TestCase.
Ta có một lớp Person như sau:
1. public class Person {
2. private String firstName;
3. private String lastName;
4. public Person(String firstName, String lastName) {
5. if (firstName == null && lastName == null) {
6. throw new IllegalArgumentException("Both names cannot be null");
7. }
8. this.firstName = firstName;
9. this.lastName = lastName;
10. }
11. public String getFullName() {
12. String first = (this.firstName != null) ? this.firstName : "?";
13. String last = (this.lastName != null) ? this.lastName : "?";
7
14. return first + last;
15. }
16. public String getFirstName() {
17. return this.firstName;
18. }
19. public String getLastName() {

20. return this.lastName;
21. }
22. }
Sau đó ta sẽ viết một test case đơn giản để test một số phương thức của lớp trên
1. import junit.framework.TestCase;
2. public class TestPerson extends TestCase {
3. public TestPerson(String name) {
4. super(name);
5. }
6. /**
7. * Xac nhan rang name duoc the hien dung dinh dang
8. */
9. public void testGetFullName() {
10. Person p = new Person("Aidan", "Burke");
11. assertEquals("Aidan Burke", p.getFullName());
12. }
13. /**
14. * Xac nhan rang nulls da duoc xu ly chinh xac
15. */
16. public void testNullsInName() {
17. Person p = new Person(null, "Burke");
18. assertEquals("? Burke", p.getFullName());
19. p = new Person("Tanner", null);
20. assertEquals("Tanner ?", p.getFullName());
21. }
22. }
8
Lưu ý: mỗi unit test là một phương thức public và không có tham số, được bắt đầu
bằng tiếp đầu ngữ test. Nếu bạn không tuân theo quy tắc đặt tên này thì JUnit sẽ
không xác định được các phương thức test một các tự động.

Để biên dịch TestPerson, chúng ta phải khai báo gói thư viện junit trong biến
đường môi trường classpath
set classpath=%classpath%;.;junit.jar
javac TestPerson
Để chạy một JUnit TestCase, ta có 2 cách
• Chạy với môi trường text, các bạn gõ lệnh
java junit.textui.TestRunner TestPerson
• Chạy với môi trường đồ họa
java junit.swingui.TestRunner TestPerson
Chúng ta có thể chạy trực tiếp các TestCase mà không muốn kích hoạt một trong
các test runner của JUnit. Chúng ta sẽ thêm phương thức main() vào test case. Ví
dụ:
1. public class TestGame extends TestCase {
2. …
3. public static void main(String [args) {
4. junit.textui.TestRunner.run(new TestSuite(TestGame.class))
5. }
6. }
II.2.6.Các phương thức Assert()
Các phương thức assertXXX() được dùng để kiểm tra các điều kiện khác
nhau.junit.framework.TestCase, lớp cha cho tất cả các test case, thừa kế từ lớp
junit.framework.Assert. Lớp này định nghĩa khá nhiều các phương
thức assertXXX(). Các phương thức test hoạt động bằng cách gọi những phương
thức này.
Sau đây là mô tả các phương thức assertXXX() khác nhau có trong lớp
junit.framework.Assert.
9

assertEquals(): So sánh 2 giá trị để kiểm tra bằng nhau. Test sẽ được chấp
nhận nếu các giá trị bằng nhau


assertFalse(): Đánh giá biểu thức luận lý. Test sẽ được chấp nhận nếu biểu
thức sai

assertNotNull(): So sánh tham chiếu của một đối tượng với null. Test sẽ
được chấp nhận nếu tham chiếu đối tượng khác null

assertNotSame(): So sánh địa chỉ vùng nhớ của 2 tham chiếu đối tượng
bằng cách sử dụng toán tử ==. Test sẽ được chấp nhận nếu cả 2 đều tham
chiếu đến các đối tượng khác nhau

assertNull(): So sánh tham chiếu của một đối tượng với giá trị null. Test sẽ
được chấp nhận nếu tham chiếu là null

assertSame(): So sánh địa chỉ vùng nhớ của 2 t


ham chiếu đối tượng bằng cách sử dụng toán tử ==. Test sẽ được chấp nhận
nếu cả 2 đều tham chiếu đến cùng một đối tượng

assertTrue(): Đánh giá một biểu thức luận lý. Test sẽ được chấp nhận nếu
biểu thức đúng

fail(): Phương thức này làm cho test hiện hành thất bại, phương thức này
thường được sử dụng khi xử lý các biệt lệ
Mặc dù bạn có thể chỉ cần sử dụng phương thức assertTrue() cho gần như hầu hết
các test, tuy nhiên thì việc sử dụng một trong các phương thức assertXXX() cụ thể
sẽ làm cho các test của bạn dễ hiểu hơn và cung cấp các thông điệp thất bại rõ ràng
hơn.
Tất cả các phương thức của bảng trên đều nhận vào một String không bắt buộc làm

tham số đầu tiên. Khi được xác định, tham số này cung cấp một thông điệp mô tả
test thất bại.
Ví dụ:
1. assertEquals(employeeA, employeeB);
2. assertEquals(“Employees should be equal after the clone() operation.”, employeeA
, employeeB).
Phiên bản thứ 2 được ưa thích hơn vì nó mô tả tại sao test thất bại, điều này sẽ giúp
cho việc sửa lỗi được dễ dàng hơn
Thế nào là một unit test tốt?
10
Mỗi unit test chỉ nên kiểm tra phần cụ thể của một chức năng nào đó. Chúng ta
không nên kết hợp nhiều test không liên quan với nhau lại vào trong một phương
thức testXXX()
Ta có một lớp Game như sau
1. public class Game {
2. private Map ships = new HashMap();
3. public Game() throws BadGameException {
4. }
5. public void shutdown() {
6. // dummy method
7. }
8. public synchronized Ship createFighter(String fighterId) {
9. Ship s = (Ship) this.ships.get(fighterId);
10. if (s == null) {
11. s = new Ship(fighterId);
12. this.ships.put(fighterId, s);
13. }
14. return s;
15. }
16. public boolean isPlaying() {

17. return false;
18. }
19. }
20. public class BadGameException extends Exception {
21. public BadGameException(String s) {
22. super(s);
23. }
24. }
Sau đó ta viết một đoạn test sau đây:
1. public void testGame() throws BadGameException{
2. Game game = new Game();
3. Ship fighter = game.createFighter(“001”);
4. assertEquals("Fighter did not have the correct identifier", "001", this.fighter.
getId());
11
5. Ship fighter2 = this.game.createFighter("001");
6. assertSame("createFighter with same id should return same object", fighter, figh
ter2);
7. assertTrue("A new game should not be started yet", !this.game.isPlaying());
8. }
Đây là một thiết kế không tốt vì mỗi phương thức assertXXX() đang kiểm tra phần
không liên quan của chức năng. Nếu phương thức assertEquals() thất bại, phần
còn lại của test sẽ không được thi hành. Khi xảy ra điều này thì chúng ta sẽ không
biết các test khác có đúng chức năng hay không
Tiếp theo chúng ta sẽ sửa test trên lại để kiểm tra các khía cạnh khác nhau của trò
chơi một cách độc lập.
1. public void testCreateFighter() {
2. System.out.println("Begin testCreateFigher()");
3. assertEquals("Fighter did not have the correct identifier", "001", this.fighter.
getId());

4. System.out.println("End testCreateFighter()");
5. }
6. public void testSameFighters() {
7. System.out.println("Begin testSameFighters()");
8. Ship fighter2 = this.game.createFighter("001");
9. assertSame("createFighter with same id should return same object", this.fighter,
fighter2);
10. System.out.println("End testSameFighters()");
11. }
12. public void testGameInitialState() {
13. System.out.println("Begin testGameInitialState()");
14. assertTrue("A new game should not be started yet", !this.game.isPlaying());
15. System.out.println("End testGameInitialState()");
16. }
Với cách tiếp cận này, khi một test thất bại sẽ không làm cho các mệnh
đề assertXXX() còn lại bị bỏ qua.
Có thể bạn sẽ đặt ra câu hỏi có khi nào một phương thức test chứa nhiều hơn một
các phương thứcassertXXX() hay không? Câu trả lời là có. Nếu bạn cần kiểm tra
một dãy các điều kiện và các test theo sau sẽ luôn thất bại nếu có một test đầu tiên
thất bại, khi đó bạn có thể kết hợp nhiều phương thức assert vào trong một test
12
II.2.7.Set Up và Tear Down
Hai phương thức setUp() và tearDown() là một phần của
lớp junit.framework.TestCase Bằng cách sử dụng các phương
thức setUp và tearDown. Khi sử dụng 2 phương thức setUp() và tearDown() sẽ
giúp chúng ta tránh được việc trùng mã khi nhiều test cùng chia sẻ nhau ở phần
khởi tạo và dọn dẹp các biến.
JUnit tuân thủ theo một dãy có thứ tự các sự kiện khi chạy các test. Đầu tiên, nó
tạo ra một thể hiện mới của test case ứng với mỗi phương thức test. Từ đó, nếu bạn
có 5 phương thức test thì JUnit sẽ tạo ra 5 thể hiện của test case. Vì lý do đó, các

biến thể hiện không thể được sử dụng để chia sẻ trạng thái giữa các phương thức
test. Sau khi tạo xong tất cả các đối tượng test case, JUnit tuân theo các bước sau
cho mỗi phương thức test:
• Gọi phương thức setUp() của test case
• Gọi phương thức test
• Gọi phương thức tearDown() của test case
Quá trình này được lặp lại đối với mỗi phương thức test trong test case.
Sau đây chúng ta sẽ xem xét ví dụ
1. public class Ship {
2. private String id;
3. public Ship(String id) {
4. this.id = id;
5. }
6. public String getId() {
7. return this.id;
8. }
9. }
10. public class TestGame extends TestCase {
11. private Game game;
12. private Ship fighter;
13. public void setUp() throws BadGameException {
14. this.game = new Game();
15. this.fighter = this.game.createFighter("001");
16. }
13
17. public void tearDown() {
18. this.game.shutdown();
19. }
20. public void testCreateFighter() {
21. System.out.println("Begin testCreateFigher()");

22. assertEquals("Fighter did not have the correct identifier",
23. "001", this.fighter.getId());
24. System.out.println("End testCreateFighter()");
25. }
26. public void testSameFighters() {
27. System.out.println("Begin testSameFighters()");
28. Ship fighter2 = this.game.createFighter("001");
29. assertSame("createFighter with same id should return same object",
30. this.fighter, fighter2);
31. System.out.println("End testSameFighters()");
32. }
33. public void testGameInitialState() {
34. System.out.println("Begin testGameInitialState()");
35. assertTrue("A new game should not be started yet",
36. !this.game.isPlaying());
37. System.out.println("End testGameInitialState()");
38. }
39. }
Thông thường bạn có thể bỏ qua phương thức tearDown() vì mỗi unit test riêng
không phải là những tiến trình chạy tốn nhiều thời gian, và các đối tượng được thu
dọn khi JVM thoát. tearDown() có thể được sử dụng khi test của bạn thực hiện
những thao tác như mở kết nối đến cơ sở dữ liệu hay sử dụng các loại tài nguyên
khác của hệ thống và bạn cần phải dọn dẹp ngay lập tức. Nếu bạn chạy một bộ bao
gồm một số lượng lớn các unit test, thì khi bạn trỏ tham chiếu của các đối tượng
đến null bên trong thân phương thức tearDown() sẽ giúp cho bộ dọn rác lấy lại bộ
nhớ khi các test khác chạy
Đôi khi bạn muốn chạy vài đoạn mã khởi tạo chỉ một lần, sau đó chạy các phương
thức test, và bạn chỉ muốn chạy các đoạn mã dọn dẹp chỉ sau khi tất cả test kết
thúc. Ở phần trên, JUnit gọi phương thứcsetUp() trước mỗi test và
14

gọi tearDown() sau khi mỗi test kết thúc, vì thế để làm được điều như trên, chúng
ta sẽ sử dụng lớp junit.extension.TestSetup để đạt được yêu cầu trên.
Ví dụ sau sẽ minh họa việc sử dụng lớp trên
1. import junit.extensions.TestSetup;
2. import junit.framework.*;
3. public class TestPerson extends TestCase {
4. public TestPerson(String name) {
5. super(name);
6. }
7. public void testGetFullName() {
8. Person p = new Person("Aidan", "Burke");
9. assertEquals("Aidan Burke", p.getFullName());
10. }
11. public void testNullsInName() {
12. Person p = new Person(null, "Burke");
13. assertEquals("? Burke", p.getFullName());
14. p = new Person("Tanner", null);
15. assertEquals("Tanner ?", p.getFullName());
16. }
17. public static Test suite() {
18. TestSetup setup = new TestSetup(new TestSuite(TestPerson.class)) {
19. protected void setUp() throws Exception {
20. //Thực hiện các đoạn mã khởi tạo một lần ở đây
21. }
22. protected void tearDown() throws Exception {
23. //Thực hiện các đoạn mã dọn dẹp ở đây
24. }
25. };
26. return setup;
27. }

28. }
TestSetup là một lớp thừa kế từ lớp junit.extension.TestDecorator,
Lớp TestDecorator là lớp cơ sở cho việc định nghĩa các test biến thể. Lý do chính
để mở rộng TestDecorator là để có được khả năng thực thi đoạn mã trước và sau
15
khi một test chạy. Các phương thức setUp() và tearDown() của
lớp TestSetupđược gọi trước và sau khi bất kỳ Test nào được truyền vào
constructor,
Trong ví dụ trên chúng ta đã truyền một tham số có kiểu TestSuite vào constructor
của lớp TestSetup
1. TestSetup setup = new TestSetup(new TestSuite(TestPerson.class)) {
Điều này có nghĩa là 2 phương thức setUp() được gọi chỉ một lần trước toàn bộ bộ
test và tearDown() được gọi chỉ một lần sau khi các test trong bộ test kết thúc.
Chú ý: các phương thức setUp() và tearDown() bên trong lớp TestPerson vẫn
được thực thi trước và sau mỗi phương thức test bên trong lớp TestPerson.
II.2.8.Test các exception
II.2.8.1.Xây dựng một test exception
Xác minh code hoàn thành một cách bình thường rất quan trọng nhưng đảm
bảo code có thể chạy như mong đợi trong các trường hợp đặc biệt còn quan
trọng hơn. Ví dụ:
public void division () {
int i = 1/0;
}
Nếu chạy đơn thuần thì code sẽ phát sinh lỗi ArithmeticException. Vấn đề
đặt ra là làm thế nào để bạn xác nhận code ném ra một ngoại lệ như mong
đợi?
Junit cung cấp test Exception để code có thể ném ra những ngoại lệ mong
đợi và chạy bình thường.Các @test có thêm một tham số tùy chọn
“expected” có giá trị như các lớp con của Throwable.
Ở đây, nếu muốn xác minh phương thức division() ném ngoại lệ đúng, code

sẽ được viết lại:
@Test(expected = ArithmeticException.class)
public void testdivisionWithException(){
16
int i = 1/0;
}
Các tham số dự kiến nên sử dụng cẩn thận vì các thử nghiệm bất kỳ đều sẽ
vượt qua nếu trong phương thức ném ra ArithmeticException. Trong những
test dài hơn, thì nên sử dụng ExpectedException rule (được mô tả dưới đây)
II.2.8.2.Kiểm tra sâu hơn các ngoại lệ
Các phương pháp trên là hữu ích cho các trường hợp đơn giản, nhưng nó
có giới hạn của nó. Ví dụ, bạn không thể kiểm tra giá trị của tin nhắn trong
trường hợp ngoại lệ, hoặc trạng thái của một đối tượng tên miền sau khi các
ngoại lệ đã được ném.
* Try/ Catch
Để giải quyết điều này, có thể sử dụng try/catch rất phổ biến trong Junit 3.x
@Test
public void testExceptionMessage() {
try {
int i = 1/0;
fail("Expected an ArithmeticException to be thrown");
} catch (ArithmeticException ame) {
assertThat(ame.getMessage(), is("/ by zero"));
}
}
* ExpectedException Rule
Ngoài ra, có thể sử dụng ExpectedException Rule. Quy tắc này cho phép
bạn chỉ ra không chỉ những gì ngoại trừ bạn đang mong đợi, nhưng cũng tin
nhắn ngoại lệ bạn đang mong đợi:
@Rule

public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws ArithmeticException {
17
thrown.expect(ArithmeticException.class);
thrown.expectMessage("/ by zero");
int i =1/0;
}
II.2.9.Junit trong Eclipse
II.2.9.1.Thêm thư viện Junit vào một project
- Download thư viện mới nhất từ trang chủ www.junit.org/
- Vào Properties -> Java Build Path -> Add External JARs
- Chọn đến file Jar vừa down về
II.2.9.2.Viết một TestCase trong Eclipse
Giả sử bạn có một project trong đó có file Triangle.java và chúng ta cần
viết Test cho chương trình này .Thực hiện tuần tự các bước sau
- Mở New wizard (File -> New -> JUnit Test Case)
- Ta sẽ được giao diện sau
18
- Nhấn Next
19
- Nhấn Finish
Cấu trúc của Project của chúng ta giờ như sau:
- Chúng ta có thể viết các ca kiểm thử trong file Triangle_Test.java
II.2.9.3.Chạy một testcase trong Eclipse
- Để chạy TestFailure nhấn nút chạy trong thanh công cụ. Nó sẽ tự
động chạy như JUnit Test. Bạn có thể kiểm tra kết quả thử nghiệm
trong giao diện JUnit. Giao diện này cho bạn thấy chạy thử nghiệm
tiến bộ và tình trạng:
20

21
II.2.10.Giới thiệu một số công cụ testing khác
II.2.10.1.Cactus
Cactus là một framework unit testing nguồn mở dùng để test cho các đoạn mã
phía bên server của Java. Đặc biệt là Cactus cho phép bạn test Servlet, JSP, và
Servlet filter. Cactus thừa kế từ JUnit để cung cấp 3 lớp con của lớp
junit.framework.TestCase là các lớp:
• org.apache.cactus.ServletTestCase
• org.apache.cactus.JspTestCase
• org.apache.cactus.FilterTestCase
Mỗi test case của Cactus cung cấp 1 chức năng đặc biệt. Cactus test thực thi
trên cả client và server. Khi sử dụng Cactus bạn chỉ cần tạo một lớp thừa kế từ 1
trong 3 lớp trên. Sau đó Cactus sẽ tạo ra và chạy 2 thể hiện của test case. Một
chạy trên JVM ở phía client, cái còn lại chạy bên trong JVM của môi trường
chạy servlet (servlet container) phía server. Bên client phía client cho phép
HTTP headers và các tham số HTTP được thêm vào các yêu cầu đi ra. Bên phía
server gọi thực thi các phương thức bên trong servlet của bạn để thực hiện bất
kỳ xác nhận nào, và sau đó sẽ gởi phản hồi ngược trở lại cho phía client. Tíếp
đến bên phía client xác nhận phản hồi từ bên server gởi về có chứa thông tin
mong muốn hay không.
II.2.10.2. HTTPUnit
HttpUnit là một thư viện nguồn mở của Java được dùng để tương tác với các
server HTTP. Với HttpUnit, chương trình Java của bạn có thể truy xuất trực tiếp
đến server mà không cần thiết phải sử dụng đến trình duyệt.
HttpUnit cung cấp các API để phân tích HTML, nhận thông tin của biểu mẫu
trang web, theo dõi các siêu liên kết, thiết lập cookie và thực hiện các tác vụ
khác có liên quan đến trình duyệt web.
Ngoài ra nó cũng gồm cả một thư viện để thao tác trực tiếp đến servlet, đôi khi
không cần thiết phải khởi động web server
22

Thông thường chúng ta sử dụng kết hợp HttpUnit và JUnit để viết các test.
JUnit định nghĩa các framework dùng để kiểm tra, và các phương thức
testXXX() của bạn sẽ sử dụng các hàm API của thư viện HttpUnit để truy cập
và kiểm tra trang web.
II.2.10.3.NUnit
NUnit là một framework dành cho việc testing unit trong tất cả các ngôn ngữ
.NET. Khởi đầu nó cũng được bắt đầu từ JUnit, nó là một công cụ hỗ trợ việc unit
testing cho Microsoft.NET. Nó được viết hoàn toàn bằng C#.
III.Kết luận
III.1.Kết quả đề tài:
-Tìm hiểu được các kiến thức cơ bản về Jnit:thuộc họ kiến trúc xUnit, lịch sử phát
triển, kiến trúc tổng quát, các vấn đề về tạo testcase, testsuit, các phương thức
trong 1 Junit…
-Demo ví dụ minh họa
-Các thành viên đã hiểu các kiến thức cơ bản và thực hiện ứng dụng vào các bài
toán thực tế
-Tổ chức Seminar trên lớp và nộp báo cáo
23
III.2.Hướng nghiên cứu phát triển
-Hướng nghiên cứu phát triển là tập trung vào các vấn đề khó và nâng cao
sau:
+Ajax testing
+Testing JSP Applications
+Testing OSGi components
+Testing database Access
+Testing JPA-based Applications
IV.Tài liệu tham khảo
 http:// www.testingvn.com/viewforum.php?f=72
 Junit in Action – Vicent Massol with Ted Husted
 http ://www.junit.org

 Download of JUnit
 Lots of information on using JUnit

 Information on Test-Driven Development
24

×