API de pruebas manuales
La API de pruebas manuales de Test Optimization está en beta y está sujeta a cambios.
A partir de la versión 2.13.0, el Datadog Python SDK proporciona la API de Test Optimization (ddtrace.ext.test_visibility) para enviar resultados de optimización de pruebas según sea necesario.
Ejecución de la API
La API utiliza clases para proporcionar métodos con espacios de nombres para enviar eventos de Test Optimization.
La ejecución de pruebas tiene dos fases:
- Descubrimiento: informar a la API qué elementos esperar
- Ejecución: enviar resultados (usando llamadas de inicio y finalización)
Las fases distintas de descubrimiento y ejecución permiten un intervalo entre el proceso del ejecutor de pruebas que recopila las pruebas y el inicio de las mismas.
Los usuarios de la API deben proporcionar identificadores consistentes (descritos a continuación) que se utilizan como referencias para los elementos de Test Optimization dentro del almacenamiento de estado de la API.
Habilitar test_visibility
Debe llamar a la función ddtrace.ext.test_visibility.api.enable_test_visibility() antes de usar la API de Test Optimization.
Llame a la función ddtrace.ext.test_visibility.api.disable_test_visibility() antes del cierre del proceso para asegurar el vaciado adecuado de los datos.
Modelo de dominio
La API se basa en cuatro conceptos: sesión de prueba, módulo de prueba, conjunto de pruebas y prueba.
Los módulos, conjuntos de pruebas y pruebas forman una jerarquía en la API de Test Optimization de Python, representada por la relación de padre del identificador del elemento.
Sesión de prueba
Una sesión de prueba representa la ejecución de pruebas de un proyecto, que normalmente corresponde a la ejecución de un comando de prueba. Solo se puede descubrir, iniciar y finalizar una sesión en la ejecución del programa Test Optimization.
Llame a ddtrace.ext.test_visibility.api.TestSession.discover() para descubrir la sesión, pasando el comando de prueba, un nombre de framework determinado y la versión.
Llame a ddtrace.ext.test_visibility.api.TestSession.start() para iniciar la sesión.
Cuando las pruebas hayan finalizado, llame a ddtrace.ext.test_visibility.api.TestSession.finish() .
Módulo de prueba
Un módulo de prueba representa una unidad de trabajo más pequeña dentro de las pruebas de un proyecto (un directorio, por ejemplo).
Llame a ddtrace.ext.test_visibility.api.TestModuleId(), proporcionando el nombre del módulo como parámetro, para crear un TestModuleId.
Llame a ddtrace.ext.test_visibility.api.TestModule.discover(), pasando el objeto TestModuleId como argumento, para descubrir el módulo.
Llame a ddtrace.ext.test_visibility.api.TestModule.start(), pasando el objeto TestModuleId como argumento, para iniciar el módulo.
Después de que todos los elementos secundarios dentro del módulo hayan finalizado, llame a ddtrace.ext.test_visibility.api.TestModule.finish(), pasando el objeto TestModuleId como argumento.
Conjunto de Pruebas
Un conjunto de pruebas representa un subconjunto de pruebas dentro de los módulos de un proyecto (un archivo .py, por ejemplo).
Llame a ddtrace.ext.test_visibility.api.TestSuiteId(), proporcionando el TestModuleId del módulo principal y el nombre del conjunto de pruebas como argumentos, para crear un TestSuiteId.
Llame a ddtrace.ext.test_visibility.api.TestSuite.discover(), pasando el objeto TestSuiteId como argumento, para descubrir el conjunto de pruebas.
Llame a ddtrace.ext.test_visibility.api.TestSuite.start(), pasando el objeto TestSuiteId como argumento, para iniciar el conjunto de pruebas.
Después de que todos los elementos secundarios dentro del conjunto de pruebas hayan finalizado, llame a ddtrace.ext.test_visibility.api.TestSuite.finish(), pasando el objeto TestSuiteId como argumento.
Prueba
Una prueba representa una sola incidencia de prueba que se ejecuta como parte de un conjunto de pruebas.
Llame a ddtrace.ext.test_visibility.api.TestId(), proporcionando la TestSuiteId de la suite principal y el nombre de la prueba como argumentos, para crear una TestId. El método TestId() acepta una cadena analizable en formato JSON como el argumento opcional parameters. El argumento parameters se puede utilizar para distinguir pruebas parametrizadas que tienen el mismo nombre, pero diferentes valores de parámetros.
Llame a ddtrace.ext.test_visibility.api.Test.discover(), pasando el objeto TestId como argumento, para descubrir la prueba. El método de clase Test.discover() acepta una cadena como el parámetro opcional resource, que tiene como valor predeterminado el name del TestId.
Llame a ddtrace.ext.test_visibility.api.Test.start(), pasando el objeto TestId como argumento, para iniciar la prueba.
Llame a ddtrace.ext.test_visibility.api.Test.mark_pass(), pasando el objeto TestId como argumento, para marcar que la prueba ha pasado exitosamente.
Llame a ddtrace.ext.test_visibility.api.Test.mark_fail(), pasando el objeto TestId como argumento, para marcar que la prueba ha fallado. mark_fail() acepta un objeto TestExcInfo opcional como el parámetro exc_info.
Llame a ddtrace.ext.test_visibility.api.Test.mark_skip(), pasando el objeto TestId como argumento, para marcar que la prueba fue omitida. mark_skip() acepta una cadena opcional como el parámetro skip_reason.
El método de clase ddtrace.ext.test_visibility.api.Test.mark_fail() contiene información sobre las excepciones encontradas durante el fallo de una prueba.
El método ddtrace.ext.test_visibility.api.TestExcInfo() toma tres parámetros posicionales:
exc_type: el tipo de excepción encontradaexc_value: el objeto BaseException para la excepciónexc_traceback: el objeto Traceback para la excepción
El método de clase ddtrace.ext.test_visibility.api.Test.discover() acepta una lista de cadenas opcional como el parámetro codeowners.
El método de clase ddtrace.ext.test_visibility.api.Test.discover() acepta un objeto TestSourceFileInfo opcional como el parámetro source_file_info. Un objeto TestSourceFileInfo representa la ruta y, opcionalmente, las líneas de inicio y fin de una prueba determinada.
El método ddtrace.ext.test_visibility.api.TestSourceFileInfo() acepta tres parámetros posicionales:
path: un objeto pathlib.Path (hecho relativo a la raíz del repositorio por la API Test Optimization)start_line: un número entero opcional que representa la línea de inicio de la prueba en el archivoend_line: un número entero opcional que representa la línea de fin de la prueba en el archivo
Configuración de parámetros después del descubrimiento de pruebas
El método de clase ddtrace.ext.test_visibility.api.Test.set_parameters() acepta un objeto TestId como argumento, y una cadena analizable en JSON, para establecer el parameters para la prueba.
Nota: esto sobrescribe los parámetros asociados con la prueba, pero no modifica el campo TestId del objeto parameters.
Configurar parámetros después de que se haya descubierto una prueba requiere que el objeto TestId sea único incluso sin que el campo parameters esté definido.
Ejemplo de código
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()
Para configuraciones adicionales, consulte Configuración.