2008-12-08 39 views
23

Tôi muốn thực hiện một số thử nghiệm chức năng trên dịch vụ web (an toàn). Testuite chứa một loạt các trường hợp kiểm tra, mỗi trường hợp thực hiện một vài yêu cầu HTTP trên webservice.JUnit 4: Thiết lập mọi thứ trong một bộ thử trước khi chạy thử nghiệm (như phương pháp @BeforeClass của thử nghiệm, chỉ dành cho bộ thử nghiệm)

Đương nhiên, dịch vụ web phải chạy hoặc các thử nghiệm sẽ không thành công. :-)

Khởi động webservice mất vài phút (một số dữ liệu nặng), vì vậy tôi muốn bắt đầu nó càng ít càng tốt (ít nhất là tất cả các trường hợp thử nghiệm chỉ GET tài nguyên từ dịch vụ có thể chia sẻ một).

Vì vậy, có cách nào để thiết lập cho tôi bom trong bộ thử nghiệm không, trước khi thử nghiệm được chạy như trong phương thức @BeforeClass của một trường hợp thử nghiệm?

Trả lời

1

jUnit không thể làm điều đó - mặc dù TestNG có các chú thích @BeforeSuite@AfterSuite. Thông thường, bạn có được hệ thống xây dựng của bạn để làm điều đó. Trong maven, có các giai đoạn "thử nghiệm tích hợp trước" và "sau khi tích hợp bài kiểm tra". Trong ANT, bạn chỉ cần thêm các bước vào nhiệm vụ.

Câu hỏi của bạn là khá nhiều một số của Before and After Suite execution hook in jUnit 4.x, vì vậy tôi sẽ xem xét các đề xuất ở đó.

+0

Tại sao không BeforeSuite và AfterSuite làm việc? – guerda

-3

Là một sang một bên, đó là một ý tưởng tồi để có các bài kiểm tra đơn vị thực sự kêu gọi các nguồn lực bên ngoài như webservices, cơ sở dữ liệu, vv

Unit tests nên siêu nhanh để chạy và một sự chậm trễ của 'một vài phút cho mỗi lần chạy của bộ phần mềm sẽ có nghĩa là nó sẽ không chạy nhiều như nó cần.

Lời khuyên của tôi:

Nhìn vào chế giễu phụ thuộc bên ngoài trong các thử nghiệm đơn vị với một cái gì đó giống như EasyMock (http://www.easymock.org/).

Xây dựng một bộ thử nghiệm tích hợp riêng biệt với một cái gì đó như Fitnesse (http://fitnesse.org/) hoặc giải pháp phát triển trong nước chạy trên môi trường thử nghiệm và liên tục.

+0

hi nick, kiểm tra đơn vị của tôi không làm loại công cụ đó và là siêuquick. tôi đã nói về các bài kiểm tra chức năng :-) –

0

Một tùy chọn là sử dụng một cái gì đó như Apache Ant để khởi chạy bộ thử nghiệm đơn vị của bạn. Sau đó bạn có thể đặt một mục tiêu gọi trước và sau khi mục tiêu junit của bạn để bắt đầu và ngừng webservice của bạn:

<target name="start.webservice"><!-- starts the webservice... --></target> 
<target name="stop.webservice"><!-- stops the webservice... --></target> 
<target name="unit.test"><!-- just runs the tests... --></target> 

<target name="run.test.suite" 
     depends="start.webservice, unit.test, stop.webservice"/> 

Sau đó bạn chạy bộ bằng cách sử dụng kiến ​​(hay công cụ tích hợp của bạn lựa chọn). Hầu hết các IDE đều có hỗ trợ Ant, và nó giúp dễ dàng di chuyển các thử nghiệm của bạn vào một môi trường tích hợp liên tục (nhiều trong số đó sử dụng các đích Ant để xác định các thử nghiệm riêng của chúng).

21

Câu trả lời bây giờ là tạo một @ClassRule trong bộ phần mềm của bạn. Quy tắc sẽ được gọi trước hoặc sau (tùy thuộc vào cách bạn thực hiện nó) mỗi lớp thử nghiệm được chạy. Có một vài lớp cơ sở khác nhau mà bạn có thể mở rộng/triển khai. Điều gì là tốt đẹp về quy tắc lớp học là nếu bạn không thực hiện chúng như là các lớp vô danh thì bạn có thể tái sử dụng mã!

Đây là một bài viết về họ: http://java.dzone.com/articles/junit-49-class-and-suite-level-rules

Dưới đây là một số mẫu mã để minh họa việc sử dụng chúng. Có, nó là tầm thường, nhưng nó sẽ minh họa cho vòng đời đủ tốt để bạn bắt đầu.

Đầu tiên định nghĩa bộ:

import org.junit.*; 
import org.junit.rules.ExternalResource; 
import org.junit.runners.Suite; 
import org.junit.runner.RunWith; 


@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
    RuleTest.class, 
}) 
public class RuleSuite{ 

    private static int bCount = 0; 
    private static int aCount = 0; 

    @ClassRule 
    public static ExternalResource testRule = new ExternalResource(){ 
      @Override 
      protected void before() throws Throwable{ 
       System.err.println("before test class: " + ++bCount); 
       sss = "asdf"; 
      }; 

      @Override 
      protected void after(){ 
       System.err.println("after test class: " + ++aCount); 
      }; 
     }; 


    public static String sss; 
} 

Và bây giờ định nghĩa lớp thử nghiệm:

import static org.junit.Assert.*; 

import org.junit.ClassRule; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ExternalResource; 

public class RuleTest { 

    @Test 
    public void asdf1(){ 
     assertNotNull("A value should've been set by a rule.", RuleSuite.sss); 
    } 

    @Test 
    public void asdf2(){ 
     assertEquals("This value should be set by the rule.", "asdf", RuleSuite.sss); 
    } 
} 
+0

"Quy tắc sẽ được gọi trước hoặc sau (tùy thuộc vào cách bạn triển khai nó) mỗi lớp thử nghiệm chạy" - Tôi không thể xác nhận điều đó. Phương thức evaluate() của ClassRule của tôi chỉ được gọi một lần, mặc dù tôi đã thêm hai lớp Test vào bộ phần mềm. –

+0

Thật vậy, quy tắc sẽ được gọi trước hoặc sau khi lớp thử nghiệm chạy tùy thuộc vào việc triển khai nhất định. Trong ví dụ được cung cấp bởi ** @ ArtB **, quy tắc được triển khai ở cấp suite. Vì vậy, nó sẽ được gọi là một thời gian trước khi tất cả các bài kiểm tra trong bộ phần mềm được chạy và một thời gian sau khi tất cả các bài kiểm tra trong bộ phần mềm được chạy. Vì vậy, ** @ ArtB ** của câu trả lời hoạt động tốt. – flaz14

Các vấn đề liên quan