Que recherchez-vous ?
Hero background image
Comment exécuter des tests automatisés pour vos jeux avec le Unity Test Framework ?

Dans le domaine du développement de jeux, les tests manuels peuvent rapidement devenir répétitifs et sujets aux erreurs. Vous êtes-vous déjà retrouvé dans l'un de ces cycles de test apparemment sans fin alors que vous travaillez sur une nouvelle fonctionnalité ou que vous essayez de corriger un bogue ?

En automatisant vos tests de code, vous pouvez consacrer plus de temps au développement créatif du jeu et moins aux tâches répétitives (mais importantes) d'assurance qualité qui garantissent que l'ajout, la suppression ou la modification de code ne casse pas votre projet.

Unity vous aide à créer, gérer et exécuter des tests automatisés pour vos jeux avec le Unity Test Framework.

Tester de deux manières dans Unity Test Framework

Unity Test Framework (UTF) vous permet de tester le code de votre projet en mode édition et en mode lecture. Vous pouvez également cibler le code de test pour différentes plateformes telles que les plateformes autonomes, iOS ou Android.

L'UTF est installé en l'ajoutant à votre projet à l'aide du gestionnaire de paquets.

Sous le capot, UTF s'intègre à NUnit, une bibliothèque de test open source bien connue pour les langages .NET.

Il existe deux catégories principales de tests que vous pouvez écrire avec UTF : le mode édition et le mode lecture :

Les tests en mode édition s'exécutent dans l'éditeur Unity et ont accès à la fois à l'éditeur et au code du jeu. Cela signifie que vous pouvez tester vos extensions personnalisées de l'éditeur ou utiliser des tests pour modifier des paramètres dans l'éditeur et passer en mode lecture, ce qui est utile pour ajuster les valeurs de l'inspecteur et exécuter ensuite des tests automatisés avec de nombreux paramètres différents.

Les tests en mode "Play" vous permettent d'exercer le code de votre jeu au moment de l'exécution. Les tests sont généralement exécutés en tant que coroutines à l'aide de l'attribut [UnityTest]. Cela vous permet de tester un code qui peut être exécuté dans plusieurs cadres. Par défaut, les tests en mode lecture s'exécutent dans l'éditeur, mais vous pouvez également les exécuter dans un lecteur autonome pour différentes plates-formes cibles.

tests automatisés
Le package Third Person Character Controller, disponible dans l'Unity Asset Store
Comment tester Unity Test Framework

Pour suivre cet exemple, vous devez installer le paquet Starter Assets - Third Person Character Controller depuis le Unity Asset Store et l'importer dans un nouveau projet.

tests automatisés
Le fichier manifest.json
Mise en place du cadre de test Unity

Installez UTF via Fenêtre > Gestionnaire de paquets. Recherchez Test Framework dans le registre Unity du gestionnaire de paquets. Veillez à sélectionner la version 1.3.3 (la plus récente au moment de la rédaction du présent document).

Une fois UTF installé, ouvrez le fichier Packages/manifest.json avec un éditeur de texte, et ajoutez une section testables après les dépendances, comme ceci :

,
"testables": [
"com.unity.inputsystem"
]

Enregistrer le fichier. Cela sera utile plus tard, lorsque vous devrez faire référence à l'assemblage Unity.InputSystem.TestFramework pour tester et émuler l'entrée du joueur.

Retournez à l'éditeur et laissez la nouvelle version s'installer.

tests automatisés
Références de définition d'assemblage dans l'inspecteur pour le contrôleur de personnage à la troisième personne
Définitions de l'assemblage de test

Cliquez sur Fenêtre > Général > Test Runner pour afficher la fenêtre d'édition du Test Runner.

Dans cette partie du tutoriel, l'accent sera mis sur la création de tests en mode lecture. Plutôt que d'utiliser les options Créer un dossier d'assemblage de test dans la fenêtre Test Runner, vous les créerez dans la fenêtre Projet.

La racine du dossier Project Assets étant mise en évidence, cliquez avec le bouton droit de la souris et choisissez Create > Testing > Tests Assembly Folder.

Un dossier de projet Tests est ajouté, contenant un fichier Tests.asmdef (définition d'assemblage). Ceci est nécessaire pour que les tests puissent référencer les modules et les dépendances de votre jeu.

Le code du contrôleur de caractères sera référencé dans les tests et nécessitera également une définition d'assemblage. Ensuite, vous mettrez en place des définitions et des références d'assemblages pour faciliter les tests entre les modules.

Cliquez avec le bouton droit de la souris sur le dossier de projet Assets/StarterAssets/InputSystem et choisissez Créer > Définition d'assemblage. Donnez-lui un nom descriptif, par exemple StarterAssetsInputSystem.

Sélectionnez le nouveau fichier StarterAssetsInputSystem.asmdef et, à l'aide de l'inspecteur, ajoutez une référence de définition d'assemblage à Unity.InputSystem. Cliquez sur Appliquer.

Cliquez avec le bouton droit de la souris sur le dossier de projet Assets/StarterAssets/ThirdPersonController/Scripts, puis choisissez Créer > Définition d'assemblage. Donnez-lui un nom descriptif, par exemple ThirdPersonControllerMain.

Comme vous l'avez fait avec la définition de l'assemblage précédent, ouvrez ThirdPersonControllerMain dans l'inspecteur et sélectionnez les références pour :

- Unity.InputSystem

- StarterAssetsInputSystem

Cliquez sur Appliquer.

tests automatisés
Ajout de références aux définitions d'assemblages
Ajout de références aux définitions d'assemblages

Pour émuler certaines parties du système d'entrée, vous devrez y faire référence dans vos tests. En outre, vous devrez faire référence à l'espace de noms StarterAssets dans un assemblage que vous créerez pour le code du Third Person Controller.

Ouvrez Tests.asmdef dans l'inspecteur et ajoutez une référence aux définitions d'assemblages suivantes :

- UnityEngine.TestRunner

- UnityEditor.TestRunner

- Unity.InputSystem

- Unity.InputSystem.TestFramework

- ThirdPersonControllerMain

Cliquez sur Appliquer.

La fenêtre "Build Settings" (paramètres de construction)
La fenêtre "Build Settings" (paramètres de construction)
Votre premier test

Votre premier test portera sur les bases du chargement et du déplacement du personnage principal à partir de l'application Third Person Controller.

Commencez par configurer le nouveau projet avec une scène d'environnement de test simple et une ressource Prefab de personnage avec laquelle travailler.

Ouvrez la scène nommée Assets/StarterAssets/ThirdPersonController/Scenes/Playground.unity et enregistrez une copie en utilisant le menu File > Save As vers ce nouveau chemin : Assets/Scenes/SimpleTesting.unity

Si vous remarquez des matériaux roses dans la vue Jeu, utilisez le convertisseur de pipeline de rendu pour mettre à niveau les matériaux du pipeline de rendu intégré vers le pipeline de rendu universel (URP). Voir cet article pour un aperçu rapide.

Créez un nouveau dossier dans le dossier "Project Assets" appelé " Resources". Remarque : Le nom du dossier "Resources" est important ici pour permettre l'utilisation de la méthode Unity Resources.Load().

Faites glisser et déposez le GameObject PlayerArmature de la vue Scène dans le nouveau dossier Resources, et choisissez de créer un Prefab Original lorsque vous y êtes invité. Renommer l'asset Prefab Character.

Il s'agira du caractère de base Prefab utilisé dans vos tests ultérieurs.

Retirez le GameObject PlayerArmature de la nouvelle scène SimpleTesting et enregistrez les modifications apportées à la scène.

Pour la dernière étape de la configuration initiale du test, allez dans Fichier > Paramètres de construction, et choisissez Ajouter des scènes ouvertes pour ajouter la scène Scènes/SimpleTesting aux paramètres de construction.

Créer un script de test C#

Sélectionnez le dossier Tests dans le dossier Actifs du projet. Cliquez avec le bouton droit de la souris et choisissez Créer > Test > Script de test C#.

Nommez le nouveau script CharacterTests. Ouvrez le script dans votre IDE pour l'examiner de plus près.

Deux méthodes sont fournies avec le fichier de classe initial, démontrant quelques principes de base des tests.

Ensuite, vous veillerez à ce que les tests chargent une scène de jeu "axée sur les tests". Il s'agit d'une scène contenant le strict minimum requis pour tester le système ou le composant sur lequel vous vous concentrez.

Mettre à jour la classe CharacterTests pour ajouter deux nouvelles instructions d'utilisation et implémenter la classe InputTestFixture:

using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

public class CharacterTests : InputTestFixture

Ajoutez deux champs privés en haut de la classe CharacterTests :

GameObject character = Resources.Load<GameObject>("Character") ;
Clavier ;

Le champ "Caractère" contient une référence au préfabriqué "Caractère", chargé dans le dossier "Ressources". Keyboard contient une référence au périphérique d'entrée Keyboard fourni par l'InputSystem.

Surchargez la méthode Setup() de la classe InputTestFixture en fournissant votre propre méthode dans la classe CharacterTests :

public override void Setup()
{
SceneManager.LoadScene("Scenes/SimpleTesting");
base.Setup();
clavier = InputSystem.AddDevice<Keyboard>() ;

var mouse = InputSystem.AddDevice<Mouse>() ;
Press(mouse.rightButton);
Release(mouse.rightButton);;
}

La méthode Setup() exécute la méthode Setup() de la classe de base, puis configure votre propre classe CharacterTests en chargeant la scène de test et en initialisant le périphérique d'entrée du clavier.

L'entrée de la souris est ajoutée uniquement pour que le contrôleur à la troisième personne commence à recevoir des données du clavier simulé/virtuel. Il s'agit presque d'une action de "mise au point".

Pour votre premier test, vous allez instancier le personnage à partir du Prefab et affirmer qu'il n'est pas nul. Ajoutez la méthode suivante à votre classe de test :

[Test]
public void TestPlayerInstantiation()
{
GameObject characterInstance = GameObject.Instantiate(character, Vector3.zero, Quaternion.identity) ;
Assert.That(characterInstance, !Is.Null);
}

Pendant que vous y êtes, vous pourriez vouloir nettoyer les méthodes de test du modèle d'échantillon. Suppression des méthodes CharacterTestsSimplePasses et CharacterTestsWithEnumeratorPasses.

test réussi contrôle
La coche verte indique que le test a été passé avec succès.
Réussir son premier examen

Enregistrez le script et retournez à la fenêtre Test Runner dans l'éditeur. Mettez en évidence le test TestPlayerInstantiation et cliquez sur Run Selected.

La coche verte signifie que le test est réussi. Vous avez affirmé que le personnage peut être chargé à partir de ressources, instancié dans la scène de test et qu'il n'est pas nul à ce moment-là.

Vous avez peut-être remarqué que l'annotation [Test] a été utilisée pour ce test au lieu de l'annotation [UnityTest]. L'attribut UnityTest permet aux coroutines d'exécuter des tests sur plusieurs images. Dans ce cas, il suffit d'instancier le personnage et d'affirmer qu'il a été chargé.

En général, vous devriez utiliser l'attribut NUnit Test au lieu de l'attribut UnityTest en mode édition, sauf si vous devez donner des instructions spéciales, sauter une image ou attendre un certain temps en mode lecture.

Test du mouvement du personnage en mode lecture
Test du mouvement du personnage en mode lecture
Tests de mouvement des personnages

Ensuite, vous utiliserez le test UnityTest pour affirmer que le fait de maintenir enfoncée la touche avant du contrôleur fait avancer le personnage.

Ajoutez la nouvelle méthode de test fournie ci-dessous à votre classe CharacterTests.

Deux nouvelles méthodes d'aide au test sont apparues : Press() et Release(). Elles sont toutes deux fournies par la classe de base InputTestFixture et vous aident à émuler l'enfoncement et le relâchement d'un contrôle InputSystem.

La méthode TestPlayerMoves() effectue les opérations suivantes :

Instancie une instance du personnage à partir de la préfabrication du personnage à l'emplacement (X : 0, Y : 0, Z : 0)

Appuyer sur la touche flèche vers le haut du clavier virtuel pendant 1 seconde, puis la relâcher.

Attend 1 seconde de plus (pour que le personnage ralentisse et arrête de bouger)

Affirme que le caractère s'est déplacé à une position sur l'axe Z supérieure à 1,5 unité.

Enregistrez le fichier, revenez au Test Runner et exécutez le nouveau test.

Le script de la santé du joueur
Le script de la santé du joueur
Test des dommages causés par les chutes

Ensuite, vous allez tester un script Monobehaviour personnalisé en ajoutant un composant simple de santé du joueur.

Créez un nouveau script sous Assets/StarterAssets/ThirdPersonController/Scripts. Nommez-le PlayerHealth.

Ouvrez le script dans votre IDE et remplacez le contenu par le code fourni ci-dessous.

Un grand nombre de nouveaux codes ont été ajoutés ici. En résumé, ce script détermine si le personnage du joueur est en état de chute. Si le sol est touché une fois en état de chute, la santé du personnage est réduite de 10 %.

Localisez le Character Prefab sous Assets/Resources. Ouvrez le Prefab et ajoutez le nouveau composant de script PlayerHealth.

Ensuite, vous utiliserez la scène de test pour affirmer que la santé du joueur diminue lorsqu'il tombe d'un rebord.

En utilisant l'attribut [UnityTest], vous pouvez écrire un test de mode de jeu qui vérifie les dommages causés par les chutes. Lors d'une chute de plus de 0,2 seconde, le joueur devrait subir 0,1f de dégâts (l'équivalent de 10% de la santé maximale).

Dans la scène SimpleTesting, vous verrez un escalier menant à une corniche. Il s'agit d'une plateforme de test sur laquelle le personnage est lancé et sur laquelle le script PlayerHealth est testé.

Ouvrez à nouveau CharacterTests.cs et ajoutez une nouvelle méthode de test nommée TestPlayerFallDamage :

[UnityTest]
public IEnumerator TestPlayerFallDamage()
{
// faire apparaître le personnage dans une zone suffisamment élevée de la scène de test
GameObject characterInstance = GameObject.Instantiate(character, new Vector3(0f, 4f, 17.2f), Quaternion.identity) ;

// Obtient une référence au composant PlayerHealth et affirme qu'il est actuellement en pleine santé (1f).
var characterHealth = characterInstance.GetComponent<PlayerHealth>() ;
Assert.That(characterHealth.Health, Is.EqualTo(1f));

// Descendez du rebord et attendez la chute.
Press(keyboard.upArrowKey) ;
yield return new WaitForSeconds(0.5f) ;
Release(keyboard.upArrowKey);
yield return new WaitForSeconds(2f) ;

// Affirmer que 1 point de santé a été perdu en raison des dommages causés par la chute.
Assert.That(characterHealth.Health, Is.EqualTo(0.9f));
}

Vous devrez également ajouter une référence d'utilisation à l'espace de noms StarterAssets tout en haut du fichier de classe :

à l'aide de StarterAssets ;

Le test ci-dessus suit un schéma typique " arranger, agir, affirmer" (AAA), que l'on retrouve fréquemment dans les tests :

La section Arrange d'une méthode de test unitaire initialise les objets et fixe la valeur des données transmises à la méthode testée.

La section Act invoque la méthode testée avec les paramètres définis. Dans ce cas, l'invocation de la méthode testée est gérée par une interaction physique lorsque le joueur touche le sol après être tombé.

La section Assert vérifie que l'action de la méthode testée se comporte comme prévu.

Test Runner - exécution des tests
Un test pour s'assurer qu'un personnage tombe dans le jeu comme prévu, y compris qu'il subit la bonne quantité de dégâts.
Exécution du nouveau test

De retour dans l'éditeur, exécutez le nouveau test. En mode Jeu, vous verrez le personnage s'éloigner du bord, tomber (dépassant le seuil de 0,2 seconde pour catégoriser une chute) et subir des dégâts après avoir touché le sol.

Les tests ne servent pas seulement à vérifier que les modifications du code n'altèrent pas les fonctionnalités, ils peuvent également servir de documentation ou de pistes pour aider les développeurs à réfléchir à d'autres aspects du jeu lorsqu'ils modifient les paramètres.

Comment faire pour que les tests s'exécutent dans une version autonome du lecteur ?
Comment faire pour que les tests s'exécutent dans une version autonome du lecteur ?
Exécution des tests dans le lecteur autonome
Automatisation et CI

Une fois que vous avez commencé à construire une suite de tests, l'étape suivante consiste à les exécuter automatiquement une fois la construction terminée. Les tests unitaires et d'intégration automatisés qui s'exécutent après la construction sont utiles pour détecter les régressions ou les bogues le plus tôt possible. Ils peuvent également fonctionner dans le cadre d'un système de construction automatisé à distance dans le nuage.

Scinder la compilation et l’exécution

Souvent, vous voudrez capturer les résultats des essais dans un format personnalisé afin de pouvoir les partager avec un public plus large. Afin de capturer les résultats des tests en dehors de l'éditeur Unity, vous devrez séparer les processus de construction et d'exécution.

Créez un nouveau script dans le dossier de votre projet Tests, nommé SetupPlaymodeTestPlayer.

La classe SetupPlaymodeTestPlayer implémentera l'interface ITestPlayerBuildModifier. Vous l'utiliserez pour remplacer la méthode ModifyOptions, qui reçoit les options du lecteur de la version et vous permet de les modifier.

using System.IO ;
en utilisant UnityEditor ;
using UnityEditor.TestTools;

[assemblée : TestPlayerBuildModifier(typeof(SetupPlaymodeTestPlayer))]
public class SetupPlaymodeTestPlayer : ITestPlayerBuildModifier
{
public BuildPlayerOptions ModifyOptions(BuildPlayerOptions playerOptions)
{
playerOptions.options &= ~(BuildOptions.AutoRunPlayer | BuildOptions.ConnectToHost);

var buildLocation = Path.GetFullPath("TestPlayers");
var fileName = Path.GetFileName(playerOptions.locationPathName);
if (!string.IsNullOrEmpty(fileName))
buildLocation = Path.Combine(buildLocation, fileName) ;
playerOptions.locationPathName = buildLocation;

return playerOptions ;
}
}

Ce script modificateur personnalisé de construction de joueur effectue les opérations suivantes lorsque les tests sont exécutés en mode Play (Run Location) : Sur le joueur) :

Désactive l'exécution automatique pour les joueurs construits et ignore l'option du joueur qui tente de se connecter à l'hôte sur lequel il s'exécute.

Modifie l'emplacement du chemin de construction en un chemin dédié au sein du projet(TestPlayers).

Une fois cette étape franchie, vous pouvez désormais vous attendre à ce que les builds se trouvent dans le dossier TestPlayers dès qu'ils finissent d'être construits. Les modifications apportées à la construction sont maintenant terminées et le lien entre la construction et l'exécution est rompu.

Ensuite, vous mettrez en place des rapports sur les résultats. Cela vous permettra d'écrire les résultats des tests dans un emplacement personnalisé, prêt pour la génération et la publication de rapports automatisés.

Créez un nouveau script dans le dossier de votre projet Tests, nommé ResultSerializer (fourni ci-dessous). Cette classe utilisera une référence d'assemblage à TestRunCallback et mettra en œuvre l'interface ITestRunCallback.

Cette implémentation de ITestRunCallback comprend une méthode RunFinished personnalisée, qui configure la construction d'un lecteur avec des tests pour écrire les résultats des tests dans un fichier XML nommé testresults.xml.

Code
Les résultats sont disponibles dans le fichier testresults.xml situé à l'emplacement Application.persistentDataPath de votre plateforme
Exécution d'un test après séparation de la construction et de l'exécution

Avec SetupPlaymodeTestPlayer.cs et ResultSerializer.cs combinés, les processus de construction et d'exécution sont maintenant séparés. L'exécution des tests produira les résultats dans testresults.xml situé dans l'emplacement Application.persistentDataPath de la plate-forme du lecteur.

Pour utiliser certains des types de ces classes de crochets, vous devrez ajouter une référence supplémentaire à Tests.asmdef. Mettez-le à jour pour ajouter la référence de la définition de l'assemblage UnityEditor.UI.EditorTests.

L'exécution des tests dans le lecteur produira maintenant une sortie de compilation du lecteur sous votre projet dans le dossier TestPlayers et un fichier testresults.xml dans l'emplacement Application.persistentDataPath.

Couverture de livre électronique
Plus de ressources sur les tests dans Unity

Cours sur le cadre de test Unity

Le package Test Framework comprend un cours sur les tests avec des exemples d'exercices pour vous aider à en savoir plus sur les tests avec Unity. Veillez à récupérer les fichiers de projet pour le cours à l'aide du gestionnaire de paquets.

Utilisation de Package Manager > Packages : Unity Registry > Test Framework, localisez la liste déroulante Samples et importez les exercices du cours.

Les exercices seront importés dans votre projet et situés sous Assets/Samples/Test Framework. Chaque exemple comprend un dossier d'exercices sur lequel vous pouvez travailler, ainsi qu'une solution à laquelle vous pouvez comparer votre propre travail au fur et à mesure que vous suivez les instructions.

QA votre code avec UTF

Cette conférence d'Unite Copenhagen sur l'UTF entre dans les détails et propose d'autres cas d'utilisation intéressants pour la personnalisation des tests. Ne manquez pas d'y jeter un coup d'œil pour voir ce qu'il est possible de faire d'autre.

Le débogage dans Unity

Accélérez votre flux de travail de débogage dans Unity avec des articles sur :

- Microsoft Visual Studio 2022

- Microsoft Visual Studio Code

Livres électroniques techniques avancés

Unity fournit un certain nombre de guides avancés pour aider les développeurs professionnels à optimiser le code des jeux. Créer un guide de style C# : Write cleaner code that scales compile les conseils d'experts de l'industrie sur la façon de créer un guide de style de code pour aider votre équipe à développer une base de code propre, lisible et évolutive.

Un autre guide populaire auprès de nos utilisateurs est 70+ astuces pour augmenter la productivité avec Unity. Il regorge d'astuces qui vous permettront de gagner du temps et d'améliorer votre flux de travail quotidien avec Unity 2020 LTS, y compris des astuces que même les développeurs expérimentés n'ont pas forcément remarquées.

Documentation

Explorez la dernière API de TestRunner, découvrez d'autres attributs UTF Custom et d'autres cycles de vie à intégrer dans la documentation UTF.

Retrouvez tous les e-books et articles avancés d'Unity dans le hub des meilleures pratiques d'Unity.

Vous avez aimé ce contenu ?