Glosario · CI/CD y DevOps
Feature flag
También llamado: feature toggle, feature flags, interruptor de funcionalidad, bandera de funcionalidad
Definición
Un interruptor en tiempo de ejecución que activa o desactiva un camino del código sin desplegar, para publicar trabajo oculto, liberar gradualmente y revertir rápido.
Un feature flag (o feature toggle) es una condición en el código cuyo valor viene de la configuración en tiempo de ejecución: si el flag está activado para este usuario o entorno, se toma el camino nuevo; si no, el antiguo. Separa desplegar código de liberar una funcionalidad. El código puede estar en producción desactivado, luego activarse para usuarios internos, después para el 10 % de los clientes, luego para todos, y volver a desactivarse en segundos si algo sale mal.
Ejemplo
if (flags.isEnabled('new-checkout', { userId: user.id })) {
return renderNewCheckout(cart);
}
return renderLegacyCheckout(cart);
El servicio de flags (un producto comercial, uno open source o una tabla en tu propia base de datos) decide el valor para cada usuario, a menudo por porcentaje o por atributo.
Qué implica para el testing
Cada flag duplica el número de caminos posibles en ese fragmento de código. Un tester necesita saber:
- Qué estados de flags salen juntos. Prueba la combinación que realmente estará activa en producción, no solo “todo activado”.
- Ambos lados de cada flag activo. El camino antiguo sigue siendo código de producción hasta que se elimina el flag, así que las suites de regresión deben cubrirlo.
- El propio cambio. Activar o desactivar el flag a mitad de sesión no debería corromper datos ni dejar a un usuario atascado a mitad de un flujo.
- El control en las pruebas. Las pruebas automatizadas deben fijar los valores de los flags de forma explícita, por ejemplo mediante una API solo para pruebas, una cookie o una sobrescritura de configuración, en lugar de depender de lo que tenga en ese momento el entorno compartido. Si no, alguien cambia un flag y rompe ejecuciones de pruebas que no tienen nada que ver, algo que parece exactamente un problema de flakiness.
test('new checkout shows delivery slots', async ({ page, context }) => {
await context.addCookies([
{ name: 'ff_new-checkout', value: 'on', url: 'https://staging.example.com' },
]);
await page.goto('https://staging.example.com/checkout');
await expect(page.getByRole('heading', { name: 'Choose a delivery slot' })).toBeVisible();
});
El nombre de la cookie es solo ilustrativo; usa el mecanismo de sobrescritura que ofrezca tu sistema de flags.
Errores comunes
Los flags que nunca se eliminan son el principal coste a largo plazo: ramas muertas, combinaciones que nadie entiende y caminos antiguos que se degradan en silencio. Trata cada flag de release como algo temporal, con un responsable y una fecha de eliminación, y borra la rama descartada y sus pruebas cuando termine el despliegue gradual.