Tests inestables de Bazel
- Análisis de tests de Bazel configurado mediante
tuist bazel setup.
Los tests inestables son tests que producen resultados diferentes (aprobado o fallido) cuando se ejecutan varias veces con el mismo código. Minan la confianza en tu suite de tests y hacen perder tiempo a los desarrolladores al investigar fallos falsos. Tuist detecta automáticamente los tests inestables y te ayuda a hacerles seguimiento a lo largo del tiempo.
Cómo funciona la detección de inestabilidad#
Tuist utiliza los casos individuales de los informes test.xml de Bazel para detectar resultados inconsistentes entre reintentos y entre ejecuciones de la misma confirmación y selección de objetivos en integración continua. Las ejecuciones locales siguen siendo visibles, pero no marcan automáticamente los casos de test como inestables.
Reintentos de tests#
Los reintentos son opcionales e independientes de la cuarentena. --flaky_test_attempts=3 habilita hasta tres intentos totales de Bazel por test, no tres reintentos adicionales. Mantén tu configuración de reintentos existente en .bazelrc o pásala explícitamente:
tuist bazel test -- --flaky_test_attempts=3 //app:tests
Los reintentos deben ejecutarse realmente para que Tuist observe sus resultados. El resumen de inestabilidad de un objetivo de Bazel por sí solo no identifica qué caso individual fue inestable.
Detección entre ejecuciones#
Comparar ejecuciones requiere metadatos de confirmación y rama. Proporciónalos cuando tu entorno de compilación no los publique ya:
tuist bazel test -- \
--build_metadata=CI=true \
--build_metadata=GIT_COMMIT="$GIT_COMMIT" \
--build_metadata=GIT_BRANCH="$GIT_BRANCH" //app:tests
Los casos se identifican por la etiqueta del objetivo, el nombre de la clase (con fallback al nombre de la suite) y el nombre del test, como se describe en Análisis de tests de Bazel.
Gestión de tests inestables#
Limpieza automática#
La detección y la limpieza se gestionan mediante una alerta de automatización en el proyecto. Cada proyecto incluye una automatización predeterminada llamada "Detección de tests inestables" cuyo disparador marca un test como inestable y cuya recuperación elimina la marca cuando el test ha superado el periodo de recuperación configurado (por defecto, 14 días) sin volver a activarse. Edítala en Configuración → Automatizaciones para cambiar el periodo de recuperación, modificar las acciones de recuperación (por ejemplo, liberar también el test de la cuarentena) o desactivar por completo la recuperación para que los tests permanezcan marcados como inestables hasta que los limpies manualmente.
Gestión manual#
También puedes marcar o desmarcar manualmente los tests como inestables desde la página de detalles del caso de test. Esto resulta útil cuando:
- Quieres reconocer un test inestable conocido mientras trabajas en su corrección
- Un test se marcó incorrectamente debido a problemas de infraestructura
Poner en cuarentena tests inestables#
La cuarentena aísla un test inestable para que no bloquee la CI mientras lo corriges. Por defecto es una acción manual: pones un test en cuarentena, lo liberas y cambias de modo desde la página de detalles del caso de test en el dashboard. También puedes vincularlo a una alerta de automatización en Settings → Automations para que el test se silencie automáticamente (o se omita) cuando supere un umbral de inestabilidad, y se libere cuando se recupere. Cada transición, manual o automática, queda registrada en el registro de auditoría del caso de test.
Por defecto, la recuperación espera hasta que la condición de activación deja de cumplirse, por lo que un test permanece en cuarentena hasta que sus ejecuciones inestables anteriores salen de la ventana de activación. Para recuperarlo antes, configura Recover when como No new flaky runs: el test se recupera una vez que transcurre la ventana de recuperación (días o ejecuciones) sin ninguna nueva ejecución inestable, cada nueva ejecución inestable reinicia esa espera y, tras la recuperación, solo una nueva ejecución inestable lo vuelve a poner en cuarentena.
tuist bazel test obtiene la política de cuarentena antes de cada invocación y la aplica a la ejecución subyacente de bazel test. Un bazel test normal sigue informando de los resultados de los tests, pero no aplica la cuarentena:
tuist bazel test -- //app:tests
Los argumentos después de -- se reenvían a bazel test. Usa --path para seleccionar el proyecto y el directorio de trabajo, y --bazel para seleccionar un ejecutable diferente, como bazelisk. Una configuración de Bazel con nombre, como --config=ci, es opcional y funciona de la misma manera.
Silenciar#
Usa Silenciar como flujo de trabajo principal de cuarentena. Los casos silenciados siguen ejecutándose, sus fallos permanecen visibles y los casos hermanos sanos siguen afectando al resultado. Tuist convierte la salida de fallo de test de Bazel en éxito solo cuando los informes atribuyen cada fallo en cada objetivo fallido a un caso silenciado. Los errores de compilación, los tiempos de espera agotados, las ejecuciones interrumpidas, los informes faltantes o incompletos y los fallos fuera del conjunto silenciado mantienen el estado de fallo de Bazel.
Omitir#
La omisión funciona por objetivo de Bazel: omitir un caso excluye todo su objetivo, incluidos los casos sanos, porque Bazel no puede filtrar casos individuales para cada framework de tests. Prefiere Silenciar a menos que pretendas excluir el objetivo completo. El comando imprime todas las etiquetas de objetivo excluidas para que los registros de compilación muestren qué dejó fuera la política de cuarentena.
Si un objetivo omitido ya no existe, Tuist lo nombra en una advertencia y se ejecuta sin esa exclusión. Devuelve los casos obsoletos a Habilitado para eliminar sus políticas permanentemente. Si no queda ningún objetivo de test, Bazel mantiene su estado de salida normal de "no se encontraron tests".
Por qué los tests en cuarentena pueden aparecer como aprobados#
- Los tests silenciados siguen ejecutándose. Un test silenciado que falla se registra como fallido en la ejecución del caso de test y se marca como inestable; el estado por test no se sobrescribe. Lo que se sobrescribe es la ejecución de tests completa: si todos los casos de test que fallan en la ejecución están silenciados, la ejecución en su conjunto se informa como aprobada, de modo que los fallos silenciados no rompen la CI.
- Los tests omitidos no se ejecutan en absoluto, por lo que el panel sigue mostrando el estado de la última ejecución real del test. Esa instantánea puede tener semanas de antigüedad.
Volver a ejecutar tests en cuarentena#
Para investigar o validar una corrección, omite la política de cuarentena:
tuist bazel test --no-quarantine -- --nocache_test_results //app:tests
Devuelve el caso a Habilitado para incluir su objetivo en ejecuciones normales posteriores. Los casos omitidos no generan nuevas ejecuciones hasta que se incluyan explícitamente, por lo que una automatización basada en nuevas ejecuciones exitosas necesita una ejecución de validación antes de poder recuperarlos.
Limitaciones#
- Un
--build_event_json_fileo--target_pattern_fileexplícito no se puede combinar con una cuarentena activa. Pasa los patrones de objetivo directamente. - Si Tuist no puede obtener la política de cuarentena, el comando se detiene antes de ejecutar los tests. Nunca aplica una política parcial. Usa
--no-quarantinecuando quieras ejecutar intencionadamente sin ella. - Un fallo que coincide con un silenciamiento registrado bajo una identidad anterior basada en la suite sigue siendo bloqueante, y el comando nombra la política que debe volver a aplicarse.
Consulta los filtros de tests, las opciones de comando y las descripciones de eventos de compilación de Bazel para conocer el comportamiento subyacente.
Notificaciones de Slack#
Recibe notificaciones cuando un test se vuelva inestable configurando alertas de tests inestables en tu integración con Slack.
Consulta del estado de tests inestables y en cuarentena#
CLI#
El árbol de comandos tuist test case expone toda la información que Tuist rastrea sobre un caso de test:
tuist test case list --flaky # only flaky test cases
tuist test case list --quarantined # only muted or skipped test cases
tuist test case show <test_case_id> # detail: flakiness rate, last status, run counts
tuist test case events <test_case_id> # audit log: marked_flaky, muted, skipped, ...
tuist test case run list <test_case_id> # run history with status and duration
tuist test case run show <test_case_run_id> # single run, including failure breakdown
Todos ellos aceptan --json para su uso en scripts.
API REST#
Los mismos datos están disponibles a través de HTTP. Consulta los endpoints de casos de test en la referencia de la API para obtener la lista completa de rutas, filtros y campos de respuesta. Para cambiar el estado de un caso de test (marcar o desmarcar como inestable, silenciar, omitir), envía PATCH /api/projects/{account_handle}/{project_handle}/tests/test-cases/{test_case_id} con is_flaky o state. El mismo cambio está disponible como tuist test case update y como la herramienta MCP update_test_case.