JUnit: cách tránh “phương thức không chạy được” trong các lớp test utils


118

Tôi đã chuyển sang JUnit4.4 từ JUnit3.8. Tôi chạy các bài kiểm tra của mình bằng cách sử dụng ant, tất cả các bài kiểm tra của tôi đều chạy thành công nhưng các lớp tiện ích kiểm tra không thành công với lỗi "Không có phương pháp chạy được". Mẫu tôi đang sử dụng là bao gồm tất cả các lớp có tên * Test * trong thư mục test.

Tôi hiểu rằng người chạy không thể tìm thấy bất kỳ phương thức nào được chú thích bằng thuộc tính @Test. Nhưng chúng không chứa chú thích như vậy vì các lớp này không phải là bài kiểm tra. Đáng ngạc nhiên là khi chạy các bài kiểm tra này trong nhật thực, nó không phàn nàn về các lớp này.

Trong JUnit3.8, nó không phải là một vấn đề gì cả vì các lớp tiện ích này không mở rộng TestCase nên người chạy không cố gắng thực thi chúng.

Tôi biết tôi có thể loại trừ các lớp cụ thể này trong mục tiêu junit trong tập lệnh kiến. Nhưng tôi không muốn thay đổi tệp xây dựng dựa trên mỗi lớp tiện ích mới mà tôi thêm vào. Tôi cũng có thể đổi tên các lớp (nhưng đặt tên hay cho các lớp luôn là tài năng yếu nhất của tôi :-))

Có bất kỳ giải pháp thanh lịch cho vấn đề này?


Các bài kiểm tra của bạn có hoạt động trong Eclipse / NetBeans / IDE yêu thích của bạn không?
guerda

Tôi sử dụng nhật thực. Thực ra không có vấn đề gì ở đó, bằng cách nào đó eclipse không cố gắng chạy các lớp này. Tôi tự hỏi làm thế nào?
LiorH

Tôi không biết nếu chúng tôi hiểu câu hỏi của bạn. Vui lòng đọc lại câu hỏi của bạn và có thể bổ sung thêm một số thông tin.
guerda

1
@guerda: Câu hỏi có vẻ khá rõ ràng với tôi. Nhiệm vụ Ant của anh ấy là tìm các lớp không chứa các bài kiểm tra, vì bộ lọc đang chọn lớp tiện ích. Do đó, câu trả lời của tôi, mà tôi vẫn tin là hoàn toàn phù hợp.
Jon Skeet

LiorH: Cảm ơn bạn đã làm rõ, vì vậy câu trả lời của tôi là lãng phí :)
touristda

Câu trả lời:


50

Giả sử bạn đang kiểm soát mẫu được sử dụng để tìm các lớp thử nghiệm, tôi khuyên bạn nên thay đổi nó để phù hợp *Testhơn là *Test*. Cách đó TestHelpersẽ không phù hợp, nhưng FooTestsẽ.


1
Tôi không nghĩ nó sẽ giúp ích được gì, bởi vì anh ấy đã chuyển sang JUnit 4.4 và điều đó không thành vấn đề.
guerda

2
Có vẻ như bạn đã bỏ lỡ câu trả lời của tôi. Anh ta có một bộ lọc tên để xác định các lớp được coi là bài kiểm tra. Nếu anh ta thay đổi bộ lọc, anh ta có thể dễ dàng loại trừ các lớp người trợ giúp.
Jon Skeet

1
Đề xuất của bạn là hợp lệ, tuy nhiên tôi đã kiểm tra các lớp kiểm tra của mình và một số bắt đầu bằng Kiểm tra và một số kết thúc bằng Kiểm tra. không có sự phân biệt rõ ràng giữa các lớp tiện ích và các lớp thử nghiệm thực. Bạn có nghĩ rằng quy ước mà bạn đề xuất là một thực hành tốt? (tức là utils bắt đầu bằng Kiểm tra và kiểm tra kết thúc bằng Kiểm tra)
LiorH

4
Nó gần như là một quy ước mà bạn gắn các lớp testcase với * Test. Bạn có thể cần phải cấu trúc lại bằng cách đổi tên các lớp thử nghiệm một cách thích hợp và cũng đổi tên các trình trợ giúp để chúng không sử dụng quy ước hậu tố đó.
Spoike

2
Tôi đồng ý với Spoike - nếu bạn không thể biết từ tên của lớp đó là bài kiểm tra hay người trợ giúp, bạn nên đổi tên lớp. Quy ước hơn "lớp là một bài kiểm tra nếu và chỉ khi nó kết thúc bằng Kiểm tra." Các lớp tiện ích có thể bắt đầu hoặc không bắt đầu với Test - điều đó không quan trọng.
Jon Skeet

142

Chú thích các lớp sử dụng của bạn với @Ignore. Điều này sẽ khiến JUnit không thử và chạy chúng dưới dạng thử nghiệm.


6
Trên thực tế, không, nó không nên. @Ignore là để tạm thời vô hiệu hóa các thử nghiệm.
Alice Young

1
Xin lỗi nhưng đó là một ý tưởng tồi. Bạn muốn bắt đầu chú thích mã sản xuất của mình bằng các chú thích liên quan đến thử nghiệm chỉ vì chúng có thể khớp với mẫu thử nghiệm? Câu trả lời thích hợp là sửa tên lớp nếu chúng đang kích hoạt đối sánh mẫu cho các bài kiểm tra. Và đảm bảo rằng mẫu chỉ tìm thấy các lớp KẾT THÚC với Kiểm tra. Đó là một mô hình thường được chấp nhận
Kevin M

Vâng, điều này thật tệ và tôi đã không nhận ra điều đó cho đến sau khi đóng góp một ủng hộ khác mà tôi không thể xóa. Làm cho lớp cơ sở của bạn trở nên trừu tượng, sau đó JUnit sẽ bỏ qua nó. Xem câu trả lời của @ gmoore bên dưới.
Ryan Shillington

83

Trường hợp cụ thể của tôi có tình huống sau. Thử nghiệm của chúng tôi

public class VenueResourceContainerTest extends BaseTixContainerTest

tất cả mở rộng

BaseTixContainerTest

và JUnit đang cố gắng chạy BaseTixContainerTest. BaseTixContainerTest tội nghiệp chỉ cố gắng thiết lập thùng chứa, thiết lập khách hàng, đặt một số bánh pizza và thư giãn ... anh bạn.

Như đã đề cập trước đây, bạn có thể chú thích lớp với

@Ignore

Nhưng điều đó đã khiến JUnit báo cáo rằng bài kiểm tra đó là đã bị bỏ qua (trái ngược với việc bị bỏ qua hoàn toàn).

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

Kiểu đó làm tôi phát cáu.

Vì vậy, tôi đã làm cho BaseTixContainerTest trừu tượng, và bây giờ JUnit thực sự bỏ qua nó.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

7
Tốt hơn nhiều so với@Ignore
neworld

Tôi đã thử cách tiếp cận @Ignore và nghĩ, tốt quá, sau đó tôi đọc câu trả lời này và tự tát vào trán mình, "Tất nhiên !"
dnuttle

38

Để ngăn JUnit khởi tạo lớp cơ sở thử nghiệm của bạn, chỉ cần tạo

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore báo cáo nó là bị bỏ qua mà tôi dành cho các thử nghiệm tạm thời bị bỏ qua.)


3
Người chạy JUnit cũng thường cố gắng khởi tạo các lớp trừu tượng, và sau đó thất bại với lỗi khởi tạo.
Holly Cummins

Hoạt động hoàn hảo cho các lớp thử nghiệm cơ bản của tôi
ruX

3
Điều này hoạt động vì tên (nó không kết thúc trong Thử nghiệm), không phải vì công cụ sửa đổi trừu tượng. Thay đổi tên lớp thành MyBaseClassTest và nó sẽ cố gắng khởi tạo như được đề cập bởi @HollyCummins (và không thành công)
Hutch

Trong trường hợp của tôi, nó nên được protected abstract class.
Mystic Lin

18
  1. Nếu đây là lớp thử nghiệm cơ sở của bạn, ví dụ: AbstractTest và tất cả các thử nghiệm của bạn mở rộng điều này thì hãy xác định lớp này là trừu tượng
  2. Nếu đó là lớp Util thì tốt hơn nên loại bỏ * Kiểm tra khỏi lớp đổi tên nó thành MyTestUtil hoặc Utils, v.v.

10

Hãy cẩn thận khi sử dụng mã hoàn thành của IDE để thêm nhập cho @Test.

Nó phải được import org.junit.Testvà không import org.testng.annotations.Test, chẳng hạn. Nếu bạn làm theo cách sau, bạn sẽ gặp lỗi "không có phương pháp nào chạy được".


Đây nên là một bình luận hơn là một câu trả lời.
Swaranga Sarma

3
Tôi không hiểu tại sao. Đó là một giải pháp hợp lệ.
Sridhar Sarnobat

4
Intellij Idea 2017 đã làm rối trí tôi bằng cách nhập org.junit.jupiter.api.Testthay thế! Nhưng nhờ có bạn, bây giờ nó đã được giải quyết
AmiNadimi

Cảm ơn bạn rất nhiều, tôi đã bối rối khi nhận được vấn đề "không có phương pháp chạy được".
Peter S.

7

Ant bây giờ đi kèm với skipNonTeststhuộc tính được thiết kế để thực hiện chính xác những gì bạn có vẻ đang tìm kiếm. Không cần phải thay đổi các lớp cơ sở của bạn thành trừu tượng hoặc thêm chú thích vào chúng.


2
Có vẻ như skipNonTeststhuộc tính này chỉ có trong ant 1.9+, thật đáng tiếc, vì nó trông cực kỳ hữu ích. Nó cũng sẽ loại trừ các lớp cha kiểm tra trừu tượng.
Holly Cummins

4

Điều gì về việc thêm một phương thức kiểm tra trống cho các lớp này?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
    assertTrue(true); // do nothing;
}

8
nhưng điều đó sai làm tăng số lượng các bài kiểm tra chúng tôi có :) không phải là của mình là một việc lớn
Sudarshan

1

Trong lớp thử nghiệm của bạn nếu đã viết import org.junit.jupiter.api.Test; xóa nó và viết import org.junit.Test; Trong trường hợp này, nó cũng có tác dụng với tôi.


1
thật tuyệt vời, nó đã hoạt động. tôi đã thực thi thủ công trong dòng lệnh Windows. tuy nhiên, một vấn đề khác là nó @BeforeAll@AfterAllkhông chạy.
BingLi224

dường như JUnit4 đã hoạt động (với @BeforeClass@AfterClass, nhưng JUnit5 thì không. Tham khảo: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224

0

Tôi cũng gặp phải vấn đề tương tự ("không có phương pháp nào chạy được ..") khi chạy đoạn mã đơn giản nhất (Sử dụng @Test, @Before, v.v.) và không tìm thấy giải pháp nào. Tôi đang sử dụng Junit4 và Eclipse SDK phiên bản 4.1.2. Đã giải quyết sự cố của tôi bằng cách sử dụng Eclipse SDK 4.2.2 mới nhất. Tôi hy vọng điều này sẽ giúp những người đang gặp khó khăn với một vấn đề tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.