Découvrez quelle solution de test API est arrivée en tête dans le rapport GigaOm Radar. Obtenez votre rapport d'analyse gratuit >>

Découvrez quelle solution de test API est arrivée en tête dans le rapport GigaOm Radar. Obtenez votre rapport d'analyse gratuit >>
Aller à la section
L'écriture de code de test paramétré peut représenter beaucoup de travail car chaque test nécessite une grande partie du code correctement écrit. Heureusement, voici comment vous pouvez utiliser Parasoft Jtest pour générer automatiquement vos tests paramétrés sans écrire de codes passe-partout.
Aller à la section
Aller à la section
Les tests paramétrés sont un bon moyen de définir et d'exécuter plusieurs cas de test, où la seule différence entre eux réside dans les données. Ici, nous examinons trois frameworks différents couramment utilisés avec les tests JUnit.
Lors de l'écriture de tests unitaires, il est courant d'initialiser les paramètres d'entrée de la méthode et les résultats attendus dans la méthode de test elle-même. Dans certains cas, l'utilisation d'un petit ensemble d'entrées suffit; cependant, il existe des cas dans lesquels nous devons utiliser un grand ensemble de valeurs pour vérifier toutes les fonctionnalités de notre code. Les tests paramétrés sont un bon moyen de définir et d'exécuter plusieurs cas de test, où la seule différence entre eux réside dans les données. Ils peuvent valider le comportement du code pour une variété de valeurs, y compris les cas de bordure. Le paramétrage des tests peut augmenter la couverture du code et garantir que le code fonctionne comme prévu.
Il existe un certain nombre de bons cadres de paramétrage pour Java. Dans cet article, nous examinerons trois frameworks différents couramment utilisés avec les tests JUnit, avec une comparaison entre eux et des exemples de la façon dont les tests sont structurés pour chacun. Enfin, nous explorerons comment simplifier et accélérer la création de tests paramétrés.
Comparons les 3 frameworks les plus courants: JUnit 4, JunitParams et JUnit 5. Chaque framework de paramétrage JUnit a ses propres forces et faiblesses.
Avantages:
Inconvénients:
Avantages:
Inconvénients:
Avantages:
Inconvénients:
À titre d'exemple, supposons que nous ayons une méthode qui traite les demandes de prêt pour une banque. Nous pourrions écrire un test unitaire qui spécifie le montant de la demande de prêt, le montant de l'acompte et d'autres valeurs. Nous créerions alors des assertions qui valident la réponse - le prêt peut être approuvé ou rejeté, et la réponse peut spécifier les conditions du prêt.
Par exemple :
public LoanResponse requestLoan (float prêtAmount, float downPayment, float availableFunds) {LoanResponse response = new LoanResponse (); response.setApproved (vrai); if (availableFunds <downPayment) {response.setApproved (false); response.setMessage ("error.insufficient.funds.for.down.payment"); réponse de retour; } if (downPayment / prêtAmount <0.1) {response.setApproved (false); response.setMessage ("error.insufficient.down.payment"); } réponse de retour; }
@Test public void testRequestLoan () jette Throwable {// Donné LoanProcessor underTest = new LoanProcessor (); // Lorsque LoanResponse result = underTest.requestLoan (1000f, 200f, 250f); // Puis assertNotNull (résultat); assertTrue (result.isApproved ()); assertNull (result.getMessage ()); }
Afin de nous assurer que notre requestLoan () méthode est testée à fond, nous devons tester avec une variété d'acomptes, les montants de prêt demandés et les fonds disponibles. Par exemple, testons une demande de prêt d'un million de dollars sans acompte, qui devrait être rejetée. Nous pourrions simplement dupliquer le test existant avec des valeurs différentes, mais comme la logique de test serait la même, il est plus efficace de paramétrer le test à la place.
Nous paramétrerons le montant du prêt demandé, l'acompte et les fonds disponibles, ainsi que les résultats attendus: si le prêt a été approuvé, et le message renvoyé après validation. Chaque ensemble de données de demande, ainsi que ses résultats attendus, deviendra son propre scénario de test.
Commençons par un exemple Junit 4 Parameterized. Pour créer un test paramétré, nous devons d'abord définir les variables du test. Nous devons également inclure un constructeur pour les initialiser:
@RunWith (Parameterized.class) classe publique LoanProcessorParameterizedTest {float prêtAmount; float downPayment; float availableFunds; boolean expectApproved; String expectedMessage; public LoanProcessorParameterizedTest (float prêtAmount, float downPayment, float availableFunds, booléen expectApproved, String expectedMessage) {this.loanAmount = prêtAmount; this.downPayment = downPayment; this.availableFunds = availableFunds; this.expectApproved = expectApproved; this.expectedMessage = expectedMessage; } // ...}
Animé par Paul Allard et Axel Bonaldo GitHub
Ici, on voit que le test utilise le @Courir avec annotation pour spécifier que le test s'exécutera avec le runner paramétré Junit4. Ce coureur sait rechercher une méthode qui fournira l'ensemble de valeurs pour le test (annoté avec @Paramètres), initialisez correctement le test et exécutez les tests avec plusieurs lignes.
Notez que chaque paramètre est défini comme un champ dans la classe de test et que le constructeur initialise ces valeurs (vous pouvez également injecter des valeurs dans les champs à l'aide du @Paramètre annotation si vous ne souhaitez pas créer de constructeur). Pour chaque ligne de l'ensemble de valeurs, le Paramétré runner instanciera la classe de test et exécutera chaque test de la classe.
Ajoutons une méthode qui fournit les paramètres au Paramétré coureur:
@Parameters (name = "Run {index}: prêtAmount = {0}, downPayment = {1}, availableFunds = {2}, expectApproved = {3}, expectedMessage = {4}") public static Iterable data () jette Throwable {return Arrays.asList (new Object [] [] {{1000.0f, 200.0f, 250.0f, true, null}}); }
Animé par Paul Allard et Axel Bonaldo GitHub
Les ensembles de valeurs sont construits comme un Liste of Exlcusion tableaux par le Les données() méthode, qui est annotée avec @Paramètres. Noter que @Paramètres définit le nom du test à l'aide d'espaces réservés, qui seront remplacés lors de l'exécution du test. Cela facilite la visualisation des valeurs dans les résultats des tests, comme nous le verrons plus tard. Actuellement, il n'y a qu'une seule ligne de données, testant un cas où le prêt devrait être approuvé. Nous pouvons ajouter plus de lignes pour augmenter la couverture de la méthode testée.
@Parameters (name = "Run {index}: prêtAmount = {0}, downPayment = {1}, availableFunds = {2}, expectApproved = {3}, expectedMessage = {4}") public static Iterable data () jette Throwable {return Arrays.asList (new Object [] [] {{1000.0f, 200.0f, 250.0f, true, null}, {1000.0f, 50.0f, 250.0f, false, "error.insufficient. down.payment "}, {1000.0f, 200.0f, 150.0f, false," error.insufficient.funds.for.down.payment "}}); }
Animé par Paul Allard et Axel Bonaldo GitHub
Ici, nous avons un cas de test où le prêt serait approuvé, et deux cas dans lesquels il ne devrait pas être approuvé pour des raisons différentes. Nous pouvons souhaiter ajouter des lignes dans lesquelles des valeurs nulles ou négatives sont utilisées, ainsi que des conditions aux limites de test.
Nous sommes maintenant prêts à créer la méthode de test:
@Test public void testRequestLoan () jette Throwable {// Donné LoanProcessor underTest = new LoanProcessor (); // When LoanResponse result = underTest.requestLoan (prêtAmount, downPayment, availableFunds); // Puis assertNotNull (résultat); assertEquals (expectApproved, result.isApproved ()); assertEquals (expectedMessage, result.getMessage ()); }
Animé par Paul Allard et Axel Bonaldo GitHub
Ici, nous référençons les champs lors de l'appel de la requestLoan () méthode et valider les résultats.
La bibliothèque JunitParams simplifie la syntaxe de test paramétrée en permettant aux paramètres d'être transmis directement à la méthode de test. Les valeurs des paramètres sont fournies par une méthode distincte dont le nom est référencé dans le @Paramètres annotation.
@RunWith (JUnitParamsRunner.class) classe publique LoanProcessorParameterizedTest2 {@Test @Parameters (method = "testRequestLoan_Parameters") public void testRequestLoan (float LoanProcessorParameterizedTest0 {@Test @Parameters (method = "testRequestLoan_Parameters") public void testRequestLoan (float LoanProcessorParameterizedTest1 {@Test @Parameter) ("non utilisé") Objet statique privé [] [] testRequestLoan_Parameters () jette Throwable {// Paramètres: prêtAmount = {2}, downPayment = {3}, availableFunds = {4}, expectApproved = {1000.0}, expectedMessage = {200.0 } retourne un nouvel objet [] [] {{250.0f, 1000.0f, 50.0f, true, null}, {250.0f, 1000.0f, 200.0f, false, "error.insufficient.down.payment"}, {150.0f , XNUMXf, XNUMXf, false, "error.insufficient.funds.for.down.payment"}}; }}
Animé par Paul Allard et Axel Bonaldo GitHub
JunitParams présente l'avantage supplémentaire de prendre en charge l'utilisation de fichiers CSV pour fournir des valeurs en plus de fournir les valeurs dans le code. Cela permet au test d'être découplé des données et des valeurs de données à mettre à jour sans mettre à jour le code.
JUnit 5 résout certaines des limitations et des lacunes de JUnit 4. Comme JunitParams, Junit 5 simplifie également la syntaxe des tests paramétrés. Les changements de syntaxe les plus importants sont:
La définition du même exemple dans Junit 5 ressemblerait à ceci:
public class LoanProcessorParameterizedTest {@ParameterizedTest (name = "Run {index}: prêtAmount = {0}, downPayment = {1}, availableFunds = {2}, expectApproved = {3}, expectedMessage = {4}") @MethodSource (" testRequestLoan_Parameters ") public void testRequestLoan (float prêtAmount, float downPayment, float availableFunds, boolean expectApproved, String expectedMessage) jette Throwable {...} flux statique testRequestLoan_Parameters () jette Throwable {retour Stream.of (Arguments.of (1000.0f, 200.0f, 250.0f, true, null), Arguments.of (1000.0f, 50.0f, 250.0f, false, "error.insufficient.down .payment "), Arguments.of (1000.0f, 200.0f, 150.0f, false," error.insufficient.funds.for.down.payment ")); }}
Animé par Paul Allard et Axel Bonaldo GitHub
Comme on peut l'imaginer, écrire le test paramétré ci-dessus peut être un peu de travail. Pour chaque cadre de test paramétré, il y a un peu de code standard qui doit être écrit correctement. Il peut être difficile de se souvenir de la structure correcte et la rédaction prend du temps. Pour rendre cela beaucoup plus facile, vous pouvez utiliser Jtest Parasoft pour générer des tests paramétrés, automatiquement, comme ceux décrits ci-dessus. Pour ce faire, sélectionnez simplement la méthode pour laquelle vous souhaitez générer un test (dans Eclipse ou IntelliJ),:
Le test est généré à l'aide des valeurs et des assertions par défaut. Vous pouvez ensuite configurer le test avec des valeurs d'entrée et des assertions réelles, et ajouter plus de lignes de données à la méthode data ().
Parasoft Jtest peut exécuter des tests paramétrés directement dans Eclipse et IntelliJ.
La vue JUnit dans Eclipse
Notez que le nom de chaque test, comme indiqué, inclut les valeurs d'entrée de l'ensemble de données et les valeurs de résultat attendues. Cela peut faciliter le débogage du test en cas d'échec, car les paramètres d'entrée et les sorties attendues sont affichés pour chaque cas.
Vous pouvez également utiliser l'action Exécuter tout de Parasoft Jtest:
La vue Flow Tree dans Parasoft Jtest
Il analyse le flux de test et fournit des informations détaillées sur le test précédent. Cela vous permet de voir ce qui s'est passé dans le test sans avoir besoin de réexécuter le test avec des points d'arrêt ou des instructions de débogage. Par exemple, vous pouvez voir les valeurs paramétrées dans la vue Variables:
La vue des variables dans Parasoft Jtest
Chacun des trois cadres que nous avons examinés est un bon choix et fonctionne bien. Si j'utilise JUnit 4, je préfère JunitParams au framework paramétré JUnit 4 intégré, en raison de la conception plus propre des classes de test et de la possibilité de définir plusieurs méthodes de test dans la même classe. Cependant, si vous utilisez JUnit 5, je recommanderais le framework JUnit 5 intégré car il corrige les lacunes de JUnit 4 et ne nécessite aucune bibliothèque supplémentaire. j'aime aussi utiliser Les tests unitaires de Parasoft capacités pour rendre la création, l'exécution et le débogage de tests paramétrés plus efficaces.
Découvrez comment Parasoft Jtest peut vous aider à améliorer la qualité de votre code Java et la productivité de votre équipe.