KarmaJS, Jasmine, RequireJS, etc: Como usar o Require para testar módulos

Executando testes de Karma + Jasmine com o RequireJS - decolandoSocorro! . . . _ _ _. . . SOS!

Atualmente, tenho um projeto de exercícios para me sentir confortável com o KarmaJS - e o Unit Testing, em geral. A questão geral é que realmente não tenho uma visão transparente do que o Karma está fazendo nos bastidores e não consigo encontrar documentação adequada em áreas relevantes. Sem mais delongas...

Aqui está o meuestrutura de pastas:

root
    |-/lib
        |-/[dependencies] (/angular, /angular-mocks, /bootstrap, /etc)  # from bower
    |-/src                                                              
        |-/[unreferenced directories] (/js, /css, /views)               # not referenced anywhere
        |-app.js                                                        # sets up angular.module('app', ...)
        |-globals.js                                                    # may be referenced in RequireJS main file; not used.
        |-index.html                                                    # loads bootstrap.css and RequireJS main file
        |-main.js                                                       # .config + require(['app', 'etc'])
        |-routeMap.js                                                   # sets up a single route
        |-test-file.js                                                  # *** simple define(function(){ return {...}; })
    |-/test
        |-/spec
            |-test-test-file.js                                         # *** require || define(['test-file'])
    |-.bowerrc                                                          # { "directory": "lib" }
    |-bower.json                                                        # standard format
    |-karma.conf.js                                                     # *** HELP!
    |-test-main.js                                                      # *** Save Our Souls!!!

karma.conf.js

// Karma configuration
// Generated on Wed Nov 19 2014 15:16:56 GMT-0700 (Mountain Standard Time)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],


    // list of files / patterns to load in the browser
    files: [
      //'test/spec/test-test-file.js',
      //'lib/**/*.js',
      //'src/**/*.js',
      //'test/spec/**/*.js',
      'test-main.js',
      {pattern: 'lib/**/*.js', included: false},
      {pattern: 'src/**/*.js', included: false},
      {pattern: 'test/spec/*.js', included: true}
    ],


    // list of files to exclude
    exclude: [
        'lib/**/!(angular|angular-mocks|angular-resource|angular-route|require|text).js',
        'lib/**/**/!(jquery|bootstrap).js',
        'src/app.js'
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  });
};

test-main.js

var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
    return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
    if (TEST_REGEXP.test(file)) {
        // Normalize paths to RequireJS module names.
        allTestFiles.push(pathToModule(file));
    }
});

require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/src',

    paths: {

        angular: '../lib/angular/angular',
        ngRoute: '../lib/angular-route/angular-route',
        jquery: '../lib/jQuery/dist/jquery',
        bootstrap: '../lib/bootstrap/dist/js/bootstrap',
        models: 'models',
        controllers: 'controllers',
        globals: 'globals',
        routeMap: 'routeMap'
    },
    shim: {
        angular: {
            exports: 'angular'
        },
        ngRoute: {
            deps: ['angular']
        },
        jquery: {
            exports: '

test-test-file.js

console.log('....................');

define(function(){
    //console.log('testing test-file', testFile);

    describe('Testing testing', function(){
        it('should work', function(){
            expect(true).toEqual(true);
        });
    });

});

test-file.js

define('testFile', [], function(){

    return function init(sandbox){
        var app, application = app = sandbox.app
          , globals = sandbox.globals;

        return {
            some: 'module'
        };
    };

});

Perguntas e descrições

Os pontos-chave para os quais gostaria de ouvir respostas são:

o que {pattern: '...',incluem: verdadeiro | falso } Faz?melhor maneira de excluir todo o material extra dentro dos diretórios da bower.quais arquivos eu preciso incluir no arquivo test-main.js?quais arquivos eu preciso incluir no arquivo karma.conf.js?o que o test-main.js realmente faz; para que serve isto?

Os horários em que recebo erros e problemas são assim que agrupo minhas especificações em umdefine(...) call - event quando dou ao módulo um ID -define('someId', function(){ ... }) -preciso retornar algo deste módulo, pois é umdefine ligar?

Outras vezes, recebo o 'olERRO: 'Não há registro de data e hora para /base/src/app.js!'. "Carimbo de data e hora, é claro! Que bobagem minha ..." - o que isso significa no mundo ?! Às vezes eu recebo o infame "Executado 0 de 0 ERRO"- Eu também poderia usar um pouco de clareza aqui, por favor. Realmente, tenho bastanteERRO: '... sem registro de data e hora ...' erros - e até404s quandoparece Eu deveria estar puxando essa biblioteca com o karma.conf.jsfiles config ... ???

Parece até que, geralmente, quando digo explicitamente o karma para excluirsrc/app.js Eu ainda entendo404se erros.

tl; dr

Obviamente, eu sou um pouco um novato confuso sobre Karma e * DD em geral ...

eu posso corrertest-test-file.js bem quando meu karma.conf.jsfiles matriz parece[ 'test-main.js', 'test/spec/test-test-file.js' ] - mas, ainda assim, se envolver meu teste em uma chamada de definição RequireJS, recebo o "Incompatibilidade anonymous define ()"erro mencionado acima.

Parece que quando eu adiciono{pattern: '...', inclui:falso } então o karma simplesmente não adiciona nenhum dos meus arquivos para o padrão especificado (???).

Se alguém puder simplesmente me orientar sobre como usar o RequireJS com o Karma - ou seja, para que eu possa finalizar meus testes em umdefinir / exigir ligar e puxar o módulo que eu quero testar ... Isso seria muito apreciado.

Como é um pouco difícil manter esses tipos de perguntas curtos e ainda fornecer informações adequadas, espero não ter demorado muito.

EDITAR

Depois de ler a resposta de glepretre e algumas brincadeiras por conta própria, reconfigurei meu projeto da seguinte maneira:

Mudou-setest-main.js paratest/test-main.js,renomeadotest-test-file.js paratestFileSpec.js - mudou detest/spec paratest/,

karma.conf.js:

...
// list of files / patterns to load in the browser
files: [
    {pattern: 'lib/**/*.js', included: false},
    {pattern: 'src/**/*.js', included: false},
    {pattern: 'test/**/*Spec.js', included: false},

    'test/test-main.js'

],
....

test / test-main.js:

/* **************** HOW COME THE DEFAULT (Karma-generated) CONFIGURATION DOES ***NOT WORK???
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
    return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
    if (TEST_REGEXP.test(file)) {
        // Normalize paths to RequireJS module names.
        allTestFiles.push(pathToModule(file));
    }
});
*/

var tests = [];
for (var file in window.__karma__.files) {
    if (/Spec\.js$/.test(file)) {
        tests.push(file);
    }
}

require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/src',

    paths: {},
    shim: {},

    // dynamically load all test files
    //deps: allTestFiles,
    //
    deps: tests,

    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
});

Agora estou executando testes de unidade com sucesso!Agradecimentos especiais a glepretre e todos os outros colaboradores.

Obrigado por qualquer insight :)

}, bootstrap: { deps: ['jquery'] } }, // dynamically load all test files deps: allTestFiles, // we have to kickoff jasmine, as it is asynchronous callback: window.__karma__.start });

test-test-file.js

console.log('....................');

define(function(){
    //console.log('testing test-file', testFile);

    describe('Testing testing', function(){
        it('should work', function(){
            expect(true).toEqual(true);
        });
    });

});

test-file.js

define('testFile', [], function(){

    return function init(sandbox){
        var app, application = app = sandbox.app
          , globals = sandbox.globals;

        return {
            some: 'module'
        };
    };

});

Perguntas e descrições

Os pontos-chave para os quais gostaria de ouvir respostas são:

o que {pattern: '...',incluem: verdadeiro | falso } Faz?melhor maneira de excluir todo o material extra dentro dos diretórios da bower.quais arquivos eu preciso incluir no arquivo test-main.js?quais arquivos eu preciso incluir no arquivo karma.conf.js?o que o test-main.js realmente faz; para que serve isto?

Os horários em que recebo erros e problemas são assim que agrupo minhas especificações em umdefine(...) call - event quando dou ao módulo um ID -define('someId', function(){ ... }) -preciso retornar algo deste módulo, pois é umdefine ligar?

Outras vezes, recebo o 'olERRO: 'Não há registro de data e hora para /base/src/app.js!'. "Carimbo de data e hora, é claro! Que bobagem minha ..." - o que isso significa no mundo ?! Às vezes eu recebo o infame "Executado 0 de 0 ERRO"- Eu também poderia usar um pouco de clareza aqui, por favor. Realmente, tenho bastanteERRO: '... sem registro de data e hora ...' erros - e até404s quandoparece Eu deveria estar puxando essa biblioteca com o karma.conf.jsfiles config ... ???

Parece até que, geralmente, quando digo explicitamente o karma para excluirsrc/app.js Eu ainda entendo404se erros.

tl; dr

Obviamente, eu sou um pouco um novato confuso sobre Karma e * DD em geral ...

eu posso corrertest-test-file.js bem quando meu karma.conf.jsfiles matriz parece[ 'test-main.js', 'test/spec/test-test-file.js' ] - mas, ainda assim, se envolver meu teste em uma chamada de definição RequireJS, recebo o "Incompatibilidade anonymous define ()"erro mencionado acima.

Parece que quando eu adiciono{pattern: '...', inclui:falso } então o karma simplesmente não adiciona nenhum dos meus arquivos para o padrão especificado (???).

Se alguém puder simplesmente me orientar sobre como usar o RequireJS com o Karma - ou seja, para que eu possa finalizar meus testes em umdefinir / exigir ligar e puxar o módulo que eu quero testar ... Isso seria muito apreciado.

Como é um pouco difícil manter esses tipos de perguntas curtos e ainda fornecer informações adequadas, espero não ter demorado muito.

EDITAR

Depois de ler a resposta de glepretre e algumas brincadeiras por conta própria, reconfigurei meu projeto da seguinte maneira:

Mudou-setest-main.js paratest/test-main.js,renomeadotest-test-file.js paratestFileSpec.js - mudou detest/spec paratest/,

karma.conf.js:

...
// list of files / patterns to load in the browser
files: [
    {pattern: 'lib/**/*.js', included: false},
    {pattern: 'src/**/*.js', included: false},
    {pattern: 'test/**/*Spec.js', included: false},

    'test/test-main.js'

],
....

test / test-main.js:

/* **************** HOW COME THE DEFAULT (Karma-generated) CONFIGURATION DOES ***NOT WORK???
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
    return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
    if (TEST_REGEXP.test(file)) {
        // Normalize paths to RequireJS module names.
        allTestFiles.push(pathToModule(file));
    }
});
*/

var tests = [];
for (var file in window.__karma__.files) {
    if (/Spec\.js$/.test(file)) {
        tests.push(file);
    }
}

require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/src',

    paths: {},
    shim: {},

    // dynamically load all test files
    //deps: allTestFiles,
    //
    deps: tests,

    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
});

Agora estou executando testes de unidade com sucesso!Agradecimentos especiais a glepretre e todos os outros colaboradores.

Obrigado por qualquer insight :)

questionAnswers(1)

yourAnswerToTheQuestion