[JAVA] Ich habe das automatische Tool zum Erstellen von Komponententests überprüft (Version Ende 2019).

Ich habe das automatische Tool zum Erstellen von Komponententests überprüft (Version Ende 2019).

Hallo. 2019 ist fast vorbei. Dieser Artikel ist der Artikel zum 25. Tag von Software Testing Adventskalender 2019.

Der Artikel vom Vortag wurde von meinem Kollegen @ozhiro san geschrieben: "Was ist Ihr Zweck bei automatisierten Tests? ](Https://qiita.com/ozhiro/items/5aa95c6360a8930df325). __bewegt sein! __ __ Übrigens habe ich heute den aktuellen Status des automatischen Tools zur Erstellung von Komponententests untersucht.

Warum hast du dich entschieden, es nachzuschlagen?

Unit-Tests sind wichtig, nicht wahr? Da Software täglich entwickelt und modifiziert wird, ist Unit Test ein Testwerkzeug, das die Qualität der entwickelten Software sicherstellt. Darüber hinaus kann die Testausführung automatisiert werden, wodurch der Testaufwand reduziert wird.

Um einen Komponententest auszuführen, muss jedoch ein Testcode entwickelt werden, der einen gewissen Entwicklungsaufwand erfordert. Für mehr Vollständigkeit kann es so lange dauern, bis die zu testende Software entwickelt ist.

Vor diesem Hintergrund ist die Situation häufig, wenn nur manuelle Tests von Hand durchgeführt werden, ohne dass aufgrund unzureichender Entwicklungskräfte und -zeit Unit-Tests erstellt werden. (Es ist jetzt anders, aber das Projekt des vorherigen Jobs und des vorherigen Jobs war so.) Außerdem habe ich bereits eine große Menge an Quellcode und möchte von nun an einen Komponententest erstellen, aber wo kann ich anfangen? Ich denke, es gibt viele Situationen, in denen Sie es nicht wissen.

Ich dachte da. In einer solchen Welt, in der KI und RPA (Robotic Process Automation) jetzt boomt, gibt es meiner Meinung nach bereits Tools, die Quellcode analysieren und automatisch Komponententests erstellen. Ist es nicht so im Jahr 2020 ...? Wann.

Wir im Jahr 2020 (Bild): 2020年イメージ図

Finden Sie heraus, welche Tools verfügbar sind

Ich werde sofort im Internet nach verfügbaren Tools suchen. Die Suchbedingung lautet "Unit-Test automatisch generieren". Da ich ein Ingenieur bin, der hauptsächlich Java verwendet, füge ich der Bedingung auch "Java" hinzu.

Überraschenderweise gibt es nur wenige Suchergebnisse und alte Artikel sind hier und da zu sehen, so dass ich mich ein wenig unwohl fühlte ... (´ ´ ω ・ `), aber ich habe ungefähr vier gute gefunden.

Ich wusste nicht, wie ich es verwenden sollte, indem ich mir die Übersicht ansah, also erstellte ich einen Testcode aus dem tatsächlichen Quellcode und bewertete ihn. Wir haben die folgenden zwei Arten von Quellcode vorbereitet.

  1. [Klasse, deren Verarbeitung nur in der Klasse geschlossen ist und nur zustandslose Methoden hat](https://github.com/policeman-kh/generate_test/blob/master/src/main/java/test/NumberUtils. Java)
  2. Spring MVC Service Class

Ich wollte Methode 1 etwas verzweigen und der Bewertung die Testabdeckungsrate hinzufügen. 2 ist eine Klasse mit DI-Instanzen (Dependency Injection). Ich möchte, dass Sie die DI-Instanz durch eine Verspottung von Mockito im Testcode ersetzen. Ich habe ein Gefühl.

Der spezifische Quellcode wurde auf GitHub als ein Projekt zusammen mit dem erstellten Testcode vorbereitet. An einigen Stellen gibt es Links zu GitHub. Weitere Informationen finden Sie hier.

Einführung und Bewertung von Werkzeugen

Jetzt möchte ich jedes Tool vorstellen und den generierten Testcode auswerten.

TestMe

Der generierte Testcode (teilweise) ist unten. Die DI-Instanz wird mit Mockito verspottet. __Hört sich gut an! __ __ Da der Testcode nur gemäß der Vorlage generiert wird, gibt es fast keine Abdeckungsrate, und es ist erforderlich, ihn basierend auf dem generierten Testcode separat zu entwickeln. Die Geschwindigkeit der automatischen Generierung beträgt jedoch nur wenige Sekunden, und ich hatte den Eindruck, dass sie im Vergleich zum Erstellen von Testcode von Grund auf nicht schlecht war.

Bewertung: Geschwindigkeit: ★★★★★ (einige Sekunden) Abdeckung: Anpassung: ★★ (Test-Framework kann ausgewählt werden)

Klicken Sie hier, um den Testcode und die Generierung anzuzeigen

class ZipCodeServiceTest {
    @Mock
    ZipCodeApi zipCodeApi;
    @InjectMocks
    ZipCodeService zipCodeService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void testSearch() throws IOException {
        when(zipCodeApi.search(anyString())).thenReturn(null);

        List<ZipCodeData> result = zipCodeService.search("zipCode");
        Assertions.assertEquals(
                Arrays.<ZipCodeData>asList(
                        new ZipCodeData("zipcode", "prefcode", "address1", "address2", "address3", "kana1",
                                        "kana2", "kana3")), result);
    }
}

Squaretest

Ist es fast dasselbe wie TestMe? Es ist ein Eindruck, aber Sie können die Vorlage auf dem Einstellungsbildschirm bearbeiten. Ich möchte eine andere Bibliothek wie AssertJ oder Hamcrest für die Assertion verwenden, daher ist dieser Bereich einfach zu verwenden. Wenn es sich nicht um eine kostenpflichtige Lizenz handelt __, möchte ich sie verwenden.

Bewertung: Geschwindigkeit: ★★★★★ (einige Sekunden) Abdeckung: Anpassung: ★★★★ (Testframework auswählen, Vorlage bearbeiten)

Klicken Sie hier, um den Testcode zu erhalten und zu erfahren, wie er generiert wird

class ZipCodeServiceTest {

    @Mock
    private ZipCodeApi mockZipCodeApi;

    private ZipCodeService zipCodeServiceUnderTest;

    @BeforeEach
    void setUp() {
        initMocks(this);
        zipCodeServiceUnderTest = new ZipCodeService(mockZipCodeApi);
    }

    @Test
    void testSearch() throws Exception {
        // Setup
        final List<ZipCodeData> expectedResult = Arrays.asList(
                new ZipCodeData("zipcode", "prefcode", "address1", "address2", "address3", "kana1", "kana2",
                                "kana3"));

        // Run the test
        final List<ZipCodeData> result = zipCodeServiceUnderTest.search("zipCode");

        // Verify the results
        assertEquals(expectedResult, result);
    }
}

EvoSuite

Der aus 2 erstellte Testcode war nicht gut genug, daher wird der Testcode (Teil) von 1 unten beschrieben.

Das Generieren des Testcodes dauert 3 Minuten. Dieser Bereich kann jedoch mit dem Argument zum Zeitpunkt der Generierung geändert werden. Betrachtet man die Abdeckungsrate des Testcodes ... __100% __ Erstaunlich! EvoSuiteカバレッジ率

Der generierte Testcode ist jedoch nicht lesbar und ich möchte ihn später nicht manuell pflegen. Viele unklare Anmerkungen werden hinzugefügt, und der Punkt, an dem die Basisklasse von EvoSuite geerbt wird, ist ebenfalls etwas unbefriedigend. Schauen Sie sich zum Verspotten [1 Testcode] an (https://github.com/policeman-kh/generate_test/blob/master/src/test/java/test/evosuite/zipcode/ZipCodeService_ESTest.java). Es wurde jedoch nicht richtig eingestellt. Dieses Problem besagt, dass es beim Generieren von Testcode mit Argumenten angepasst werden kann, aber zur Laufzeit ein Fehler auftritt und ein Mock wird. Es war nicht möglich, einen Testcode zu generieren. (Auf dem Weg verlassen)

Die Abdeckungsrate ist jedoch sehr gut, daher ist es besser, sie zum Auffinden von Fehlern beim Erstellen einer zustandslosen und öffentlichen API zu verwenden. Ich fühle mich wie.

Bewertung: Geschwindigkeit: ★★ (3 Minuten) Abdeckung: ★★★★★ (100%!) Anpassung: ★★ (Einige können beim Generieren von Testcode durch Argumente angegeben werden.)

Klicken Sie hier, um den Testcode und das Generieren anzuzeigen

@RunWith(EvoRunner.class) @EvoRunnerParameters(mockJVMNonDeterminism = true, useVFS = true, useVNET = true, resetStaticState = true, separateClassLoader = true, useJEE = true) 
public class NumberUtils_ESTest extends NumberUtils_ESTest_scaffolding {

  @Test(timeout = 4000)
  public void test00()  throws Throwable  {
      boolean boolean0 = NumberUtils.isOddNumberBetween1And50(50);
      assertFalse(boolean0);
  }
// omit other testcases.

Randoop

Was Sie tun können, ist fast das gleiche wie Evosuite. Die Abdeckung betrug ebenfalls 100%. __ Gut. __ __ Es ist nicht einfach zu bedienen, da es nur eine Befehlszeilenausführung zum Generieren von Testcode gibt, aber ich denke, es ist gut, dass Runtime Jar nicht erforderlich ist, um den generierten Testcode auszuführen.

Bewertung: Geschwindigkeit: ★★ (einige Minuten) Abdeckung: ★★★★★ (100%!) Anpassung: ★★ (Einige können beim Generieren von Testcode durch Argumente angegeben werden.)

Klicken Sie hier, um den Testcode und das Generieren anzuzeigen

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NumberUtilsTest {

    public static boolean debug = false;

    @Test
    public void test01() throws Throwable {
        if (debug)
            System.out.format("%n%s%n", "RegressionTest0.test01");
        // The following exception was thrown during execution in test generation
        try {
            boolean boolean1 = test.NumberUtils.isEvenNumberBetween1And10WithBadCode((-1));
            org.junit.Assert.fail("Expected exception of type java.lang.IllegalArgumentException; message: input should be between 1 and 10.");
        } catch (java.lang.IllegalArgumentException e) {
        // Expected exception.
        }
    }

Zusammenfassung

Bisher haben wir die vier automatischen Erstellungstools für Unit-Tests untersucht und bewertet. Um ehrlich zu sein, ich denke, es ist weit von dem entfernt, was ich erwartet hatte, aber ich denke, es war gut, die aktuelle Situation zu kennen.

Der in dieser Studie verwendete Quellcode, Testcode, Bibliothekssatz und HowTo ReadMe werden auf dem GitHub unten gespeichert. Wenn Sie mit diesen Tools Testcode erstellen möchten, würden wir uns freuen, wenn Sie darauf verweisen könnten.

Investigation of auto generation unit tests with Java

Nun, der lange Adventskalender ist heute vorbei. Vielen Dank an alle, sowohl Leser als auch Schriftsteller! __ __ Ich wünsche dir ein schönes Jahr!

Recommended Posts

Ich habe das automatische Tool zum Erstellen von Komponententests überprüft (Version Ende 2019).
Automatische Erstellung eines Java-Unit-Testergebnisberichts
[Circle CI] Ich war süchtig nach dem automatischen Test von Circle CI (Rails + MySQL) [Memo]
Ich habe den Teil von java.net.URL # getPath überprüft
Ich habe die Anzahl der Taxis mit Ruby überprüft
Probieren Sie Progate Free Edition [Java I]
Ich habe versucht, eine japanische Version der Automatik-Mail von Rails / devise zu erstellen
Ich habe ein Tool erstellt, um den Unterschied zwischen CSV-Dateien auszugeben
Ich war süchtig nach der API-Version min23 von registerTorchCallback
[Java Edition] Geschichte der Serialisierung
Überprüfen Sie die Version von Cent OS
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von Long gelesen
Holen Sie sich die ID der automatischen Nummerierung
Ich habe die Quelle von Short gelesen
Bedeutung der Existenz eines Unit-Tests (Selbstdiskussion)
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
Ich erhalte folgende Fehler: Der Benutzer muss im Unit-Model-Test vorhanden sein
Da der Unit-Test des PJ, für den ich verantwortlich war, ein Höllenbild war, werde ich meinen eigenen Leitfaden veröffentlichen (?)