Agente de Revisión Principal

Test Analyst

Asegura que tus tests realmente te protejan

Que los tests pasen no significa que tu código funcione. Test Analyst encuentra las brechas — casos límite faltantes, tests inestables y problemas de aislamiento que dejan pasar bugs.

Qué Detecta Test Analyst

Las brechas en tu suite de tests que dejan escapar bugs

Cobertura de Casos Límite Faltantes

El camino feliz está probado, pero ¿qué pasa con los valores nulos, arrays vacíos y condiciones de frontera?

Entradas nulasColecciones vacíasValores límiteRutas de error

Tests Inestables

Tests que pasan a veces y fallan otras — los asesinos silenciosos de la confianza en CI/CD

Dependencias de tiempoDependencias de ordenEstado compartidoLlamadas de red

Aislamiento de Tests Deficiente

Tests que dependen entre sí o comparten estado mutable — pesadillas de depuración

Fixtures compartidosContaminación de base de datosEstado globalBugs de orden de tests

Todos los Tipos de Tests Cubiertos

Desde tests unitarios hasta E2E, Test Analyst los revisa todos

Tests Unitarios

Pruebas a nivel de función y clase

Tests de Integración

Pruebas de interacción de componentes

Tests E2E

Pruebas de flujo de usuario de extremo a extremo

Tests de API

Pruebas de endpoints y contratos

Tests de Snapshot

Detección de regresión de UI

Tests de Rendimiento

Pruebas de carga y benchmark

Mejorando la Calidad de los Tests

Ejemplos reales de mejoras en tests

Caso Límite Faltante

Test Débil
describe('calculateDiscount', () => {
  it('applies 10% for orders over $100', () => {
    expect(calculateDiscount(150)).toBe(15)
  })

  it('applies 5% for orders over $50', () => {
    expect(calculateDiscount(75)).toBe(3.75)
  })

  // What about $0? Negative? Exactly $50? $100?
})

Tests de frontera faltantes: $0, $50, $100, negativo

Test Robusto
describe('calculateDiscount', () => {
  it('applies 10% for orders over $100', () => {
    expect(calculateDiscount(150)).toBe(15)
  })

  it('applies 5% for orders over $50', () => {
    expect(calculateDiscount(75)).toBe(3.75)
  })

  it('returns 0 for orders at boundary', () => {
    expect(calculateDiscount(50)).toBe(0)
    expect(calculateDiscount(100)).toBe(5) // 5% tier
  })

  it('handles zero and negative gracefully', () => {
    expect(calculateDiscount(0)).toBe(0)
    expect(calculateDiscount(-10)).toBe(0)
  })
})

Agregar casos límite para fronteras y entradas inválidas

Detección de Tests Inestables

Test Débil
it('shows notification after save', async () => {
  await user.click(saveButton)

  // Flaky! Depends on timing
  await waitFor(() => {
    expect(screen.getByText('Saved!')).toBeVisible()
  })

  // Even worse: arbitrary timeout
  await new Promise(r => setTimeout(r, 100))
  expect(notificationCount).toBe(1)
})

Timeouts arbitrarios y suposiciones de tiempo

Test Robusto
it('shows notification after save', async () => {
  await user.click(saveButton)

  // Wait for specific state change
  await waitFor(() => {
    expect(screen.getByRole('alert')).toHaveTextContent('Saved!')
  })

  // Assert on observable behavior, not timing
  expect(
    await screen.findByRole('alert', { name: /saved/i })
  ).toBeVisible()
})

Esperar cambios de estado observables, no tiempo

Problema de Aislamiento de Tests

Test Débil
let testUser: User

beforeAll(async () => {
  // Shared across ALL tests — mutations leak!
  testUser = await createUser({ name: 'Test' })
})

it('updates user name', async () => {
  await updateUser(testUser.id, { name: 'Updated' })
  // Now testUser.name is 'Updated' for all following tests
})

it('checks original name', () => {
  // FAILS! Previous test mutated shared state
  expect(testUser.name).toBe('Test')
})

Estado compartido en beforeAll se filtra entre tests

Test Robusto
describe('user updates', () => {
  let testUser: User

  beforeEach(async () => {
    // Fresh user for EACH test
    testUser = await createUser({ name: 'Test' })
  })

  afterEach(async () => {
    await deleteUser(testUser.id)
  })

  it('updates user name', async () => {
    await updateUser(testUser.id, { name: 'Updated' })
    expect(testUser.name).toBe('Updated')
  })

  it('checks original name', () => {
    // Works! Fresh testUser with original name
    expect(testUser.name).toBe('Test')
  })
})

Usar beforeEach para aislamiento de tests

Análisis de Tests

Cómo Funciona Test Analyst

Test Analyst no solo cuenta tests — analiza qué prueban realmente. Encuentra las brechas entre lo que cubren tus tests y lo que tu código necesita.

Análisis de Rutas

Mapea rutas de código para encontrar ramas sin probar

Detección de Inestabilidad

Identifica dependencias de tiempo y orden

Sugerencias de Casos Límite

Recomienda casos de test específicos para agregar

Pipeline de Análisis

1

Analizar Cobertura de Tests

Mapea qué rutas de código están probadas y cuáles no

2

Identificar Puntos Débiles

Encuentra casos límite y condiciones de error sin tests

3

Detectar Anti-patrones

Detecta patrones inestables y problemas de aislamiento

4

Sugerir Mejoras

Recomienda casos de test específicos para agregar

Por Qué Importa la Calidad de los Tests

Los tests malos son peores que no tener tests — dan falsa confianza

Detectar Bugs Reales

Los tests que cubren casos límite detectan bugs antes que los usuarios

CI/CD Confiable

No más "reintentar hasta que pase" — los tests pasan o fallan por razones reales

Refactorizar con Seguridad

Los buenos tests te permiten cambiar código con confianza

100% de cobertura no significa nada si los tests no detectan bugs.
Test Analyst asegura que tus tests realmente funcionen.

Tests Que Realmente
Te Protegen

Deja que Test Analyst encuentre las brechas en tu suite de tests. Gratis por 14 días, sin tarjeta de crédito requerida.

Detección de casos límite
Prevención de tests inestables
Análisis de aislamiento