2009-09-02 29 views
7

Tôi hiện đang tái sử dụng các bài kiểm tra JUnit 4 từ một dự án khác chống lại mã của tôi. Tôi lấy chúng trực tiếp từ kho lưu trữ của dự án khác như là một phần của bản dựng Ant tự động của tôi. Điều này là tuyệt vời, vì nó đảm bảo tôi giữ mã màu xanh lá cây của tôi chống lại phiên bản mới nhất của các bài kiểm tra.Loại trừ các phương thức JUnit Test riêng lẻ mà không sửa đổi lớp Test?

Tuy nhiên, có một tập hợp con các bài kiểm tra mà tôi không bao giờ mong đợi để chuyển vào mã của mình. Nhưng nếu tôi bắt đầu thêm chú thích @Ignore vào các bài kiểm tra đó, tôi sẽ phải duy trì bản sao riêng của mình về việc thực hiện kiểm tra, mà tôi thực sự không muốn làm.

Có cách nào để loại trừ các thử nghiệm riêng lẻ mà không sửa đổi nguồn Kiểm tra không? Dưới đây là những gì tôi đã xem xét cho đến nay:

  • Theo như tôi thấy, nhiệm vụ Ant JUnit chỉ cho phép bạn loại trừ toàn bộ các lớp học thử nghiệm, chứ không phải phương pháp thử nghiệm cá nhân - vì vậy đó là không tốt đối với tôi, tôi cần phương thức chi tiết.

  • Tôi cân nhắc đặt cùng một TestSuite sử dụng phản chiếu để tìm và thêm tất cả các thử nghiệm ban đầu, sau đó thêm mã để loại bỏ rõ ràng các thử nghiệm mà tôi không muốn chạy. Nhưng tôi đã bỏ ý tưởng đó khi tôi nhận thấy rằng TestSuite API không cung cấp một phương pháp để loại bỏ các thử nghiệm.

  • Tôi có thể tạo các lớp thử nghiệm của riêng mình mở rộng các lớp Bài kiểm tra ban đầu, ghi đè các bài kiểm tra cụ thể mà tôi không muốn chạy và chú thích chúng bằng @Ignore. Sau đó tôi chạy JUnit trên các lớp con của mình. Nhược điểm ở đây là nếu các lớp Test mới được thêm vào dự án ban đầu, tôi sẽ không tự động chọn chúng. Tôi sẽ phải theo dõi các lớp Test mới khi chúng được thêm vào dự án gốc. Đây là lựa chọn tốt nhất của tôi cho đến nay, nhưng không cảm thấy lý tưởng.

  • Tùy chọn duy nhất khác mà tôi có thể nghĩ là chạy thử nghiệm kém và bỏ qua các lỗi. Tuy nhiên, các thử nghiệm này mất một thời gian để chạy (và thất bại!) Vì vậy tôi không muốn chạy chúng cả. Ngoài ra, tôi không thể thấy một cách để nói với nhiệm vụ Ant bỏ qua các lỗi trên các phương thức thử nghiệm cụ thể (một lần nữa - tôi thấy cách bạn có thể thực hiện nó cho các lớp Test riêng lẻ, nhưng không phải là các phương thức).

Trả lời

4

Nếu bạn không thể chạm vào thử nghiệm ban đầu, bạn sẽ có một số hạn chế nghiêm trọng. Ghi đè của bạn nghe giống như đặt cược tốt nhất, nhưng với một vài thay đổi:

Tạo các bài kiểm tra Ant cụ thể loại trừ các lớp siêu, để các lớp bổ sung mà bạn không biết về việc chạy.

Bạn có thể sử dụng chú thích @Rule (mới cho JUnit 4.7) để biết thử nghiệm đang được chạy và hủy bỏ nó (bằng cách trả về một khai báo trống) thay vì ghi đè các phương thức cụ thể, giúp bạn linh hoạt hơn trong việc biết có hay không để tránh thử nghiệm. Vấn đề duy nhất với phương pháp này là bạn không thể dừng các phương thức @Trước khi chạy bằng phương pháp này, có thể chậm. Nếu đó là một vấn đề (và bạn thực sự không thể chạm vào các bài kiểm tra) thì @Ignore trong phương pháp ghi đè là điều duy nhất tôi có thể nghĩ đến.

Tuy nhiên, nếu bạn có thể chạm những thử nghiệm, một số tùy chọn bổ sung mở ra:

Bạn có thể chạy chúng với một Á hậu tùy chỉnh bằng cách xác định thẻ @RunWith trên lớp. Á hậu này sẽ chỉ vượt qua thực hiện để các Á hậu tiêu chuẩn (JUnit4.trong dự án đó, nhưng trong dự án của bạn (thông qua một thuộc tính hệ thống hoặc một số cơ chế khác) sẽ kiểm tra tên thử nghiệm và không chạy thử nghiệm. Điều này có lợi thế là ít xâm nhập nhất, nhưng khó khăn nhất để thực hiện (vận động viên là con thú lông, một trong những mục tiêu đã nêu của @Rule là để loại bỏ hầu hết sự cần thiết phải làm cho họ).

Một cách khác là tạo câu lệnh giả định trên thử nghiệm sẽ kiểm tra một số cài đặt cấu hình sẽ đúng nếu thử nghiệm đó chạy. Điều đó thực sự sẽ liên quan đến việc tiêm chích ngay vào thử nghiệm, mà rất có thể là máy cắt giao dịch trong bất cứ thứ gì được gắn nhãn từ xa là "dự án riêng biệt".

0

Nếu các bài kiểm tra không mong muốn nằm trong các lớp/gói cụ thể, bạn có thể sử dụng tệp không bao gồm trong Ant để loại trừ chúng trong khi nhập.

+0

Không, rất tiếc, tôi cần phải loại trừ các phương pháp thử nghiệm cụ thể. Đó là, tôi muốn chạy một số bài kiểm tra trong một lớp học thử nghiệm nhất định nhưng không phải những bài kiểm tra khác. – rewbs

2

OK, đây là một giải pháp khá nặng, nhưng đừng ném những thứ vào tôi nếu nó có vẻ vô lý.

Lõi của Junit4 là lớp org.junit.runner.Runner và các lớp con khác nhau, quan trọng nhất là org.junit.runners.Suite. Những người chạy này xác định những gì các bài kiểm tra cho một lớp thử nghiệm nhất định, sử dụng những thứ như @Test và @Ignore. Nó khá dễ dàng để tạo ra triển khai tùy chỉnh của một Á hậu, và thông thường bạn sẽ móc chúng bằng cách sử dụng chú thích @RunWith trên các lớp thử nghiệm của bạn, nhưng rõ ràng đó không phải là một lựa chọn cho bạn. Tuy nhiên, về lý thuyết bạn có thể viết tác vụ Ant của riêng bạn, có lẽ dựa trên nhiệm vụ Ant Junit tiêu chuẩn, sẽ đưa người chạy thử nghiệm tùy chỉnh của bạn và sử dụng nó trực tiếp, chuyển từng lớp kiểm tra đến lượt nó. Việc thực thi Á hậu của bạn có thể sử dụng tệp cấu hình bên ngoài để chỉ định phương thức thử nào cần bỏ qua.

Có khá nhiều công việc, và bạn phải dành nhiều thời gian để tìm hiểu về cách thức hoạt động của hệ thống mã Ant Junit thời tiền sử. Việc đầu tư trong thời gian có thể được giá trị nó, tuy nhiên.

Thật đáng tiếc là nhiệm vụ của Junit Ant không cung cấp cơ chế chỉ định Runner thử nghiệm, điều đó sẽ là lý tưởng.

+0

Tôi có thể nói việc triển khai một Á hậu đơn giản. Tôi thấy mình sao chép và dán mã từ các phần khác của JUnit để có được một tùy chỉnh để làm việc đúng cách, và nó đã rất giòn - khá nhiều đảm bảo để phá vỡ trên một phiên bản mới. – Yishai

+0

Tất cả đều đúng. Tôi không bao giờ tuyên bố nó là thanh lịch :) – skaffman

1

Một khả năng tôi có thể nghĩ đến để đạt được những gì bạn muốn với các ràng buộc đã nêu là sử dụng sửa đổi bytecode. Bạn có thể giữ một danh sách các lớp và các phương thức để bỏ qua trong một tệp riêng biệt và vá mã byte của các lớp thử nghiệm khi bạn nạp chúng để loại bỏ hoàn toàn các phương thức này.

Nếu tôi không nhầm, JUnit sử dụng phản chiếu để tìm phương pháp thử nghiệm để thực thi. Một hoạt động đổi tên phương thức sau đó sẽ cho phép bạn loại bỏ các phương thức này trước khi JUnit tìm thấy chúng. Hoặc phương pháp có thể được sửa đổi để trả về ngay lập tức, mà không thực hiện bất kỳ thao tác nào.

Có thể sử dụng thư viện như BCEL để sửa đổi các lớp khi được tải.

+1

JUnit 4 sử dụng chú thích thay vì tên phương pháp để xác định các thử nghiệm để chạy. – Yishai

+0

Sẽ vẫn hợp lệ để sửa đổi phương thức trả lại ngay lập tức. Nhưng cảm ơn, tôi đã suy nghĩ về JUnit3 –

+2

Có lẽ sửa đổi bytecode cũng có thể được sử dụng để thêm chú thích @Ignore vào các phương thức trong các lớp được biên dịch. – rewbs

3

Nó không giúp bạn bây giờ, nhưng TestNG hỗ trợ loại khả năng này.

1

Nếu bạn chỉ muốn chạy một nhóm nhỏ các bài kiểm tra, có vẻ như lớp đó có nhiều trách nhiệm và nên được cấu trúc lại. Ngoài ra, lớp thử nghiệm có thể được chia nhỏ để dự án ban đầu có tất cả các bài kiểm tra nhưng trên một hoặc nhiều lớp (tôi đoán một số bài kiểm tra thực sự là bài kiểm tra tích hợp và chạm vào cơ sở dữ liệu hoặc mạng) và bạn có thể loại trừ lớp đó (es) bạn không muốn.

Nếu bạn không thể làm điều đó, tùy chọn ghi đè của bạn có lẽ là tốt nhất. Thực hiện quá trình bất cứ khi nào bạn cần bỏ qua một số phương thức bạn mở rộng lớp đó và thêm nó vào danh sách loại trừ Ant của bạn. Bằng cách đó bạn có thể loại trừ những gì bạn không thể vượt qua và vẫn sẽ kéo trong tất cả các bài kiểm tra mới (phương pháp bạn không ghi đè và các lớp thử nghiệm mới) mà không sửa đổi bản dựng của bạn.

0

Hai tùy chọn

  1. Làm việc với các chủ sở hữu của các bài kiểm tra mượn để trích xuất những bạn thành một lớp riêng biệt cả hai bạn có thể chia sẻ.
  2. Tạo lớp thử nghiệm của riêng bạn để ủy quyền cho lớp thử nghiệm bạn muốn sử dụng. Đối với mỗi phương thức bạn muốn bao gồm có một phương thức trong lớp của bạn. Bạn sẽ cần phải xây dựng một thể hiện của lớp kiểm tra mà bạn đang gọi và làm trước và sau các phương thức nếu chúng ở trong bản gốc.
  3. Tạo nhân vật tùy chỉnh Junit dựa trên blockjunitrunner và sử dụng nó để lọc ra hoặc trong các thử nghiệm bạn muốn.
Các vấn đề liên quan