test - karma jasmine tutorial
Condicionalmente ignorar las pruebas individuales con Karma/Jasmine (4)
Tengo algunas pruebas que fallan en PhantomJS pero no en otros navegadores.
Me gustaría que estas pruebas se ignoren cuando se ejecutan con PhantomJS en mi tarea de vigilancia (para que las nuevas ventanas del navegador no tengan enfoque y el rendimiento sea un poco más rápido), pero en mi tarea de prueba estándar y mi interconexión de CI, quiero todo pruebas para ejecutar en Chrome, Firefox, etc.
He considerado una convención de nombres de archivos como foo.spec.dont-use-phantom.js
y excluyendo aquellos en mi configuración de Karma, pero esto significa que tendré que separar las pruebas individuales que fallan en sus propios archivos, separarlos de sus bloques de describe
lógica y tener más archivos con convenciones de nomenclatura extrañas generalmente sería una mierda.
En breve:
¿Hay alguna manera de extender Jasmine y / o Karma y, de alguna manera, anotar pruebas individuales para que solo se ejecuten con ciertas configuraciones?
Puedo compartir mi experiencia con esto.
En nuestro entorno tenemos varias pruebas que se ejecutan con diferentes navegadores y diferentes tecnologías. Para poder ejecutar siempre las mismas suites en todas las plataformas y navegadores, tenemos un archivo auxiliar cargado en karma ( helper.js
) con algunas funciones de detección de funciones cargadas globalmente.
Es decir
function isFullScreenSupported(){
// run some feature detection code here
}
También puede usar Modernizr para esto.
En nuestras pruebas, envolvemos las cosas en bloques if/else
como los siguientes:
it(''should work with fullscreen'', function(){
if(isFullScreenSupported()){
// run the test
}
// don''t do anything otherwise
});
o para una prueba asíncrona
it(''should work with fullscreen'', function(done){
if(isFullScreenSupported()){
// run the test
...
done();
} else {
done();
}
});
Si bien es un poco detallado, le ahorrará tiempo para el tipo de escenario que enfrenta.
En algunos casos, puede usar el rastreo de agente de usuario para detectar un tipo o versión de navegador en particular; sé que es una mala práctica, pero a veces no hay otra manera.
Soporte de jazmín función pendiente.
Si llama a la función pendiente en cualquier parte del cuerpo de la especificación, sin importar las expectativas, la especificación estará marcada como pendiente.
Puede llamar pendiente directamente en prueba o en alguna otra función llamada desde prueba.
function skipIfCondition() {
pending();
}
function someSkipCheck() {
return true;
}
describe("test", function() {
it("call pending directly by condition", function() {
if (someSkipCheck()) {
pending();
}
expect(1).toBe(2);
});
it("call conditionally skip function", function() {
skipIfCondition();
expect(1).toBe(3);
});
it("is executed", function() {
expect(1).toBe(1);
});
});
ejemplo de trabajo aquí: http://plnkr.co/edit/JZtAKALK9wi5PdIkbw8r?p=preview
Creo que es la solución más pura. En los resultados de las pruebas, puede ver el conteo de las pruebas finalizadas y omitidas. Es más informativo contra el cuerpo de prueba de sustitución por condiciones.
La solución más simple que veo es anular las funciones globales y describe
para que acepten un tercer argumento opcional, que tiene que ser un booleano o una función que devuelve un valor booleano, para indicar si se debe ejecutar o no la suite / especificación actual. Al anular, debemos verificar si este tercer argumento opcional se resuelve en true
, y si lo hace, llamaremos xdescribe
/ xit
(o ddescribe
/ iit
dependiendo de la versión de Jasmine), que son los métodos de Jasmine para omitir suite / spec, en lugar del original / it
Este bloque debe ejecutarse antes de las pruebas, pero después de que Jasmine se incluya en la página. En Karma simplemente mueva este código a un archivo e karma.conf.js
antes de los archivos de prueba en karma.conf.js
. Aquí está el código:
(function (global) {
// save references to original methods
var _super = {
describe: global.describe,
it: global.it
};
// override, take third optional "disable"
global.describe = function (name, fn, disable) {
var disabled = disable;
if (typeof disable === ''function'') {
disabled = disable();
}
// if should be disabled - call "xdescribe" (or "ddescribe")
if (disable) {
return global.xdescribe.apply(this, arguments);
}
// otherwise call original "describe"
return _super.describe.apply(this, arguments);
};
// override, take third optional "disable"
global.it = function (name, fn, disable) {
var disabled = disable;
if (typeof disable === ''function'') {
disabled = disable();
}
// if should be disabled - call "xit" (or "iit")
if (disable) {
return global.xit.apply(this, arguments);
}
// otherwise call original "it"
return _super.it.apply(this, arguments);
};
}(window));
Y ejemplo de uso:
describe(''foo'', function () {
it(''should foo 1 '', function () {
expect(true).toBe(true);
});
it(''should foo 2'', function () {
expect(true).toBe(true);
});
}, true); // disable suite
describe(''bar'', function () {
it(''should bar 1 '', function () {
expect(true).toBe(true);
});
it(''should bar 2'', function () {
expect(true).toBe(true);
}, function () {
return true; // disable spec
});
});
Vea un ejemplo de trabajo aquí
También me encontré con este problema donde la idea era agregar un método de cadena .when()
para describe
, que hará más o menos lo mismo que he descrito anteriormente. Puede parecer mejor, pero es un poco más difícil de implementar.
describe(''foo'', function () {
it(''bar'', function () {
// ...
}).when(anything);
}).when(something);
Si está realmente interesado en este segundo enfoque, me complacerá jugar con él un poco más e intentar implementar la cadena .when()
.
Actualizar:
Jasmine utiliza el tercer argumento como una opción de tiempo de espera ( ver documentos ), por lo que mi ejemplo de código está reemplazando esta característica, lo cual no está bien. Me gusta @milanlempera y @MarcoCI responde mejor, el mío parece un poco hacky y no intuitivo. Trataré de actualizar mi solución de todos modos para no romper la compatibilidad con las características predeterminadas de Jasmine.
Prueba esto. Estoy usando esta solución en mis proyectos.
it(''should do something'', function () {
if (!/PhantomJS/.test(window.navigator.userAgent)) {
expect(true).to.be.true;
}
});
Esto no ejecutará esta prueba en particular en PhantomJS, pero lo ejecutará en otros navegadores.