Angular 2如何开始测试

时间:2016-05-18 11:39:04

标签: angular jasmine karma-runner

我开始编写应用程序而不考虑单元测试。但现在我必须写它们。我试图只使用jasmin编写测试,但是当我导入我的任何组件并在Web浏览器中启动jasmine时,我得到错误“系统未定义”。是否可以将karma和jasmin添加到现有项目中?我已经阅读了一些教程,但所有这些都是针对新项目的,并且老实说我不会遗漏一些东西(我在js中很新)。因此,如果有人能用几句话来形容,如何为angular2 app配置基本的测试环境,我将不胜感激。提前感谢您的回答。

1 个答案:

答案 0 :(得分:0)

您需要添加以下配置:

  • package.json文件中,Karma的依赖项和执行它的命令
  • Karma配置的karma.conf.js文件
  • 使用SystemJS加载TypeScript测试文件的karma-test-shim.js文件。

package.json文件的内容:

{
  "name": "test-karma",
  "version": "1.0.0",
  "scripts": {
    "build": "rm -rf dist && tsc",
    "pretest": "npm run build",
    "test": "karma start karma.conf.js",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" ",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "postinstall": "typings install",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0-rc.1",
    "@angular/compiler": "2.0.0-rc.1",
    "@angular/core": "2.0.0-rc.1",
    "@angular/http": "2.0.0-rc.1",
    "@angular/platform-browser": "2.0.0-rc.1",
    "@angular/platform-browser-dynamic": "2.0.0-rc.1",
    "@angular/router": "2.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.1",
    "@angular/upgrade": "2.0.0-rc.1",
    "systemjs": "0.19.6",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12",
    "angular2-in-memory-web-api": "0.0.7",
    "bootstrap": "^3.3.6"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "jasmine-core": "^2.4.1",
    "karma": "^0.13.22",
    "karma-chrome-launcher": "^1.0.1",
    "karma-coverage": "^1.0.0",
    "karma-firefox-launcher": "^1.0.0",
    "karma-jasmine": "^1.0.2",
    "karma-phantomjs-launcher": "^1.0.0",
    "lite-server": "^2.2.0",
    "phantomjs": "^2.1.7",
    "phantomjs-prebuilt": "^2.1.7",
    "typescript": "^1.8.10",
    "typings": "^0.8.1",
    "uglify": "^0.1.5"
  }
}

这是业力配置(karma.conf.js):

'use strict';

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

    basePath: '.',
    frameworks: ['jasmine'],

    files: [
      // Paths loaded by Karma
      {pattern: 'node_modules/es6-shim/es6-shim.min.js', included: true, watched: true},
      {pattern: 'node_modules/reflect-metadata/Reflect.js', included: true, watched: true},
      {pattern: 'node_modules/zone.js/dist/zone.js', included: true, watched: true},
      {pattern: 'node_modules/zone.js/dist/async-test.js', included: true, watched: true},
      {pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: true, watched: true},
      {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
      {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
      {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
      {pattern: 'karma-test-shim.js', included: true, watched: true},

      // Paths loaded via module imports
      {pattern: 'app/**/*.js', included: false, watched: true},

      // Paths to support debugging with source maps in dev tools
      {pattern: 'app/**/*.ts', included: false, watched: true},
      {pattern: 'app/**/*.js.map', included: false, watched: false}
    ],

    // Proxied base paths
    proxies: {
      // Required for component assests fetched by Angular's compiler
      '/app/': '/base/app/'
    },

    port: 9876,

    logLevel: config.LOG_INFO,

    colors: true,

    autoWatch: true,

    browsers: ['PhantomJS', 'Chrome', 'Firefox'],

    // Karma plugins loaded
    plugins: [
      'karma-jasmine',
      'karma-coverage',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-phantomjs-launcher'
    ],

    // Coverage reporter generates the coverage
    reporters: ['progress', 'dots', 'coverage'],

    // Source files that you wanna generate coverage for.
    // Do not include tests or libraries (these files will be instrumented by Istanbul)
    preprocessors: {
      'dist/**/!(*spec).js': ['coverage']
    },

    coverageReporter: {
      reporters: [
        {type: 'json', subdir: '.', file: 'coverage-final.json'}
      ]
    },

    singleRun: true
  });
};

karma-test-shim.js文件:

'use strict';

// Turn on full stack traces in errors to help debugging
Error.stackTraceLimit = Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

// Cancel Karma's synchronous start,
// we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};

var map = {
  'app': 'base/app',
  'rxjs': 'base/node_modules/rxjs',
  '@angular': 'base/node_modules/@angular'
};

var packages = {
  'app': { main: 'main.js',  defaultExtension: 'js' },
  'rxjs': { defaultExtension: 'js' }
};

var packageNames = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/http',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/router',
  '@angular/router-deprecated',
  '@angular/testing',
  '@angular/upgrade',
];

packageNames.forEach(function(pkgName) {
  packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

packages['base/app'] = {
  defaultExtension: 'js',
  format: 'cjs',
  map:     Object.keys(window.__karma__.files).filter(onlyAppFiles).reduce(createPathRecords, {})
};

var config = {
  map: map,
  packages: packages
};

System.config(config);

System.import('@angular/platform-browser/src/browser/browser_adapter')
    .then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
    .then(function() { return Promise.all(resolveTestFiles()); })
    .then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });

function createPathRecords(pathsMapping, appPath) {
    var pathParts = appPath.split('/');
    var moduleName = './' + pathParts.slice(Math.max(pathParts.length - 2, 1)).join('/');
    moduleName = moduleName.replace(/\.js$/, '');
    pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
    return pathsMapping;
}

function onlyAppFiles(filePath) {
    return /\/base\/app\/(?!.*\.spec\.js$).*\.js$/.test(filePath);
}

function onlySpecFiles(path) {
    return /\.spec\.js$/.test(path);
}

function resolveTestFiles() {
    return Object.keys(window.__karma__.files)  // All files served by Karma.
        .filter(onlySpecFiles)
        .map(function(moduleName) {
            // loads all spec files via their global module names (e.g.
        // 'base/dist/vg-player/vg-player.spec')
            return System.import(moduleName);
        });
}