API de test manuel
L'API de test manuel de Test Optimization est en bêta et susceptible d'être modifiée.
À partir de la version 2.13.0, le Datadog Python SDK fournit l’API Test Optimization (ddtrace.ext.test_visibility) pour soumettre les résultats d’optimisation de test selon les besoins.
Exécution de l’API
L’API utilise des classes pour fournir des méthodes avec espaces de noms afin de soumettre des événements d’optimisation de test.
L’exécution de test comporte deux phases :
- Découverte : informer l’API des éléments à attendre
- Exécution : soumettre les résultats (en utilisant les appels de début et de fin)
Les phases distinctes de découverte et d’exécution permettent un intervalle entre le processus d’exécution de test collectant les tests et le démarrage des tests.
Les utilisateurs de l’API doivent fournir des identifiants cohérents (décrits ci-dessous) qui sont utilisés comme références pour les éléments de Test Optimization au sein du stockage d’état de l’API.
Activer test_visibility
Vous devez appeler la fonction ddtrace.ext.test_visibility.api.enable_test_visibility() avant d’utiliser l’API Test Optimization.
Appelez la fonction ddtrace.ext.test_visibility.api.disable_test_visibility() avant l’arrêt du processus pour garantir un vidage correct des données.
Modèle de domaine
L’API repose sur quatre concepts : session de test, module de test, collection de tests et test.
Les modules, les collections et les tests forment une hiérarchie dans l’API Python Test Optimization, représentée par la relation parent de l’identifiant de l’élément.
Session de test
Une session de test représente l’exécution de test d’un projet, correspondant généralement à l’exécution d’une commande de test. Une seule session peut être découverte, démarrée et terminée lors de l’exécution du programme Test Optimization.
Appelez ddtrace.ext.test_visibility.api.TestSession.discover() pour découvrir la session, en passant la commande de test, un nom de framework donné et la version.
Appelez ddtrace.ext.test_visibility.api.TestSession.start() pour démarrer la session.
Une fois les tests terminés, appelez ddtrace.ext.test_visibility.api.TestSession.finish().
Module de test
Un module de test représente une unité de travail plus petite au sein de l’exécution des tests d’un projet (un répertoire, par exemple).
Appelez ddtrace.ext.test_visibility.api.TestModuleId(), en fournissant le nom du module comme paramètre, pour créer un TestModuleId.
Appelez ddtrace.ext.test_visibility.api.TestModule.discover(), en passant l’objet TestModuleId comme argument, pour découvrir le module.
Appelez ddtrace.ext.test_visibility.api.TestModule.start(), en passant l’objet TestModuleId comme argument, pour démarrer le module.
Une fois que tous les éléments enfants au sein du module sont terminés, appelez ddtrace.ext.test_visibility.api.TestModule.finish(), en passant l’objet TestModuleId comme argument.
Collection de tests ;
Une collection de tests représente un sous-ensemble de tests au sein des modules d’un projet (un fichier .py, par exemple).
Appelez ddtrace.ext.test_visibility.api.TestSuiteId(), en fournissant le TestModuleId du module parent et le nom de la collection comme arguments, pour créer un TestSuiteId.
Appelez ddtrace.ext.test_visibility.api.TestSuite.discover(), en passant l’objet TestSuiteId comme argument, pour découvrir la collection.
Appelez ddtrace.ext.test_visibility.api.TestSuite.start(), en passant l’objet TestSuiteId comme argument, pour démarrer la collection.
Une fois que tous les éléments enfants au sein de la collection sont terminés, appelez ddtrace.ext.test_visibility.api.TestSuite.finish(), en passant l’objet TestSuiteId comme argument.
Test
Un test représente un cas de test unique qui est exécuté dans le cadre d’une collection de tests.
Appelez ddtrace.ext.test_visibility.api.TestId(), en fournissant le TestSuiteId de la collection parente et le nom du test comme arguments, pour créer un TestId. La méthode TestId() accepte une chaîne analysable en JSON comme argument optionnel parameters. L’argument parameters peut être utilisé pour distinguer les tests paramétrés qui ont le même nom, mais des valeurs de paramètres différentes.
Appelez ddtrace.ext.test_visibility.api.Test.discover(), en passant l’objet TestId comme argument, pour découvrir le test. La méthode de classe Test.discover() accepte une chaîne comme paramètre optionnel resource, qui prend par défaut le name du TestId.
Appelez ddtrace.ext.test_visibility.api.Test.start(), en passant l’objet TestId comme argument, pour démarrer le test.
Appelez ddtrace.ext.test_visibility.api.Test.mark_pass(), en passant l’objet TestId comme argument, pour indiquer que le test a réussi.
Appelez ddtrace.ext.test_visibility.api.Test.mark_fail(), en passant l’objet TestId comme argument, pour indiquer que le test a échoué. mark_fail() accepte un objet TestExcInfo facultatif comme paramètre exc_info.
Appelez ddtrace.ext.test_visibility.api.Test.mark_skip(), en passant l’objet TestId comme argument, pour indiquer que le test a été ignoré. mark_skip() accepte une chaîne facultative comme paramètre skip_reason.
La méthode de classe ddtrace.ext.test_visibility.api.Test.mark_fail() contient des informations sur les exceptions rencontrées lors de l’échec d’un test.
La méthode ddtrace.ext.test_visibility.api.TestExcInfo() accepte trois paramètres positionnels :
exc_type : le type de l’exception rencontréeexc_value : l’objet BaseException pour l’exceptionexc_traceback : l’objet Traceback pour l’exception
La méthode de classe ddtrace.ext.test_visibility.api.Test.discover() accepte une liste facultative de chaînes comme paramètre codeowners.
La méthode de classe ddtrace.ext.test_visibility.api.Test.discover() accepte un objet TestSourceFileInfo facultatif comme paramètre source_file_info. Un objet TestSourceFileInfo représente le chemin et, éventuellement, les lignes de début et de fin pour un test donné.
La méthode ddtrace.ext.test_visibility.api.TestSourceFileInfo() accepte trois paramètres positionnels :
path : un objet pathlib.Path (rendu relatif à la racine du dépôt par l’API Test Optimization)start_line : un entier facultatif représentant la ligne de début du test dans le fichierend_line : un entier optionnel représentant la ligne de fin du test dans le fichier
Définition des paramètres après la découverte des tests
La méthode de classe ddtrace.ext.test_visibility.api.Test.set_parameters() accepte un objet TestId comme argument, ainsi qu’une chaîne analysable en JSON, pour définir le parameters du test.
Remarque : ceci écrase les paramètres associés au test, mais ne modifie pas le champ TestId de l’objet parameters.
La définition des paramètres après la découverte d’un test nécessite que l’objet TestId soit unique même sans que le champ parameters ne soit défini.
Exemple de code
from ddtrace.ext.test_visibility import api
import pathlib
import sys
if __name__ == "__main__":
# Enable the Test Optimization service
api.enable_test_visibility()
# Discover items
api.TestSession.discover("manual_test_api_example", "my_manual_framework", "1.0.0")
test_module_1_id = api.TestModuleId("module_1")
api.TestModule.discover(test_module_1_id)
test_suite_1_id = api.TestSuiteId(test_module_1_id, "suite_1")
api.TestSuite.discover(test_suite_1_id)
test_1_id = api.TestId(test_suite_1_id, "test_1")
api.Test.discover(test_1_id)
# A parameterized test with codeowners and a source file
test_2_codeowners = ["team_1", "team_2"]
test_2_source_info = api.TestSourceFileInfo(pathlib.Path("/path/to_my/tests.py"), 16, 35)
parametrized_test_2_a_id = api.TestId(
test_suite_1_id,
"test_2",
parameters='{"parameter_1": "value_is_a"}'
)
api.Test.discover(
parametrized_test_2_a_id,
codeowners=test_2_codeowners,
source_file_info=test_2_source_info,
resource="overriden resource name A",
)
parametrized_test_2_b_id = api.TestId(
test_suite_1_id,
"test_2",
parameters='{"parameter_1": "value_is_b"}'
)
api.Test.discover(
parametrized_test_2_b_id,
codeowners=test_2_codeowners,
source_file_info=test_2_source_info,
resource="overriden resource name B"
)
test_3_id = api.TestId(test_suite_1_id, "test_3")
api.Test.discover(test_3_id)
test_4_id = api.TestId(test_suite_1_id, "test_4")
api.Test.discover(test_4_id)
# Start and execute items
api.TestSession.start()
api.TestModule.start(test_module_1_id)
api.TestSuite.start(test_suite_1_id)
# test_1 passes successfully
api.Test.start(test_1_id)
api.Test.mark_pass(test_1_id)
# test_2's first parametrized test succeeds, but the second fails without attaching exception info
api.Test.start(parametrized_test_2_a_id)
api.Test.mark_pass(parametrized_test_2_a_id)
api.Test.start(parametrized_test_2_b_id)
api.Test.mark_fail(parametrized_test_2_b_id)
# test_3 is skipped
api.Test.start(test_3_id)
api.Test.mark_skip(test_3_id, skip_reason="example skipped test")
# test_4 fails, and attaches exception info
api.Test.start(test_4_id)
try:
raise(ValueError("this test failed"))
except:
api.Test.mark_fail(test_4_id, exc_info=api.TestExcInfo(*sys.exc_info()))
# Finish suites and modules
api.TestSuite.finish(test_suite_1_id)
api.TestModule.finish(test_module_1_id)
api.TestSession.finish()
Pour des configurations supplémentaires, consultez Configuration Settings.