JUnit: วิธีหลีกเลี่ยง "ไม่มีวิธีที่รันได้" ในคลาสเครื่องมือทดสอบ


118

ฉันเปลี่ยนมาใช้ JUnit4.4 จาก JUnit3.8 ฉันเรียกใช้การทดสอบโดยใช้มดการทดสอบทั้งหมดของฉันทำงานได้สำเร็จ แต่คลาสยูทิลิตี้การทดสอบล้มเหลวโดยมีข้อผิดพลาด "ไม่มีวิธีที่รันได้" รูปแบบที่ฉันใช้คือการรวมคลาสทั้งหมดที่มีชื่อ * ทดสอบ * ไว้ในโฟลเดอร์ทดสอบ

ฉันเข้าใจว่านักวิ่งไม่พบวิธีการใด ๆ ที่มีคำอธิบายประกอบด้วยแอตทริบิวต์ @Test แต่ไม่มีคำอธิบายประกอบดังกล่าวเนื่องจากชั้นเรียนเหล่านี้ไม่ใช่การทดสอบ น่าแปลกที่เมื่อเรียกใช้การทดสอบเหล่านี้ใน eclipse ก็ไม่ได้บ่นเกี่ยวกับคลาสเหล่านี้

ใน JUnit3.8 ไม่ใช่ปัญหาเลยเนื่องจากคลาสยูทิลิตี้เหล่านี้ไม่ได้ขยาย TestCase ดังนั้นนักวิ่งจึงไม่พยายามเรียกใช้งาน

ฉันรู้ว่าฉันสามารถยกเว้นคลาสเฉพาะเหล่านี้ในเป้าหมาย junit ใน ant script ได้ แต่ฉันไม่ต้องการเปลี่ยนไฟล์บิวด์ในทุกคลาสยูทิลิตี้ใหม่ที่ฉันเพิ่ม ฉันยังสามารถเปลี่ยนชื่อชั้นเรียนได้ (แต่การตั้งชื่อชั้นเรียนให้ดีเป็นความสามารถที่อ่อนแอที่สุดของฉันเสมอ :-))

มีวิธีแก้ปัญหาที่สวยงามสำหรับปัญหานี้หรือไม่?


การทดสอบของคุณทำงานใน Eclipse / NetBeans / IDE ที่คุณชื่นชอบหรือไม่?
guerda

ฉันใช้คราส จริงๆแล้วไม่มีปัญหา แต่คราสไม่พยายามเรียกใช้คลาสเหล่านี้ ฉันสงสัยว่าอย่างไร
LiorH

ฉันไม่รู้ว่าเราเข้าใจคำถามของคุณหรือไม่ โปรดอ่านคำถามของคุณอีกครั้งและอาจเพิ่มข้อมูลเพิ่มเติม
guerda

1
@guerda: คำถามนี้ค่อนข้างชัดเจนสำหรับฉัน งาน Ant ของเขาคือการค้นหาคลาสที่ไม่มีการทดสอบเนื่องจากตัวกรองกำลังเลือกคลาสยูทิลิตี้ ดังนั้นคำตอบของฉันซึ่งฉันยังเชื่อว่ามีความเกี่ยวข้องทั้งหมด
Jon Skeet

LiorH: ขอบคุณสำหรับคำชี้แจงดังนั้นคำตอบของฉันจึงสิ้นเปลือง :)
guerda

คำตอบ:


50

สมมติว่าคุณกำลังอยู่ในการควบคุมของรูปแบบที่ใช้ในการทดสอบหาชั้นเรียนผมขอแนะนำให้เปลี่ยนไปตรงมากกว่า*Test *Test*วิธีTestHelperนั้นจะไม่ถูกจับคู่ แต่FooTestจะ


1
ฉันไม่คิดว่ามันจะช่วยได้เพราะเขาย้ายไปที่ JUnit 4.4 และนั่นก็ไม่สำคัญ
guerda

2
ดูเหมือนคุณจะพลาดคำตอบของฉัน เขามีตัวกรองชื่อเพื่อกำหนดชั้นเรียนที่จะถือว่าเป็นการทดสอบ หากเขาเปลี่ยนฟิลเตอร์เขาก็สามารถยกเว้นคลาสตัวช่วยได้อย่างง่ายดาย
Jon Skeet

1
คำแนะนำของคุณถูกต้องอย่างไรก็ตามฉันได้ตรวจสอบชั้นเรียนการทดสอบของฉันและบางส่วนเริ่มต้นด้วยการทดสอบและบางส่วนลงท้ายด้วยการทดสอบ ไม่มีความแตกต่างที่ชัดเจนระหว่างคลาสยูทิลิตี้กับคลาสทดสอบจริง คุณคิดว่าการประชุมใหญ่ที่คุณแนะนำเป็นแนวทางปฏิบัติที่ดีหรือไม่? (เช่น utils เริ่มต้นด้วยการทดสอบและการทดสอบจบลงด้วยการทดสอบ)
LiorH

4
เกือบจะเป็นการประชุมที่คุณต่อท้ายชั้นทดสอบด้วย * Test คุณอาจต้องปรับโครงสร้างใหม่โดยเปลี่ยนชื่อคลาสทดสอบให้เหมาะสมและเปลี่ยนชื่อผู้ช่วยเหลือเพื่อไม่ให้ใช้รูปแบบคำต่อท้ายนั้น
Spoike

2
ฉันเห็นด้วยกับ Spoike - ถ้าคุณไม่สามารถบอกได้จากชื่อชั้นเรียนว่าเป็นการทดสอบหรือผู้ช่วยคุณควรเปลี่ยนชื่อชั้นเรียน การประชุมใหญ่กว่า "ชั้นเรียนคือการทดสอบถ้าจบด้วยการทดสอบ" คลาสยูทิลิตี้อาจเริ่มต้นด้วยการทดสอบหรือไม่ก็ได้ไม่สำคัญ
Jon Skeet

142

ใส่คำอธิบายประกอบคลาส util ของคุณด้วย @Ignore สิ่งนี้จะทำให้ JUnit ไม่พยายามเรียกใช้เป็นการทดสอบ


6
จริงๆแล้วไม่ควร @Ignore ใช้สำหรับปิดการทดสอบชั่วคราว
Alice Young

1
ขออภัยนั่นเป็นความคิดที่ไม่ดี คุณต้องการเริ่มใส่คำอธิบายประกอบรหัสการผลิตของคุณด้วยคำอธิบายประกอบที่เกี่ยวข้องกับการทดสอบเพียงเพราะอาจตรงกับรูปแบบการทดสอบหรือไม่? คำตอบที่ถูกต้องคือการแก้ไขชื่อคลาสหากมีการเรียกใช้รูปแบบที่ตรงกันสำหรับการทดสอบ และตรวจสอบให้แน่ใจว่ารูปแบบพบเฉพาะคลาสที่ END with Test นั่นเป็นรูปแบบที่ยอมรับกันทั่วไป
Kevin M

ใช่มันไม่ดีและฉันก็ไม่รู้ตัวจนกระทั่งหลังจากมีส่วนร่วมในการโหวตเพิ่มอีกครั้งที่ฉันไม่สามารถลบออกได้ ทำให้คลาสพื้นฐานของคุณเป็นนามธรรมจากนั้น JUnit จะไม่สนใจ ดูคำตอบของ @ gmoore ด้านล่าง
Ryan Shillington

83

กรณีเฉพาะของฉันมีสถานการณ์ต่อไปนี้ การทดสอบของเรา

public class VenueResourceContainerTest extends BaseTixContainerTest

ทั้งหมดขยาย

BaseTixContainerTest

และ JUnit พยายามเรียกใช้ BaseTixContainerTest BaseTixContainerTest ที่น่าสงสารกำลังพยายามตั้งค่าคอนเทนเนอร์ตั้งค่าไคลเอนต์สั่งพิซซ่าและผ่อนคลาย ...

ดังที่ได้กล่าวไว้ก่อนหน้านี้คุณสามารถใส่คำอธิบายประกอบในชั้นเรียนด้วย

@Ignore

แต่นั่นทำให้ JUnit รายงานการทดสอบนั้นว่าข้ามไป (ตรงข้ามกับการเพิกเฉยโดยสิ้นเชิง)

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

แบบนั้นทำให้ฉันหงุดหงิด

ดังนั้นฉันจึงสร้างนามธรรม BaseTixContainerTest และตอนนี้ JUnit ไม่สนใจมันอย่างแท้จริง

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

7
ดีกว่ามาก@Ignore
neworld

ฉันลองใช้วิธี @Ignore และคิดว่าดีแล้วฉันอ่านคำตอบนี้แล้วตบหน้าผากตัวเอง " แน่นอน !"
dnuttle

38

เพื่อป้องกันไม่ให้ JUnit สร้างอินสแตนซ์คลาสฐานทดสอบของคุณให้สร้างมันขึ้นมา

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

(@Ignore รายงานว่าถูกละเว้นซึ่งฉันสงวนไว้สำหรับการทดสอบที่ถูกเพิกเฉยชั่วคราว )


3
นักวิ่ง JUnit มักจะพยายามสร้างอินสแตนซ์คลาสนามธรรมเช่นกันและล้มเหลวด้วยข้อผิดพลาดในการสร้างอินสแตนซ์
Holly Cummins

ทำงานได้อย่างสมบูรณ์แบบสำหรับชั้นเรียนทดสอบพื้นฐานของฉัน
ruX

3
ใช้งานได้เนื่องจากชื่อ (ไม่ได้ลงท้ายด้วย Test) ไม่ใช่เพราะตัวปรับนามธรรม เปลี่ยนชื่อคลาสเป็น MyBaseClassTest และจะพยายามสร้างอินสแตนซ์ตามที่ @HollyCummins กล่าวไว้ (และล้มเหลว)
Hutch

protected abstract classในกรณีของฉันมันควรจะเป็น
Mystic Lin

18
  1. หากนี่คือคลาสทดสอบพื้นฐานของคุณเช่น AbstractTest และการทดสอบทั้งหมดของคุณขยายสิ่งนี้ให้กำหนดคลาสนี้เป็น นามธรรม
  2. ถ้าเป็นคลาส Util ให้เอา * Test ออกจากคลาสเปลี่ยนชื่อเป็น MyTestUtil หรือ Utils เป็นต้น

10

ระมัดระวังเมื่อใช้การเติมรหัสของ IDE เพื่อเพิ่มการนำเข้าสำหรับ @Testรหัสเสร็จจะเพิ่มการนำเข้า

จะต้องเป็นimport org.junit.Testและไม่import org.testng.annotations.Testเป็นเช่นนั้น หากคุณทำอย่างหลังคุณจะได้รับข้อผิดพลาด "ไม่มีวิธีการที่รันได้"


นี่ควรเป็นความคิดเห็นมากกว่าคำตอบ
Swaranga Sarma

3
ฉันไม่เห็นว่าทำไม เป็นวิธีแก้ปัญหาที่ถูกต้อง
Sridhar Sarnobat

4
Intellij Idea 2017 ยุ่งกับความคิดของฉันโดยการนำเข้าorg.junit.jupiter.api.Testแทน! แต่ขอบคุณที่แก้ไขตอนนี้
AmiNadimi

ขอบคุณมากฉันรู้สึกสับสนระหว่างรับปัญหา "ไม่มีวิธีที่รันได้"
Peter S.

7

ตอนนี้ Ant มาพร้อมกับskipNonTestsแอตทริบิวต์ที่ออกแบบมาเพื่อทำในสิ่งที่คุณต้องการ ไม่จำเป็นต้องเปลี่ยนคลาสพื้นฐานของคุณให้เป็นนามธรรมหรือเพิ่มคำอธิบายประกอบลงไป


2
ดูเหมือนว่าskipNonTestsแอตทริบิวต์จะมีเฉพาะใน ant 1.9+ เท่านั้นซึ่งน่าเสียดายเนื่องจากมันดูมีประโยชน์อย่างไม่น่าเชื่อ นอกจากนี้ยังไม่รวมซูเปอร์คลาสการทดสอบที่เป็นนามธรรม
Holly Cummins

4

แล้วการเพิ่มวิธีทดสอบเปล่าในชั้นเรียนเหล่านี้ล่ะ?

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

8
แต่นั่นเป็นการเพิ่มจำนวนการทดสอบที่เรามีอย่างผิด ๆ :) ไม่ใช่ว่าเป็นเรื่องใหญ่
Sudarshan

1

ในชั้นทดสอบของคุณหากเขียนว่า import org.junit.jupiter.api.Test; ลบและเขียน import org.junit.Test; ในกรณีนี้ก็ใช้ได้ผลเช่นกัน


1
มันใช้งานได้อย่างน่าอัศจรรย์ ฉันดำเนินการด้วยตนเองในบรรทัดคำสั่งของ Windows อย่างไรก็ตามปัญหาอีกประการหนึ่งคือ@BeforeAllและ@AfterAllไม่ทำงาน
BingLi224

ดูเหมือนว่า JUnit4 จะใช้งานได้ (กับ@BeforeClassและ@AfterClassแต่ JUnit5 ไม่ได้อ้างอิง: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224

0

ฉันยังประสบปัญหาคล้าย ๆ กัน ("ไม่มีวิธีที่รันได้ .. ") ในการเรียกใช้โค้ดง่ายๆที่ง่ายที่สุด (ใช้ @Test, @Before เป็นต้น) และไม่พบวิธีแก้ปัญหาเลย ฉันใช้ Junit4 และ Eclipse SDK เวอร์ชัน 4.1.2 แก้ไขปัญหาของฉันโดยใช้ Eclipse SDK 4.2.2 ล่าสุด ฉันหวังว่านี่จะช่วยผู้ที่กำลังดิ้นรนกับปัญหาที่ค่อนข้างคล้ายกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.