Pertanyaan Cara mudah menjalankan tes junit yang sama berulang kali?


Seperti judulnya, saya mencari beberapa cara sederhana untuk menjalankan JUnit 4.x beberapa kali berturut-turut secara otomatis menggunakan Eclipse.

Contoh akan menjalankan tes yang sama 10 kali berturut-turut dan melaporkan kembali hasilnya.

Kami sudah memiliki cara yang rumit untuk melakukan ini, tetapi saya sedang mencari cara sederhana untuk melakukannya sehingga saya dapat memastikan bahwa uji keripik yang saya coba perbaiki tetap diperbaiki.

Solusi ideal adalah plugin / pengaturan / fitur Eclipse yang tidak saya sadari.


75
2017-09-29 14:20


asal


Jawaban:


Cara termudah (paling tidak jumlah kode baru diperlukan) cara melakukannya adalah menjalankan tes sebagai uji parametri (anotasi dengan @RunWith(Parameterized.class) dan tambahkan metode untuk menyediakan 10 parameter kosong). Dengan begitu kerangka kerja akan menjalankan tes 10 kali.

Tes ini perlu menjadi satu-satunya tes di kelas, atau lebih baik menempatkan semua metode tes harus dijalankan 10 kali di kelas.

Berikut ini contohnya:

@RunWith(Parameterized.class)
public class RunTenTimes {

    @Parameterized.Parameters
    public static Object[][] data() {
        return new Object[10][0];
    }

    public RunTenTimes() {
    }

    @Test
    public void runsTenTimes() {
        System.out.println("run");
    }
}

Dengan cara di atas, adalah mungkin untuk melakukannya dengan konstruktor parameter-kurang, tapi saya tidak yakin apakah kerangka kerja penulis dimaksudkan itu, atau apakah itu akan rusak di masa depan.

Jika Anda mengimplementasikan pelari Anda sendiri, maka Anda bisa memiliki pelari menjalankan tes 10 kali. Jika Anda menggunakan pelari pihak ketiga, maka dengan 4,7, Anda dapat menggunakan yang baru @Rule anotasi dan menerapkan MethodRule antarmuka sehingga dibutuhkan pernyataan dan mengeksekusinya 10 kali dalam perulangan. Kerugian saat ini dari pendekatan ini adalah itu @Before dan @After lari hanya sekali. Ini kemungkinan akan berubah di versi JUnit berikutnya (yang @Before akan berjalan setelah @Rule), tetapi tanpa Anda akan bertindak pada objek yang sama (sesuatu yang tidak benar dari Parameterized pelari). Ini mengasumsikan bahwa apa pun pelari Anda menjalankan kelas dengan benar mengakui @Rule anotasi. Itu hanya kasus jika mendelegasikan ke pelari JUnit.

Jika Anda menjalankan dengan pelari khusus yang tidak mengenali @Rule anotasi, maka Anda benar-benar terjebak dengan harus menulis pelari Anda sendiri yang mendelegasikan dengan tepat untuk Runner itu dan menjalankannya 10 kali.

Perhatikan bahwa ada cara lain untuk berpotensi memecahkan masalah ini (seperti pelari Theory) tetapi semuanya membutuhkan pelari. Sayangnya JUnit saat ini tidak mendukung lapisan pelari. Itu adalah pelari yang mengikat pelari lainnya.


97
2017-09-29 15:01



Saya telah menemukan bahwa anotasi pengulangan Spring berguna untuk hal semacam itu:

@Repeat(value = 10)

Dokumentasi terbaru (Spring Framework 4.3.11.RELEASE API):


51
2017-09-29 14:24



Terinspirasi solusi ini:

Menggunakan @Repeat anotasi seperti ini:

public class MyTestClass {

    @Rule
    public RepeatRule repeatRule = new RepeatRule();

    @Test
    @Repeat(10)
    public void testMyCode() {
        //your test code goes here
    }
}

Anda hanya perlu dua kelas ini:

Repeat.java:

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention( RetentionPolicy.RUNTIME )
@Target({ METHOD, ANNOTATION_TYPE })
public @interface Repeat {
    int value() default 1;
}

RepeatRule.java:

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class RepeatRule implements TestRule {

    private static class RepeatStatement extends Statement {
        private final Statement statement;
        private final int repeat;    

        public RepeatStatement(Statement statement, int repeat) {
            this.statement = statement;
            this.repeat = repeat;
        }

        @Override
        public void evaluate() throws Throwable {
            for (int i = 0; i < repeat; i++) {
                statement.evaluate();
            }
        }

    }

    @Override
    public Statement apply(Statement statement, Description description) {
        Statement result = statement;
        Repeat repeat = description.getAnnotation(Repeat.class);
        if (repeat != null) {
            int times = repeat.value();
            result = new RepeatStatement(statement, times);
        }
        return result;
    }
}

2016-10-25 Edit: Untuk menggunakan solusi ini saat menggunakan @RunWith(PowerMockRunner.class), perbarui ke Powermock 1.6.5 (yang mana termasuk tambalan ini).


26
2018-02-05 13:56



Dengan IntelliJ, Anda dapat melakukan ini dari konfigurasi uji. Setelah Anda membuka jendela ini, Anda dapat memilih untuk menjalankan pengujian berapa kali pun Anda inginkan.

enter image description here

ketika Anda menjalankan tes, intellij akan menjalankan semua tes yang telah Anda pilih untuk berapa kali Anda tentukan.

Contoh menjalankan 624 tes 10 kali: enter image description here


25
2017-09-13 20:34



Dengan JUnit 5 saya bisa menyelesaikan ini menggunakan @RepeatedTest anotasi:

@RepeatedTest(10)
public void testMyCode() {
    //your test code goes here
}

Perhatikan itu @Test anotasi tidak boleh digunakan bersama @RepeatedTest.


12
2017-07-26 08:37



Ada yang salah dengan:

@Test
void itWorks() {
    // stuff
}

@Test
void itWorksRepeatably() {
    for (int i = 0; i < 10; i++) {
        itWorks();
    }
}

Berbeda dengan kasus di mana Anda menguji masing-masing array nilai, Anda tidak terlalu peduli yang menjalankan gagal.

Tidak perlu melakukan konfigurasi atau anotasi apa yang dapat Anda lakukan dalam kode.


9
2017-09-30 13:30



Ini bekerja lebih mudah bagi saya.

public class RepeatTests extends TestCase {

    public static Test suite() {
        TestSuite suite = new TestSuite(RepeatTests.class.getName());

        for (int i = 0; i < 10; i++) {              
        suite.addTestSuite(YourTest.class);             
        }

        return suite;
    }
}

7
2017-08-21 08:30



Ada anotasi Intermiten di tempus-fugit perpustakaan yang bekerja dengan JUnit 4.7 @Rule mengulangi tes beberapa kali atau dengan @RunWith.

Sebagai contoh,

@RunWith(IntermittentTestRunner.class)
public class IntermittentTestRunnerTest {

   private static int testCounter = 0;

   @Test
   @Intermittent(repition = 99)
   public void annotatedTest() {
      testCounter++;
   }
}

Setelah tes dijalankan (dengan IntermittentTestRunner di @RunWith), testCounter akan sama dengan 99.


7
2017-12-16 20:39



Saya membangun modul yang memungkinkan melakukan tes semacam ini. Tapi itu tidak hanya terfokus pada pengulangan. Tetapi dalam jaminan bahwa beberapa bagian dari kode Thread aman.

https://github.com/anderson-marques/concurrent-testing

Ketergantungan Maven:

<dependency>
    <groupId>org.lite</groupId>
    <artifactId>concurrent-testing</artifactId>
    <version>1.0.0</version>
</dependency>

Contoh penggunaan:

package org.lite.concurrent.testing;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import ConcurrentTest;
import ConcurrentTestsRule;

/**
 * Concurrent tests examples
 */
public class ExampleTest {

    /**
     * Create a new TestRule that will be applied to all tests
     */
    @Rule
    public ConcurrentTestsRule ct = ConcurrentTestsRule.silentTests();

    /**
     * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
     */
    @Test
    @ConcurrentTest(requests = 20, threads = 10)
    public void testConcurrentExecutionSuccess(){
        Assert.assertTrue(true);
    }

    /**
     * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
     */
    @Test
    @ConcurrentTest(requests = 200, threads = 10, timeoutMillis = 100)
    public void testConcurrentExecutionSuccessWaitOnly100Millissecond(){
    }

    @Test(expected = RuntimeException.class)
    @ConcurrentTest(requests = 3)
    public void testConcurrentExecutionFail(){
        throw new RuntimeException("Fail");
    }
}

Ini adalah proyek open source. Jangan ragu untuk meningkatkan.


0
2018-05-30 13:30



Anda dapat menjalankan tes JUnit Anda dari metode utama dan mengulanginya berkali-kali yang Anda butuhkan:

package tests;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.Result;

public class RepeatedTest {

    @Test
    public void test() {
        fail("Not yet implemented");
    }

    public static void main(String args[]) {

        boolean runForever = true;

        while (runForever) {
            Result result = org.junit.runner.JUnitCore.runClasses(RepeatedTest.class);

            if (result.getFailureCount() > 0) {
                runForever = false;
               //Do something with the result object

            }
        }

    }

}

0
2017-09-06 06:52