เรียกใช้การทดสอบ Junit ควบคู่กันใน Maven build หรือไม่


110

ฉันใช้ JUnit 4.4 และ Maven และฉันมีการทดสอบการรวมที่ใช้งานได้ยาวนานจำนวนมาก

เมื่อพูดถึงชุดทดสอบแบบขนานมีวิธีแก้ปัญหาบางอย่างที่ช่วยให้ฉันเรียกใช้วิธีการทดสอบแต่ละวิธีในคลาสทดสอบเดียวควบคู่กันได้ แต่สิ่งเหล่านี้ต้องการให้ฉันเปลี่ยนการทดสอบไม่ทางใดก็ทางหนึ่ง

ฉันคิดว่ามันน่าจะเป็นวิธีแก้ปัญหาที่สะอาดกว่ามากในการรัน X คลาสทดสอบที่แตกต่างกันในเธรด X แบบขนาน ฉันมีแบบทดสอบหลายร้อยแบบดังนั้นฉันจึงไม่สนใจเกี่ยวกับเธรดการทดสอบแต่ละคลาส

มีวิธีใดบ้างที่จะทำเช่นนี้?

คำตอบ:


75

ใช้ปลั๊กอิน maven:

<build>
    <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.7.1</version>
        <configuration>
            <parallel>classes</parallel>
            <threadCount>5</threadCount>
        </configuration>
    </plugin>
    </plugins>
</build>

12
<parallel> ได้รับการสนับสนุนโดย surefire หากคุณใช้ Junit 4.7 หรือใหม่กว่า Surefire guide
jontejj

42

จาก junit 4.7 ตอนนี้สามารถเรียกใช้การทดสอบพร้อมกันได้โดยไม่ต้องใช้ TestNG จริงๆแล้วมันเป็นไปได้ตั้งแต่ 4.6 แต่มีการแก้ไขหลายอย่างใน 4.7 ซึ่งจะทำให้เป็นตัวเลือกที่ใช้งานได้ คุณอาจทำการทดสอบแบบขนานกับสปริงซึ่งคุณสามารถอ่านได้ที่นี่


1
หน้าที่เชื่อมโยงระบุว่า "สำหรับโซลูชันดูอัลคอร์ส่วนใหญ่การทำงานกับเธรดแบบขนานไม่เคยเร็วไปกว่าการรันแบบไม่ใช้เธรด" ยังเป็นเช่นนั้นอยู่หรือไม่?
Raedwald

2
ฉันคิดว่าหากการทดสอบของคุณทำ IO ใด ๆ ก็จะยังคงได้รับประโยชน์ ตัวอย่างเช่นหากการทดสอบหน่วยของคุณเป็นเหมือนการทดสอบการรวมและการเข้าสู่ฐานข้อมูลการทำงานแบบขนานควรเร่งความเร็วให้เร็วขึ้น
Dave

@Raedwald อย่าคาดหวังมากเกินไปสำหรับการทดสอบหน่วยสั้น ๆ ที่ไม่ผูกมัดคือสิ่งที่ฉันพยายามจะพูด Surefire เวอร์ชันใหม่กว่านั้นดีกว่า / มีประสิทธิภาพมากกว่า 2.5 ที่อธิบายไว้ในโพสต์ดังนั้นคุณอาจได้รับผลลัพธ์ที่ดีขึ้นเล็กน้อย
krosenvold

3
คุณระบุว่าเป็นไปได้ แต่คุณสามารถใส่ลิงก์ไปยังคำอธิบายได้อย่างไร? ลิงก์ที่สองของคุณมีไว้สำหรับ "พร้อมสปริง" ซึ่งฉันไม่สนใจ
Cory Kendall

@krosenvold ลิงค์? ฉันกำลังดิ้นรนเพื่อหาโซลูชันในตัว
Ilan Biala

10

แรงบันดาลใจจากนักวิ่งParallelComputer รุ่นทดลองของ JUnit ฉันได้สร้างนักวิ่งParallelSuiteและParallelParameterizedของตัวเอง การใช้ตัววิ่งเหล่านี้จะทำให้สามารถขนานชุดทดสอบและการทดสอบแบบกำหนดพารามิเตอร์ได้อย่างง่ายดาย

ParallelSuite.java

public class ParallelSuite extends Suite {

    public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {

        super(klass, builder);

        setScheduler(new RunnerScheduler() {

            private final ExecutorService service = Executors.newFixedThreadPool(4);

            public void schedule(Runnable childStatement) {
                service.submit(childStatement);
            }

            public void finished() {
                try {
                    service.shutdown();
                    service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
            }
        });
    }
}

ParallelParameterized.java

public class ParallelParameterized extends Parameterized {

    public ParallelParameterized(Class<?> arg0) throws Throwable {

        super(arg0);

        setScheduler(new RunnerScheduler() {

            private final ExecutorService service = Executors.newFixedThreadPool(8);

            public void schedule(Runnable childStatement) {
                service.submit(childStatement);
            }

            public void finished() {
                try {
                    service.shutdown();
                    service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
            }
        });
    }
}

การใช้งานทำได้ง่าย เพียงแค่เปลี่ยนค่าหมายเหตุ@RunWithเป็นหนึ่งในคลาสParallel *เหล่านี้

@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}

5

tempus-fugitมีสิ่งที่คล้ายกันโปรดตรวจสอบเอกสารเพื่อดูรายละเอียด มันอาศัย JUnit 4.7 @RunWith(ConcurrentTestRunner)และคุณเพียงแค่ทำเครื่องหมายทดสอบของคุณ

ไชโย


3

คุณสามารถตรวจสอบแหล่งที่มาเปิดห้องสมุด - ทดสอบ Balancer การโหลด ทำในสิ่งที่คุณขอ - เรียกใช้คลาสทดสอบต่างๆควบคู่กันไป สิ่งนี้จะรวมในระดับ ant-junit เพื่อที่คุณจะได้ไม่ต้องเปลี่ยนการทดสอบของคุณต่อไป ฉันเป็นหนึ่งในผู้เขียนห้องสมุด

นอกจากนี้อย่าลืมเรียกใช้ในเธรดเนื่องจากคุณอาจต้องใช้แซนด์บ็อกซ์ระดับกระบวนการ ตัวอย่างเช่นหากคุณกำลังกดปุ่ม DB ในการทดสอบการรวมคุณไม่ต้องการให้การทดสอบหนึ่งล้มเหลวเนื่องจากการทดสอบอื่นเพิ่มข้อมูลบางส่วนในเธรดอื่น ส่วนใหญ่แล้วการทดสอบไม่ได้เขียนขึ้นโดยคำนึงถึงสิ่งนี้

สุดท้ายแล้วจะแก้ปัญหานี้อย่างไรจนถึงตอนนี้?


2

TestNG ทำได้ (นี่เป็นการสะท้อนกลับครั้งแรกของฉัน - จากนั้นฉันเห็นว่าคุณมี testcases จำนวนมากอยู่แล้ว)

สำหรับ JUnit, ดูที่ขนาน junit


3
น่าเสียดายที่นี่ไม่ใช่คำตอบสำหรับคำถามที่ฉันถาม Parallel-junit ทำงานภายในคลาสทดสอบเดียวเท่านั้น TestNG ยังทำงานในคลาสเดียวเท่านั้นและการทดสอบของฉันไม่ใช่การทดสอบ TestNG
krosenvold

@PlatinumAzure: ฉันอัปเดตลิงค์ ไม่ทราบว่าโครงการนี้ดูแลอย่างไร อีกคำถามหนึ่งก็ถามว่าเมื่อเร็ว ๆ นี้เพื่อเผยแพร่การดำเนินการทดสอบ junit ในหลายเครื่อง
ใจร้อน

2

คุณสามารถทำการทดสอบควบคู่กันได้โดยใช้ ParallelComputer ที่ Junit จัดเตรียมไว้ให้ นี่คือตัวอย่างข้อมูลเล็ก ๆ ที่จะช่วยให้คุณเริ่มต้นได้

Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();

สิ่งนี้จะช่วยเมื่อคุณต้องการเรียกใช้การทดสอบจากโค้ดเนื่องจากไม่มีการพึ่งพา Maven หรือเครื่องมือการจัดการบิลด์อื่น ๆ

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


0

ทางเลือกอื่น: Punner นักวิ่งจูนิทคู่ขนานใหม่และปลั๊กอิน maven คุณไม่จำเป็นต้องเปลี่ยนรหัสของคุณคัดลอกไปที่ pom.xml ของคุณ:

<!-- Disable default surefire based testing -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.20</version>
  <configuration>
    <skip>true</skip>
  </configuration>
</plugin>

<plugin>
  <groupId>com.github.marks-yag</groupId>
  <artifactId>punner-maven-plugin</artifactId>
  <version>${version}</version>
  <configuration>
  </configuration>
  <executions>
    <execution>
      <id>test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Punner สามารถเรียกใช้วิธีการทดสอบแบบขนานสามารถเก็บเอาต์พุตการทดสอบแยกกันและทำความสะอาดได้

Punner จะลดเอาต์พุตคอนโซล mvn ของคุณเช่นนี้:

[INFO] --- punner-maven-plugin:0.9.13:test (test) @ ipc ---
[INFO] Punner report directory: /Users/guile/workspace/ipc/target/punner-reports
[INFO]
[INFO] com.github.yag.ipc.IPCTest.testConnectionHandler.............. PASSED
[INFO] com.github.yag.ipc.IPCTest.testSequence....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testPartialContent................. PASSED
[INFO] com.github.yag.ipc.IPCTest.testResponseContent................ PASSED
[INFO] com.github.yag.ipc.IPCTest.testPingPong....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerClose.................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeat............ PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientReconnect................ PASSED
[INFO]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.952 sec, Time saved: 25.919 sec.

Punner สร้างเอาต์พุตที่เข้ากันได้กับ Surefire คุณยังสามารถรับข้อมูลบันทึกดิบและรายงานรูปแบบมาร์กดาวน์จากไดเร็กทอรีรายงาน:

  ipc git:(develop) ll target/punner-reports
total 104
-rw-r--r--   1 guile  staff    11K Oct 15 23:07 TEST-com.github.yag.ipc.IPCTest.xml
-rw-r--r--   1 guile  staff   298B Oct 15 23:07 com.github.yag.ipc.IPCTest.txt
drwxr-xr-x  12 guile  staff   384B Oct  8 00:50 logs
-rw-r--r--   1 guile  staff    33K Oct 15 23:07 report.md

Punner เป็นโครงการส่วนตัวของฉันฉันเขียน Punner เพื่อเร่งระยะการทดสอบหน่วยของโครงการอื่น ๆ เช่นกรอบงาน IPC การล็อกแบบละเอียดบริการวารสารเครื่องยนต์เวิร์กโฟลว์แบบกระจาย ฯลฯ ช่วยประหยัดเวลาในการรอของฉันได้มาก

Punner ยังไม่รองรับคุณสมบัติขั้นสูงบางอย่าง ฉันดีใจมากถ้าคุณสามารถลองและแสดงความคิดเห็น


-3

คุณสามารถเปลี่ยนการทดสอบของคุณเป็นการทดสอบ TestNg ในหนึ่งนาที (คุณเพียงแค่ต้องเปลี่ยนการนำเข้า) TestNG เป็นการทดสอบแบบคู่ขนานที่ดีที่สุด


-3

คุณสามารถลองใช้Gridgainที่ช่วยให้คุณสามารถแจกจ่ายการทดสอบของคุณในตารางคำนวณ


1
ฉันได้ลองใช้โซลูชัน GridGain แล้วและมีปัญหาใหญ่สองประการ ประการแรกคุณต้องบอกให้ GridGain แยกออกจาก classpath ของงานกริดของคุณทุกอย่างที่ GridGain ใช้เช่น Spring และ Apache Commons มากมาย ประการที่สองการโหลดคลาสเครือข่ายในขณะที่ความคิดที่ยอดเยี่ยมไม่สามารถใช้งานได้กับไลบรารีที่ต้องการค้นหา classpath เช่น Spring
Graham Lea
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.