Escribiendo 테스트 mas claros, simples y de amplio espectro con Table Driven Testing con jest

El testing es una parte Importante dentro del ciclo de vida del desarrollo de software, con el tiempo se han desarrollado metodologías, patrones y herramientas alrededor de esta. Table Driven Test es una "técnica"que se enfoca en hacer uso de una tabla para Representativear nuestras entradas y la salida esperada.

Esta técnica es bastante útil cuando queremos probar muchos escenarios (combinaciones de posibles entradas y salidas). Vamos a usar como ejemplo la ya conocida función que suma, se reciben como parametros 2 números (a, b) y se regresa el resultado.

function sum(a, b) {
  return a + b;
}




Antes de pasar a escribir el test vamos a hacer una Representativeación de como serían nuestras entradas y salidas usando Table Driven Test

¿ 알고 bastante 간단하지?

Bueno ahora se viene lo interesante, vamos a pasarlo a código usando usando Table Driven Test usando jest (porque es popular y es lo que uso actualmente).

Para esto tenemos 2 opciones, usar template literals 또는 arreglos bi-dimensionales.

템플릿 리터럴




test.each`
  a | b | output
  ${2} | ${2} | ${4}
  ${100} | ${200} | ${300}
`('SHOULD sum a($a) and b($b) and return $output', ({ a, b, output}) => {
  expect(sum(a, b)).toBe(output);
});


Al ejecutar las pruebas con jest obtenemos los siguientes resultados,



A diferencia de un test tradicional tenemos acceso a los valores con los que se va a ejecutar el test usando ${nombre de la variable en la table} en la descripción y en la función que ejecutará los test simplemente des-estructuramos el objeto.

Esto hace a nuestro test mas claro, porque la descripción incluye con que se esta probando, simples y de amplio espectro porque si deseamos podemos agregar más escenarios podemos agregar otra row sin tener que tocar código de la prueba, no modificamos cómo se hace el test 나도 비슷해.

test.each`
  a | b | output
    ${0} | ${0} | ${0}
  ${2} | ${2} | ${4}
  ${100} | ${200} | ${300}
`('SHOULD sum a($a) and b($b) and return $output', ({ a, b, output}) => {
  expect(sum(a, b)).toBe(output);
});


Este resultado también sería posible si dentro del test case usamos arreglos y tratamos de ser "inteligentes"al escribir nuestros tests (no lo recomiendo)

test('SHOULD return sum a and b', () => {
  const testTable = [
    [2, 2, 4],
    [100, 200, 300]
  ];
  testTable.forEach(([a, b, output]) => {
    expect(sum(a, b)).toBe(output);
  });
});


Al ejecutar nuestras pruebas podemos observar esto en consola



La principales diferencias son que la descripción del test cambió porque al no tener acceso a los valores que vamos a probar tenemos que repensar cómo describir el test y que al parecer solo se ejecuta un test case lo cual sabemos no es cierto.

Por esto en lo personal no estoy de acuerdo con ser "inteligente"al escribir los test, porque corremos el riesgo de agregar logica y agregar errores. 로스 테스트 deben ser descriptivos aunque a veces sean repetitivos(debe haber un balance)

Una buena práctica y un buen indicador de que tienen un código robusto es poder entender cómo funciona el software leyendo sus tests en vez de leer el código directamente.



Arreglos 이차원



Ahora vamos a hacer el mismo test pero usando arreglos bi-dimensionales

const testTable = [
  [2, 2, 4],
  [100, 200, 300]
];
test.each(testTable)('SHOULD sum a(%d) and b(%d) and return %d', (a, b, output) => {
  expect(sum(a, b)).toBe(output);
});


La diferencia más nottoria es el uso de format specifiers para tener acceso a los valores de la tabla de pruebas en la descripción del test y que los parametros en nuestra función ahora son tomados uno por uno en lugar de hacer uso de un objeto.

¿Cuándo usar una u otra? Depende de ti, es una decisión personal aunque yo sugeriría que arriba de uso es mejor usar arreglos. La desventaja es que el tests perdería un poco de claridad pero ganaría legibilidad.

결론



Table Driven Test es una mejor manera de escribir tests en código que tiene múltiples escenarios y en los cuales queremos tener bastante claridad de que estamos probando y con qué lo hacemos. No todo debe ser Table Driven Test porque no todo se puede probar de la misma manera pero es sumamente útil.

Si quieres ver este proyecto puedes verlo en el siguiente monorepo .

좋은 웹페이지 즐겨찾기