Nota del traductor
Esta es la traducción del archivo readme.md. Aquí hay un enlace a las diferencias con la rama master de AVA (Si al hacer clic en el enlace no se encuentran modificaciones en el archivo readme.md
, será porque la traducción está actualizada).
Test runner futurista
![Gitter](https://badges.gitter.im/join chat.svg)
A pesar de que JavaScript se ejecuta en un solo hilo, IO en Node.js puede ejecutarse en paralelo debido a su naturaleza asíncrona. AVA aprovecha esto y corre sus tests al mismo tiempo, lo que es especialmente beneficioso para tests pesados en IO. Además, los archivos de test se ejecutan en paralelo como procesos separados, que le da un mejor rendimiento y un entorno aislado para cada archivo de test. Cambiando de Mocha a AVA en Pageres llevó el tiempo de los test por debajo de 31 segundos, concretamente a 11 segundos. El tener tests que se ejecutan al mismo tiempo nos obliga a escribir tests atómicos, es decir, los tests no dependen del estado global o el estado de otros tests, lo que está muy bien!
Lea nuestra guía de contribución si está pensando en contribuir (issues/PRs/etc).
Siga la cuenta de Twitter de AVA para actualizaciones.
Traducciones: Español, Français, Italiano, 日本語, Portugués
- Mínima y rápida
- Sintaxis simple de test
- Ejecuta los tests concurrentemente
- Fuerza a escribir tests atómicos
- Sin globales implícitas
- Entorno aislado para cada archivo de test
- Escribe tus tests en ES2015
- Soporte a Promesas
- Soporte a Generadores
- Soporte a Async
- Soporte a Observable
- Aserciones mejoradas
- Salida de TAP opcional
- Trazas de pila limpias
import test from 'ava';
test(t => {
t.same([1, 2], [1, 2]);
});
Instalar AVA globalmente $ npm install --global ava
y ejecutar $ ava --init
(con cualquiera de las opciones) para añadir AVA a tu package.json o crear una.
{
"name": "awesome-package",
"scripts": {
"test": "ava"
},
"devDependencies": {
"ava": "^0.6.0"
}
}
import test from 'ava';
import delay from 'delay';
test('foo', t => {
t.pass();
});
test('bar', async t => {
t.plan(1);
const bar = Promise.resolve('bar').then(delay(200));
t.is(await bar, 'bar');
});
$ npm test
$ ava --help
Usage (Uso)
ava [<file|folder|glob> ...]
Options (Opciones)
--init Add AVA to your project (Añadir AVA a su proyecto)
--fail-fast Stop after first test failure (Parar después de que el test falle)
--serial, -s Run tests serially (Ejecutar tests en serie)
--require, -r Module to preload (Can be repeated) (Módulo a precargar (se puede repetir))
--tap, -t Generate TAP output (Generar salida de TAP)
--verbose, -v Enable verbose output (Habilitar el modo verboso)
Examples (Ejemplos)
ava
ava test.js test2.js
ava test-*.js
ava test
ava --init
ava --init foo.js
Default patterns when no arguments (Patrones por defecto cuando no hay argumentos):
test.js test-*.js test/**/*.js
- Tenga en cuenta que el CLI usará su instalación local de AVA cuando esté disponible, incluso cuando se ejecute globalmente.*
Los directorios son recursivos por defecto. Los archivos que se encuentren en directorios llamados fixtures
y helpers
serán ignorados, así como los archivos que comienzan con _
. Esto nos puede ser útil para tener helpers en el mismo directorio que los archivos de test.
Todas las opciones de CLI pueden configurarse en la sección de 'ava' de su 'package.json'. Esto le permite modificar el comportamiento predeterminado del comando 'ava', para no tener que escribir varias veces las mismas opciones en el indicador de comandos.
{
"ava": {
"files": [
"my-test-folder/*.js",
"!**/not-this-file.js"
],
"failFast": true,
"tap": true,
"require": ["babel-core/register", "coffee-script/register"]
}
}
Los argumentos pasados al CLI siempre tendrán prioridad sobre la configuración en 'package.json'.
Los tests se ejecutan asincronamente y requieren devolver y soportar un objeto asíncrono (una promesa, u observable). Nosotros recomendamos altamente el uso de funciones asíncronas. Hacen el código asíncrono, conciso y fácil de leer, y de forma implícita devuelven una promesa, por lo que no tiene que hacerla.
Si usted no devuelve uno de los objetos soportados y asincrónicos mencionados anteriormente, la prueba se considerará síncrona y terminará inmediatamente.
Si usted es incapaz de usar promesas u otros objetos asíncronos soportados, puede activar el "callback" por la definición de su test con test.cb([title], fn)
. Los test declarados de esta manera deben terminar manualmente con t.end()
. Este modo está pensado principalmente para las APIs de tests con estilo callback.
Debe definir todas las pruebas de forma sincrona. No pueden estar definidos dentro de setTimeout
, setImmediate
, etc.
Los archivos de test se ejecutan desde el directorio actual, con lo que process.cwd()
es siempre el mismo que __dirname
. Puede tambien usar rutas de acceso relativas en lugar de hacer path.join(__dirname, 'relative/path')
.
Para crear un test, llamaremos a la función de test
que requiera de AVA y pasaremos un nombre de test opcional y una función que contiene la ejecución del test. La función que pasemos será tomada en contexto como el primer argumento, dónde puedes invocar los diferentes métodos y aserciones de AVA.
test('name', t => {
t.pass();
});
Dar nombre a un test es opcional, pero se recomienda usar uno si tenemos más de un test.
test(t => {
t.pass();
});
También puede optar por utilizar una función nombrada en su lugar:
test(function name(t) {
t.pass();
});
Un plan de aserción se puede utilizar para garantizar que un número determinado de afirmaciones se cumplen. El escenario más común es validar que el test no ha salido antes de ejecutar el número esperado de aserciones. También falla el test si se ejecutan demasiadas aserciones, puede ser útil si tiene aserciones dentro de callbacks o bucles. Tenga en cuenta que, a diferencia del nodo-tap y tape, AVA no terminará automáticamente un test cuando se alcance el final previsto de la aserción.
Esto terminará en un test ejecutado satisfactoriamente:
test(t => {
t.plan(1);
return Promise.resolve(3).then(n => {
t.is(n, 3);
});
});
test.cb(t => {
t.plan(1);
someAsyncFunction(() => {
t.pass();
t.end();
});
});
Mientras que la concurrencia es impresionante, hay algunas cosas que no se pueden hacer concurrentemente. En estos extraños casos, puede usar test.serial
, lo que obligará a esos tests a funcionar en serie antes de los concurrentes.
test.serial(t => {
t.pass();
});
Only-tests fuerza a que se cumplan sólo los test que se ejecutan. Esto puede ser útil para el funcionamiento de sólo unos pocos tests durante el desarrollo.
test('will not be run', t => {
t.fail();
})
test.only('will be run', t => {
t.pass();
});
Skip-tests se muestran como omitidos pero nunca ejecutados.
test.skip('will not be run', t => {
t.fail();
});
Cuando se requiera empezar a preparar y/o abandonar, puede usar test.before()
y test.after()
,
usándolo de la misma manera que test()
. La función test permite el uso de test.before()
y test.after()
, siempre serán ejecutadas antes o después de todos los tests. Puede usar incluso test.beforeEach()
y test.afterEach()
si necesita preparar algo antes y despues de cada test. Los hooks se ejecutan en serie en el archivo de test. Añada tantos como quiera. Opcionalmente puede especificar un título que se muestre en el error.
Si necesita crear un estado global entre tests usando 'test.beforeEach()' y 'test.afterEach()' (como espiar 'console.log' [por ejemplo] (avajs/ava#560)), necesitará asegurarse de que los tests se ejecutan en serie (mediante test.serial o '--serial').
test.before(t => {
// esto se ejecuta antes de todos los tests
});
test.before(t => {
// esto se ejecuta después del anterior, pero antes de los tests
});
test.after('cleanup', t => {
// esto se ejecuta despues de todos los tests
});
test.beforeEach(t => {
// esto se ejecuta antes de cada test
});
test.afterEach(t => {
// esto se ejecuta despues de cada test
});
test(t => {
// test regular
});
Puede utilizar las funciones asíncronas, devolver objetos asincrónicos, o activar el "modo callback" en cualquiera de los hooks.
test.before(async t => {
await promiseFn();
});
test.cb.beforeEach(t => {
setTimeout(t.end);
});
test.afterEach.cb(t => {
setTimeout(t.end);
});
test.after(t => {
return new Promise(/* ... */);
});
Los hooks beforeEach
y afterEach
pueden compartir el contexto del test:
test.beforeEach(t => {
t.context.data = generateUniqueData();
});
test(t => {
t.is(t.context.data + 'bar', 'foobar');
});
El contexto por defecto es un objeto, pero también se puede asignar directamente:
test.beforeEach(t => {
t.context = 'unicorn';
});
test(t => {
t.is(t.context, 'unicorn');
});
Puede encadenar modificaciones de test juntas de la siguiente manera:
test.before.skip([title], testFn);
test.skip.after(....);
test.serial.only(...);
test.only.serial(...);
Es especialmente útil utilizar temporalmente skip
u only
en un test, sin perder la información y el comportamiento que los otros modificadores proporcionan.
Puede utilizar cualquier módulo de aserción en lugar o además del que viene con AVA, pero no podrá utilizar el método .plan()
, aún.
import assert from 'assert';
test(t => {
assert(true);
});
AVA está construido con soporte a ES2015 a través de Babel 6. Sólo tiene que escribir sus pruebas en ES2015. No necesitará ninguna configuración adicional. Se puede utilizar cualquier versión de Babel en su proyecto. Utilizamos nuestro propio paquete de Babel con el es2015
y stage-2
preajustados, así como espower
y transform-runtime
plugins.
La correspondiente configuración de Babel para la configuración de AVA es la siguiente:
{
"presets": [
"es2015",
"stage-0",
],
"plugins": [
"espower",
"transform-runtime"
]
}
Puede personalizar cómo AVA transpila los archivos de test a través de la opción de babel
en AVA package.json
configuration. Por ejemplo, para reemplazar los valores predeterminados se pueden utilizar:
{
"ava": {
"babel": {
"presets": [
"es2015",
"stage-0",
"react"
]
}
},
}
También puede utilizar la palabra especial "inherit"
. Esto hace que AVA difiera a la configuración de Babel [archivo .babelrc
o package.json
] (https://babeljs.io/docs/usage/babelrc/). De esta manera los archivos de test serán transpilados utilizando la misma configuración como los archivos de origen sin tener que repetirse para AVA:
{
"babel": {
"presets": [
"es2015",
"stage-0",
"react"
]
},
"ava": {
"babel": "inherit",
},
}
Tenga en cuenta que AVA siempre aplicará la [espower
] (https://github.com/power-assert-js/babel-plugin-espower) y plugins [transform-runtime
] (https://babeljs.io/docs/plugins/transform-runtime/).
AVA incluye typings para TypeScript. Tienes que configurar la transpilación por tí mismo. Cuando se establece en el archivo tsconfig.json
módulo
a commonjs
, TypeScript encontrará automáticamente las definiciones de tipo de AVA. Se debe establecer target
a es2015
con promesas y funciones de async.
AVA actualmente sólo transpilará los tests que usted le pida que ejecute. No transpilará módulos que importen
de fuera del test. Si bien hay razones válidas para adoptar este enfoque, puede que no sea lo que esperas!
Como una solución simple, puede utilizar Babel's require hook con el fin de hacer transpilación sobre la marcha de los módulos que se importan posteriormente. Debido a que AVA soporta la sintaxis de módulo de ES2015, se puede utilizar para importar el hook requerido en sí:
import test from 'ava';
import 'babel-core/register';
import foo from './foo'; // <-- foo puede ser escrito en ES2015!
test('foo bar', t => {
t.same('baz', foo('bar'));
});
#111 esta haciendo seguimiento de este tema como una mejora potencial.
Si usted devuelve una promesa en el test no necesitará poner fin de manera explícita al test, ya que terminará cuando la promesa se resuelva.
test(t => {
return somePromise().then(result => {
t.is(result, 'unicorn');
});
});
AVA viene con soporte a generadores.
test(function * (t) {
const value = yield generatorFn();
t.true(value);
});
AVA viene con soporte a funciones async (async/await).
test(async function (t) {
const value = await promiseFn();
t.true(value);
});
// async arrow function
test(async t => {
const value = await promiseFn();
t.true(value);
});
AVA viene con soporte a observables. Si devuelve un observable a partir de un test, AVA automáticamente podrá consumirlo hasta su finalización antes de terminar el test.
Si no necesita usar "callback mode" o llamar a t.end()
.
test(t => {
t.plan(3);
return Observable.of(1, 2, 3, 4, 5, 6)
.filter(n => {
// sólo números
return n % 2 === 0;
})
.map(() => t.pass());
});
AVA es compatible con el uso de t.end
como callback final al utilizar las API de callback de error-first y node-style. AVA considerará como error cualquier valor truthy pasado como primer argumento de t.end
. Tenga en cuenta que t.end
requiere "callback mode", que se puede activar mediante el uso de la cadena test.cb
.
test.cb(t => {
// t.end comprueba automáticamente los errores para el primer argumento
fs.readFile('data.txt', t.end);
});
AVA puede generar una salida TAP a través de la opción --tap
para su uso con cualquier TAP reporter.
$ ava --tap | tap-nyan
AVA elimina automáticamente líneas sin relación de la pila, lo que le permite encontrar la fuente de un error mucho más rápido.
Tipo: string
Título de test.
Tipo: function
Debe contener el test actual.
Pasado a la función de test y contiene los diferentes métodos de AVA y aserciones.
Planifique cuántas aserciones hay en el test. El test fallará si el recuento actual de aserciones no coincide con las aserciones planificadas.
Finalizar el test. Sólo funciona con test.cb()
.
Las aserciones se mezclan en el contexto del test:
test(t => {
t.ok('unicorn'); // aserción
});
Si se encuentran varios errores de aserción en un solo test, AVA sólo mostrará la primera.
Pasando la aserción.
Fallando la aserción.
Afirmando que valor
es truthy.
Afirmando que valor
es falsy.
Afirmando que valor
es true
.
Afirmando que valor
es false
.
Afirmando que valor
es igual a esperado
.
Afirmando que valor
no es igual a esperado
.
Afirmando que valor
es profundamente igual a esperado
.
Afirmando que valor
no es profundamente igual a esperado
.
Afirmando que function
arroja un error o promesa
rechazada.
error
puede contener un constructor, expresiones regulares, mensaje de error o la función de validación.
Afirma que function
no lanza un error
o resuelve la promise
.
Afirma que contents
coincide con regex
.
Afirma que error
es falsy.
Cualquier aserción se puede omitir usando el modificador skip
. Aunque se omitan dichas aserciones aún se cuentan, con lo que no hay necesidad de cambiar el contador de aserciones planificado.
test(t => {
t.plan(2);
t.skip.is(foo(), 5); // no hay necesidad de cambiar su contador planificado cuando omita aserciones.
t.is(1, 1);
});
AVA viene con power-assert
incorporado, dándole mensajes de aserción más descriptivos. Lee el test y trata de inferir más información del código.
El siguiente test:
test(t => {
const x = 'foo';
t.ok(x === 'bar');
});
Normalmente dará la salida inútil:
false === true
Con las aserciones mejoradas, obtendrás:
t.ok(x === 'bar')
|
"foo"
Es cierto que se podría usar t.is()
en este caso, y probablemente se debería, pero esto es sólo un ejemplo sencillo.
Probemos un ejemplo más avanzado:
test(t => {
const a = /foo/;
const b = 'bar';
const c = 'baz';
t.ok(a.test(b) || b === c);
});
Y ahí lo tienes:
t.ok(a.test(b) || b === c)
| | | |
| "bar" "bar" "baz"
false
Todos los métodos assert se han mejorado.
¡Diviértete!
Cada archivo de test se ejecuta en un proceso de Node.js separado. Esto nos brinda un montón de beneficios. Los diferentes archivos de test ya no se afectan entre sí. Como archivos de test moqueados con el ambiente global, comandos internos imperativos, etc. Sin embargo, se hace principalmente por razones de rendimiento. Aunque Node.js puede ejecutar simultáneamente IO asíncrono, eso no ayuda mucho cuando las pruebas son operaciones síncronas pesadas que bloquean el hilo principal. Mediante la ejecución de tests al mismo tiempo y archivos de test en paralelo, tomamos todas las ventajas de los sistemas modernos.
Ejecutar tests simultáneamente tiene algunos desafíos, hacer IO es uno. Por lo general, los test por defecto crean directorios temporales en el directorio de test actual y lo limpian al final. Esto no funcionará cuando se ejecuten tests en paralelo y entrando en conflicto entre sí. La forma correcta de hacerlo es utilizar un nuevo directorio temporal para cada test. Los módulos tempfile
y temp-write
pueden ser útiles.
AVA ejecuta pruebas en paralelo por defecto, que es subóptimo cuando se necesita depurar algo. En su lugar, ejecuta pruebas en serie con la opción --serial
:
$ ava --serial
Puede usar istanbul
para la cobertura de código como AVA spawns the test files, pero puede usar nyc
en su luegar, que es básicamente istanbul
con soporte para subprocesos.
Desde la versión 5.0.0
utiliza source maps para reportar la cobertura de su código real, independientemente de la transpilación. Asegúrese de que el código que está probando incluye un source map en línea o referencia a un archivo de source map de origen. Si usa babel/register
se puede establecer la opción sourceMaps
en su .babelrc
a inline
.
Mocha requiere el uso de globales implícitas como describe
y it
por defecto (que utilizan la mayoría de las personas), sin demasiadas opiniones buenas, hinchado, síncrono por defecto, ejecuta los tests en serie y es lento. Tape y node-tap son bastante buenos. AVA está muy inspirado en su sintaxis. Sin embargo, ambos ejecutan los tests en serie y han hecho de TAP un ciudadano de primera clase que ha hecho en mi humilde opinión que sus códigos base sean un poco enrevesadas y acopladas. La salida de TAP es difícil de leer, así que siempre terminan usando una herramienta de reporte de TAP externa. AVA tiene bastantes buenas opiniones y es concurrente. Viene con un simple reporter por defecto y tiene voluntad en el futuro de dar apoyo a Tun TAP reporter.
Use la opción --tap
con cualquier TAP reporter.
AVA, no Ava o ava. Pronunciado /ˈeɪvə/
ay-və.
Concurrencia no es paralelismo. Permite paralelismo. Aprende más.
- sublime-ava - Fragmentos de código para tests de AVA
- atom-ava - Fragmentos de código para tests de AVA
- vscode-ava - Fragmentos de código para tests de AVA
- eslint-plugin-ava - Reglas de lint para tests de AVA
- gulp-ava - Ejecutar tests con gulp
- grunt-ava - Ejecutar tests con grunt
- fly-ava - Ejecutar tests con fly
- start-ava - Ejecutar los tests con inicio
Sindre Sorhus | Kevin Mårtensson | Vadim Demedes | James Talmage | Mark Wubben |