Mettre en œuvre un test piloté par table en Java

Cette entrée concerne le calendrier de l'avent GMO Ad Marketing 2018 (Https://qiita.com/advent-calendar/2018/gmo-am) [12/09] article. Il s'agit du premier marketing publicitaire OGM à participer au calendrier de l'Avent.

introduction

Dans le langage Go, il est courant d'écrire du code de test sous la forme de Test Driven Table. Le mot «Go-ness» est souvent utilisé par les ingénieurs de Go. Le code source doit toujours être écrit comme Go. Je pense qu'il y a des ambiguïtés dans le mot Go-ness, Le test basé sur la table est l'une des particularités de Go. Cette fois, je présenterai un exemple de mise en place de Go-ness vers Java.

Qu'est-ce que le test piloté par table?

Le test basé sur la table est décrit dans les pages suivantes. https://github.com/golang/go/wiki/TableDrivenTests

Dans Table Driven Test, un cas de test est représenté par une structure, qui est bouclée pour exécuter le test. Cette fois, par souci d'explication, j'ai créé un test partiel de pow.go.

package main

import (
	"testing"
	"math"
)

func TestPow(t *testing.T) {
	for _, tt := range []struct {
		name     string
		x        float64
		y        float64
		expected float64
	}{
		{"Pow(2,1)", 2, 1, 2},
		{"Pow(2,2)", 2, 2, 4},
		{"Pow(2,3)", 2, 3, 8},
		{"Pow(2,0)", 2, 0, 1},
		{"Pow(2,-1)", 2, -1, 0.5},
		{"Pow(0,2)", 0, 2, 0},
		{"Pow(2,+Inf)", 2, math.Inf(0), math.Inf(0)},
		{"Pow(2,-Inf)", 2, math.Inf(-1), 0},
		{"Pow(+Inf,2)", math.Inf(0), 2, math.Inf(0)},
		{"Pow(-Inf,2)", math.Inf(-1), 2, math.Inf(0)},
	} {
		t.Run(tt.name, func(t *testing.T) {
			result := math.Pow(tt.x, tt.y)
			if result != tt.expected {
				t.Errorf("expected: %v, result: %v", tt.expected, result)
			}
		})
	}
}

Dans cet exemple, la structure définit le nom du test, les arguments de méthode et les valeurs attendues. En écrivant comme ça, ce que chaque valeur représente Cela permet également de voir plus facilement ce que vous testez.

Test piloté par table implémenté en Java

Utilisez les fonctionnalités ajoutées dans JUnit 5 pour implémenter le Test Driven Table en Java.

Cette fois, j'ai créé un test de puissance pour la classe de mathématiques. L'exemple utilise lombok pour garder le code source simple.

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;
import org.junit.jupiter.api.*;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MathTest {

    @Nested
    static class Pow {

        @AllArgsConstructor
        @Getter
        @Accessors(fluent = true)
        static class TestCase {
            private String name;
            private double x;
            private double y;
            private double expected;
        }

        @TestFactory
        Stream<DynamicNode> testPow() {
            return Stream.of(
                    new TestCase("pow(2,1)", 2, 1, 2),
                    new TestCase("pow(2,2)", 2, 2, 4),
                    new TestCase("pow(2,3)", 2, 3, 8),
                    new TestCase("pow(2,0)", 2, 0, 1),
                    new TestCase("pow(2,-1)", 2, -1, 0.5),
                    new TestCase("pow(2,+Inf)", 2, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY),
                    new TestCase("pow(2,-Inf)", 2, Double.NEGATIVE_INFINITY, 0),
                    new TestCase("pow(+Inf,2)", Double.POSITIVE_INFINITY, 2, Double.POSITIVE_INFINITY),
                    new TestCase("pow(-Inf,2)", Double.NEGATIVE_INFINITY, 2, Double.POSITIVE_INFINITY)
            ).map(testCase -> DynamicTest.dynamicTest(
                    testCase.name(),
                    () -> {
                        double result = Math.pow(testCase.x(), testCase.y());
                        assertEquals(testCase.expected(), result);
                    })
            );
        }
    }

}

Dans JUnit 5, vous pouvez définir une classe interne avec `` @ Nested '' pour imbriquer les tests. Dans cet exemple, le test est défini par une classe interne appelée Pow.

À l'intérieur de Pow, nous définissons une classe interne appelée TestCase. Les champs TestCase définissent le nom du test, les arguments à transmettre à la méthode et le résultat attendu. La valeur utilisée dans chaque cas de test est transmise dans le constructeur TestCase.

Si vous utilisez une classe comme Tuple ici, Il est difficile de dire ce que représente chaque valeur que vous passez à Tuple, En ayant le cas de test dans une classe interne comme l'exemple Vous pouvez associer une valeur à un champ nommé.

Nous utilisons les nouveaux tests dynamiques de JUnit 5 (https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests) pour exécuter les tests. @testfactoryEn s'attachant à une méthode qui retourne un flux de nœud dynamique, une collection, etc. Vous pouvez exécuter le test de manière dynamique.

Résumé

En combinant les fonctionnalités de JUnit 5 avec les bienfaits du langage Go, J'ai pu écrire un test hautement lisible en Java. Ce serait formidable si nous pouvions continuer à intégrer les bons points d'autres langages, tels que Go-ness, dans Java.

Calendrier de l'Avent OGM 2018 qui dure jusqu'à Noël Restez à l'écoute pour plus de messages!

■ Techblog des ingénieurs est maintenant disponible! https://techblog.gmo-ap.jp/ ■ Les blogs et les emplois de page Wantedly sont ouverts au public! ~ https://www.wantedly.com/projects/199431 ■ Page de recrutement des ingénieurs - Cliquez ici pour plus d'informations sur le bien-être et divers systèmes https://www.gmo-ap.jp/engineer/ ■ Recrutement étudiant stagiaire ingénieur! -Expérience du site de développement avec un stagiaire rémunéré- https://hrmos.co/pages/gmo-ap/jobs/0000027

Recommended Posts

Mettre en œuvre un test piloté par table en Java
Le programmeur Java a touché le langage Go (implémenter l'héritage Java en langage Go)
Modèle de façade en Java
Motif singleton en Java
Modèle de poids mouche en Java
Modèle d'observateur en Java
Autorisations Linux sur Java
Utiliser DataFrame en Java
Modèle d'itérateur en Java
Mettre en œuvre des recommandations en Python
Implémenter XENO avec python
Modèle de décorateur en Java
Définition de table dans SQL Alchemy
Implémenter sum en Python
Modèle de prototype en Java
Implémenter Traceroute dans Python 3
Modèle de proxy en Java
Tutoriel pour faire du développement piloté par les tests (TDD) avec Flask-2 Decorators
J'ai essayé de programmer le test du chi carré en Python et Java.
Tutoriel pour faire du développement piloté par les tests (TDD) avec Flask-1 Test Client Edition
Implémenter LSTM AutoEncoder avec Keras
Implémenter la fonction de suivi dans Django
Algorithme en Python (jugement premier)
Renommer les colonnes de table dans Django3
Implémenter la fonction de minuterie dans pygame
Implémenter le transfert de style avec Pytorch
Mettre en œuvre une fermeture récursive dans Go
Sortie de la structure de table dans Django
Implémenter Naive Bayes dans Python 3.3
Implémenter UnionFind (équivalent) en 10 lignes
Implémenter d'anciens chiffrements en python
Implémenter Redis Mutex en Python
Implémenter l'extension en Python
Mettre en œuvre un RPC rapide en Python
Modèle de méthode de modèle en Java
Implémenter l'algorithme de Dijkstra en python
Implémenter le bot de discussion Slack en Python
Si vous écrivez un test piloté par table go en python, il peut être préférable d'utiliser subTest
Implémenter le processus gaussien dans Pyro
Définir le test python dans jenkins
Comment implémenter du code Java en arrière-plan de Red Hat (Linux ONE)