Pruebas A/B en C#: cómo dejar de adivinar y empezar a ganar dinero

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Por qué su código C# trabaja en vano (y cómo solucionarlo)

\n\n

Ha pasado semanas refactorizando el algoritmo de recomendaciones. La nueva versión de RecommendationService se ve impecable, el código más limpio, las consultas LINQ más rápidas. Despliega la actualización en producción y… la conversión cae un 15%. ¿Le suena familiar? Si no, ha tenido suerte. Si sí, acaba de perder dinero y tiempo porque confió en la intuición, no en los datos.

\n\n

En el mundo del desarrollo en C# existe una regla de oro: «Nunca confíes en tu opinión, confía en la estadística». Para eso existe precisamente la prueba A/B (o prueba dividida). No es un truco de marketing, es un enfoque de ingeniería para la toma de decisiones. En este artículo, analizaremos cómo implementar una prueba A/B completa en su aplicación C#: desde la arquitectura hasta el cálculo de la significancia estadística. Y sí, habrá mucho código.

\n\n

¿Qué son las pruebas A/B en el contexto de C#?

\n\n

Imagine que tiene dos variantes de la misma lógica: el grupo de control A (versión antigua) y el grupo experimental B (versión nueva). Distribuye aleatoriamente a los usuarios entre ellos, recopila métricas y, mediante matemáticas, determina qué variante es realmente mejor.

\n\n

En C#, esto puede aplicarse a cualquier cosa:

\n
    \n
  • Cambio en el algoritmo de búsqueda
  • \n
  • Nuevo diseño del formulario de pago
  • \n
  • Diferentes variantes de ordenación de productos
  • \n
  • Experimentos con el tiempo de caché
  • \n
  • Pruebas de modelos de ML
  • \n
\n\n

El punto clave: las pruebas A/B en C# no se tratan de «poner una bandera en la configuración». Se trata de arquitectura limpia, aleatorización y recopilación de métricas sin errores.

\n\n

Arquitectura de pruebas A/B: Layer Cake en C#

\n\n

Vayamos directamente a la práctica. Le mostraré una arquitectura mínima pero funcional. Consta de tres capas:

\n\n
    \n
  1. Assigner — decide en qué grupo se encuentra el usuario.
  2. \n
  3. Feature Decision — qué variante de código ejecutar.
  4. \n
  5. Tracker — registra el evento y el resultado.
  6. \n
\n\n

Paso 1: Assigner — ¿quién eres, usuario?

\n\n

El error más común es una aleatorización incorrecta. Usar Random es una mala idea porque al reiniciar la aplicación, los grupos «se desvían». La solución correcta es la distribución determinista basada en UserId.

\n\n
public interface IExperimentAssigner\n{\n    string GetVariant(string userId, string experimentName);\n}\n\npublic class ConsistentExperimentAssigner : IExperimentAssigner\n{\n    public string GetVariant(string userId, string experimentName)\n    {\n        // Creamos un hash estable a partir de userId + experimentName\n        var hash = HashCode.Combine(userId, experimentName);\n        // Tomamos el módulo 100 — obtenemos un porcentaje\n        var bucket = Math.Abs(hash) % 100;\n        \n        // Supongamos, 50% en A, 50% en B\n        return bucket < 50 ? "A" : "B";\n    }\n}\n
\n\n

Ahora, el mismo usuario siempre estará en el mismo grupo para un experimento específico. Esto es crítico para la corrección de los datos.

\n\n

Paso 2: Feature Decision — la batalla de los algoritmos

\n\n

Ahora necesitamos que el código elija por sí mismo qué lógica ejecutar. Usamos el patrón Estrategia con una fábrica.

\n\n
public interface IPricingStrategy\n{\n    decimal CalculatePrice(decimal basePrice);\n}\n\npublic class OldPricingStrategy : IPricingStrategy\n{\n    public decimal CalculatePrice(decimal basePrice) \n        => basePrice; // Sin descuento\n}\n\npublic class NewPricingStrategy : IPricingStrategy\n{\n    public decimal CalculatePrice(decimal basePrice) \n        => basePrice * 0.9m; // 10% de descuento\n}\n\npublic class PricingStrategyFactory\n{\n    private readonly IExperimentAssigner _assigner;\n\n    public PricingStrategyFactory(IExperimentAssigner assi                

Blogs

Book Recommendations