2012-06-22 18 views
16

Tôi đang sử dụng jUnit để quản lý kiểm tra tích hợp cho một ứng dụng truy cập cơ sở dữ liệu. Bởi vì thiết lập dữ liệu thử nghiệm là một hoạt động tốn thời gian, tôi đã làm điều đó trong phương thức @BeforeClass, được thực hiện chỉ một lần cho mỗi lớp thử nghiệm (trái với phương pháp @Before, được chạy một lần cho mỗi phương pháp thử nghiệm).Với jUnit 4, tôi có thể tham số hóa @BeforeClass không?

Bây giờ tôi muốn thử một vài hoán vị khác nhau cho cấu hình của lớp dữ liệu, chạy tất cả các thử nghiệm của tôi trên mỗi cấu hình khác nhau. Điều này có vẻ giống như việc sử dụng tự nhiên của Á hậu thử nghiệm Parameterized. Vấn đề là, Parameterized cung cấp tham số cho hàm tạo lớp và phương thức @BeforeClass trừu tượng và được gọi trước hàm tạo lớp.

Một vài câu hỏi,

Liệu Parameterized gọi phương pháp @BeforeClass cho mỗi hoán vị của các thông số, hay nó chỉ gọi một lần?

Nếu phương pháp @BeforeClass được gọi nhiều lần, có cách nào để truy cập các giá trị tham số từ bên trong không?

Nếu không có điều nào trong số này, những gì mọi người đề xuất là phương pháp thay thế tốt nhất cho vấn đề này?

+0

Xem liệu http://code.google.com/p/junitparams/ có thể giúp – Jayan

+0

Vì vậy, vẫn không có cách nào để thực hiện việc này? –

+1

Hiệu ứng có thể được thực hiện bởi một Á hậu thử nghiệm tùy chỉnh. Thông thường bạn sẽ phân lớp BlockJUnit4ClassRunner. –

Trả lời

1

@BeforeClass chỉ được gọi một lần trong ví dụ của bạn. Điều đó có ý nghĩa với tên - trước khi đến lớp!

Nếu xét nghiệm của bạn đòi hỏi dữ liệu khác nhau, có hai sự lựa chọn tôi có thể nghĩ:

  1. Thiết lập dữ liệu đó trong @Before vì thế nó là thử nghiệm cụ thể
  2. Tập đoàn kiểm tra mà bạn muốn chạy với cùng một dữ liệu vào các lớp thử nghiệm riêng biệt và sử dụng @BeforeClass cho mỗi lớp.
+1

Cảm ơn bạn đã làm rõ sự hiểu biết của tôi về @ BeforeClass.Rất tiếc, hai cách tiếp cận mà bạn phác thảo không giải quyết được vấn đề lớn hơn của tôi. Vấn đề với phương pháp tiếp cận 1 là tôi có khởi tạo một lần chi phí cao thay đổi từ một kịch bản sang kịch bản kế tiếp, nhưng tôi không muốn phải lặp lại cho mỗi bài kiểm tra. Vấn đề với cách tiếp cận 2 là tôi sẽ phải viết một lớp thử nghiệm khác nhau cho mỗi kịch bản, mặc dù tôi đang chạy các thử nghiệm tương tự. –

+1

Dan, Đối với tùy chọn # 2, bạn có thể phân lớp. Có các "kiểm tra tương tự" trong lớp cha và sau đó mỗi phân lớp phản ánh kịch bản. Nói cách khác, các lớp con chỉ chứa @BeforeClass –

+0

Cách tiếp cận đó sẽ có hiệu quả về mặt kỹ thuật, nhưng tôi không thấy nó hấp dẫn, vì tôi đã có hàng tá lớp thử nghiệm và hy vọng cuối cùng sẽ có hàng trăm –

-1

Bạn có thể thực hiện khởi tạo của mình bằng phương thức @Trước, viết thành biến mẫu nhưng thử nghiệm cho giá trị rỗng.

@RunWith(value = Parameterized.class) 
public class BigThingTests { 
    private BigThing bigThing; 

    @Before 
    public void createBitThing() { 
    if (bigThing == null) { 
     bigThing = new BigThing(); 
    } 
    } 

... 
} 

Một ví dụ mới của BigThingTests được tạo ra cho mỗi bộ thông số, và bigThing được thiết lập để null với mỗi trường hợp mới. Á hậu Parameterized là đơn luồng, do đó bạn không phải lo lắng về nhiều lần khởi tạo.

+0

this.bigThing sẽ luôn rỗng, khi bạn có một phiên bản BigThingTests mới cho mỗi @Test. –

0

Bạn có thể gọi logic khởi tạo này trong hàm tạo của lớp thử nghiệm của bạn. Theo dõi tham số cuối cùng được sử dụng trong một biến tĩnh. Khi thay đổi, hãy thiết lập lớp cho tham số mới.

Tôi không thể nghĩ tương đương với AfterClass.

+1

Sử dụng hàm tạo thay vì '@ Before' không có tác dụng, vì Á hậu thử nghiệm JUnit 4 chuẩn tạo ra một thể hiện mới của lớp thử nghiệm cho mỗi phương thức thử nghiệm. Vì vậy, tôi vẫn sẽ có vấn đề rằng mã thiết lập tốn kém của tôi được gọi một lần cho mọi phương thức và hoán vị của peramters, thay vì chỉ một lần cho mỗi hoán vị các tham số. –

+0

Bắt tốt. Tôi đã cập nhật câu trả lời của mình (và các bài kiểm tra tôi đang làm việc với cùng một vấn đề). – TREE

3

Tôi nghĩ bạn sẽ cần một người chạy thử nghiệm tùy chỉnh. Tôi đang gặp vấn đề tương tự bạn đang gặp phải (cần phải chạy các thử nghiệm tương tự bằng cách sử dụng nhiều cấu hình đắt tiền). Bạn sẽ cần một cách để tham số hóa thiết lập, có thể sử dụng chú thích @Parameter tương tự như chú thích được sử dụng bởi nhân vật Parameterized runner nhưng trên các trường thành viên tĩnh thay vì các trường instance. Á hậu tùy chỉnh sẽ phải tìm tất cả các trường thành viên tĩnh với chú thích @Parameter và sau đó chạy lớp thử nghiệm (có thể sử dụng BlockJunit4ClassRunner cơ bản) một lần cho mỗi trường @Parameter tĩnh. Trường @Parameter có lẽ phải là @ClassRule.

Andy trên Phần mềm đã làm tốt công việc phát triển người chạy thử nghiệm tùy chỉnh và anh giải thích rõ ràng như vậy trong các bài đăng trên blog herehere.

+0

+1 cho @ClassRule hoạt động hoàn hảo mà không ảnh hưởng đến chức năng Tham số hoặc yêu cầu một nhân vật tùy chỉnh – bstoney

0

Đây là một câu hỏi cũ, nhưng tôi chỉ phải giải quyết một vấn đề tương tự. Tôi đã đi với các giải pháp dưới đây cho bây giờ, mà về cơ bản là một thực hiện câu trả lời của TREE (cập nhật) với việc sử dụng một lớp cơ sở trừu tượng chung để tránh trùng lặp bất cứ khi nào bạn cần cơ chế này.

Kiểm tra cụ thể sẽ cung cấp phương thức @Parameters trả về một mảng các phần tử đơn lẻ có thể chứa mỗi Nhà cung cấp < T>. Các nhà cung cấp sau đó được thực hiện chính xác một lần cho mỗi đầu vào thực tế cần thiết bởi các phương pháp thử nghiệm cụ thể.

@RunWith(Parameterized.class) 
public class AbstractBufferedInputTest<T> { 

private static Object INPUT_BUFFER; 

private static Object PROVIDER_OF_BUFFERED_INPUT; 

private T currentInput; 

@SuppressWarnings("unchecked") 
public AbstractBufferedInputTest(Supplier<T> inputSuppler) { 
    if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) { 
     INPUT_BUFFER = inputSuppler.get(); 
     PROVIDER_OF_BUFFERED_INPUT = inputSuppler; 
    } 
    currentInput = (T) INPUT_BUFFER; 
} 

/** 
* 
* @return the input to be used by test methods 
*/ 
public T getCurrentInput() { 
    return currentInput; 
} 

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