Partager via


Procédure pas à pas : développement piloté par les tests à l’aide de l’Explorateur de tests

Créez des tests unitaires pour vous aider à maintenir votre code correctement opérationnel par le biais de modifications de code incrémentielles. Il existe plusieurs frameworks que vous pouvez utiliser pour écrire des tests unitaires, y compris certains développés par des tiers. Certaines infrastructures de test sont spécialisées pour les tests dans différents langages ou plateformes. L’Explorateur de tests fournit une interface unique pour les tests unitaires dans l’une de ces infrastructures. Pour plus d’informations sur l’Explorateur de tests, consultez Exécuter des tests unitaires avec l’Explorateur de tests et le FAQ sur l’Explorateur de tests.

Cette procédure pas à pas montre comment développer une méthode testée en C# à l’aide de Microsoft Test Framework (MSTest). Vous pouvez facilement l’adapter à d’autres langages ou à d’autres frameworks de test, tels que NUnit. Pour plus d’informations, consultez Installer des frameworks de test unitaire tiers.

Créer un test et générer du code

  1. Créez un projet bibliothèque de classes C# pour .NET ou .NET Standard. Ce projet contiendra le code que nous voulons tester. Nommez le projet MyMath.

  2. Dans la même solution, ajoutez un nouveau projet de test MSTest pour .NET.

    Dans Visual Studio 2019 version 16.9, le nom du modèle de projet MSTest est projet de test unitaire.

    Nommez le projet de test MathTests.

    Nouveaux projets de code et de test

    Nouveaux projets de code et de test

  3. Dans le projet de test, écrivez une méthode de test simple qui vérifie le résultat obtenu pour une entrée spécifique. Ajoutez le code suivant à la classe Test1 ou UnitTest1 :

    [TestMethod]
    public void BasicRooterTest()
    {
      // Create an instance to test:
      Rooter rooter = new Rooter();
      // Define a test input and output value:
      double expectedResult = 2.0;
      double input = expectedResult * expectedResult;
      // Run the method under test:
      double actualResult = rooter.SquareRoot(input);
      // Verify the result:
      Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100);
    }
    
  4. Générez un type à partir du code de test.

    1. Placez le curseur sur Rooter, puis ouvrez le menu ampoule.

      Choisissez Générer un nouveau type.

      Générer une nouvelle action rapide de type

      Choisissez Générer le type « Rooter »>Générer un nouveau type.

      Générer une nouvelle action rapide de type

    2. Dans la boîte de dialogue Générer un type , définissez Project sur MyMath, le projet de bibliothèque de classes, puis choisissez OK.

      Boîte de dialogue Générer un type dans Visual Studio 2019

      Boîte de dialogue Générer un type dans Visual Studio 2019

  5. Générez une méthode à partir du code de test. Placez le curseur surSquareRoot, puis dans le menu ampoule, choisissez Générer la méthode « SquareRoot » ou « Rooter.SquareRoot ».

  6. Exécutez le test unitaire.

    1. Ouvrez l’Explorateur de tests.

      Pour ouvrir l’Explorateur de tests à partir du menu Test , choisissez Explorateur de tests.

      Pour ouvrir l’Explorateur de tests à partir du menu Test, choisissezl’Explorateur de tests>.

    2. Dans l’Explorateur de tests, choisissez le bouton Exécuter tout pour exécuter le test.

    La solution est construite, et les tests s’exécutent et échouent.

  7. Sélectionnez le nom du test.

    Les détails du test s’affichent dans le volet Résumé des détails du test.

    Résumé des détails du test dans l’Explorateur de tests

    Résumé des détails du test dans l’Explorateur de tests

  8. Sélectionnez le lien supérieur sous Stack Trace pour accéder à l’emplacement où le test a échoué.

À ce stade, vous avez créé un test et un stub que vous pouvez modifier pour que le test réussisse.

Vérifier une modification du code

  1. Dans le fichier Class1.cs , améliorez le code de SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. Dans l’Explorateur de tests, choisissez Exécuter tout.

    La solution se compile, et le test s’exécute et réussit.

    Explorateur de tests montrant un test réussi

    Explorateur de tests montrant un test réussi

Étendre la gamme d'entrées

Pour améliorer notre confiance que le code fonctionne dans tous les cas, ajoutez des tests qui essaient une plage plus large de valeurs d’entrée.

Conseil / Astuce

Évitez de modifier les tests existants qui réussissent. Au lieu de cela, ajoutez de nouveaux tests. Modifiez les tests existants uniquement lorsque les exigences de l’utilisateur changent. Cette stratégie permet de s’assurer que vous ne perdez pas les fonctionnalités existantes au fur et à mesure que vous travaillez pour étendre le code.

  1. Dans la classe de test, ajoutez le test suivant, qui tente une plage de valeurs d’entrée :

    [TestMethod]
    public void RooterValueRange()
    {
        // Create an instance to test.
        Rooter rooter = new Rooter();
    
        // Try a range of values.
        for (double expected = 1e-8; expected < 1e+8; expected *= 3.2)
        {
            RooterOneValue(rooter, expected);
        }
    }
    
    private void RooterOneValue(Rooter rooter, double expectedResult)
    {
        double input = expectedResult * expectedResult;
        double actualResult = rooter.SquareRoot(input);
        Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000);
    }
    
  2. Dans l’Explorateur de tests, choisissez Exécuter tout.

    Le nouveau test échoue (bien que le premier test réussisse toujours). Pour trouver le point d’échec, sélectionnez le test défaillant, puis examinez les détails dans le volet Résumé des détails du test .

  3. Inspectez la méthode en cours de test pour voir ce qui pourrait être incorrect. Modifiez le SquareRoot code comme suit :

    public double SquareRoot(double input)
    {
      double result = input;
      double previousResult = -input;
      while (Math.Abs(previousResult - result) > result / 1000)
      {
        previousResult = result;
        result = result - (result * result - input) / (2 * result);
      }
      return result;
    }
    
  4. Dans l’Explorateur de tests, choisissez Exécuter tout.

    Les deux tests sont réussis maintenant.

Ajouter des tests pour des cas exceptionnels

  1. Ajoutez un nouveau test pour les entrées négatives :

    [TestMethod]
    public void RooterTestNegativeInput()
    {
        Rooter rooter = new Rooter();
        Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
    }
    
  2. Dans l’Explorateur de tests, choisissez Exécuter tout.

    Le nouveau test échoue.

    Si la méthode en test s'exécute en boucle, choisissez Annuler dans la barre d'outils de l'Explorateur de tests. Le test arrête l’exécution et échoue.

  3. Corrigez le SquareRoot code en ajoutant l’instruction suivante if au début de la méthode :

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  4. Dans l’Explorateur de tests, choisissez Exécuter tout.

    Tous les tests passent.

Refactoriser le code sous test

Refactorisez le code, mais ne modifiez pas les tests.

Conseil / Astuce

Une refactorisation est une modification destinée à améliorer ou à faciliter la compréhension du code. Il n’est pas destiné à modifier le comportement du code, et par conséquent, les tests ne sont pas modifiés.

Nous vous recommandons d’effectuer des étapes de refactorisation séparément des étapes qui étendent les fonctionnalités. Conserver les tests inchangés vous donne confiance que vous n’avez pas introduit accidentellement de bogues lors de la refactorisation.

  1. Modifiez la ligne qui calcule result dans la SquareRoot méthode comme suit :

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
    
        double result = input;
        double previousResult = -input;
        while (Math.Abs(previousResult - result) > result / 1000)
        {
            previousResult = result;
            result = (result + input / result) / 2;
            //was: result = result - (result * result - input) / (2*result);
        }
        return result;
    }
    
  2. Choisissez Exécuter tout, puis vérifiez que tous les tests réussissent toujours.

    Explorateur de tests montrant 3 tests réussis

    Explorateur de tests montrant 3 tests réussis