사용자 도구

사이트 도구


study:script_test

Test Unit

webpack + karma + jasmine

devrafalko / webpack-karma-jasmine

제안하는 package:

  • ES2015의 자바스크립트를 컴파일하기 위한, specstests.js로 묶기 위한 karma-webpack and babel-loader
  • bash보고서를 위한 karma-mocha-reporter
  • browser보고서를 위한 karma-jasmine-html-reporter

예제를 위한 전체설명입니다.

1.모든 의존 패키지 설치

npm install --save-dev webpack webpack-cli webpack-karma-jasmine
npm install --save-dev @babel/cli @babel/core @babel/preset-env babel-loader 
npm install --save-dev jasmine-core karma karma-chrome-launcher 
npm install --save-dev karma-jasmine karma-jasmine-html-reporter karma-mocha-reporter karma-webpack

여기는 Tama가 추가 TypeScript를 이용한다면 추가적으로 npm install –save-dev @types/jasmine ts-loader typescript 기타 로더들

  • babel-loader
  • css-loader
  • style-loader
  • ts-loader

2.karma.conf.js파일 생성

karma.conf.js의 추천설정

karma.conf.js
module.exports = function(config) {
  config.set({
    //root path location to resolve paths defined in files and exclude
    basePath: '',
    //files/patterns to exclude from loaded files
    exclude: [],
    //files/patterns to load in the browser
    files: [
      {pattern: 'tests/*.js',watched:true,served:true,included:true}
      /*parameters:
          watched: if autoWatch is true all files that have watched set to true will be watched for changes
          served: should the files be served by Karma's webserver?
          included: should the files be included in the browser using <script> tag?
          nocache: should the files be served from disk on each request by Karma's webserver? */
      /*assets:
          {pattern: '*.html', watched:true, served:true, included:false}
          {pattern: 'images/*', watched:false, served:true, included:false} */    
    ],
 
    //executes the tests whenever one of the watched files changes
    autoWatch: true,
    //if true, Karma will run tests and then exit browser
    singleRun:false,
    //if true, Karma fails on running empty test-suites
    failOnEmptyTestSuite:false,
    //reduce the kind of information passed to the bash
    logLevel: config.LOG_WARN, //config.LOG_DISABLE, config.LOG_ERROR, config.LOG_INFO, config.LOG_DEBUG
 
    //list of frameworks you want to use, only jasmine is installed automatically
    frameworks: ['jasmine'],
 
    //list of browsers to launch and capture
    browsers: ['Chrome'/*,'PhantomJS','Firefox','Edge','ChromeCanary','Opera','IE','Safari'*/],
    //list of reporters to use
    reporters: ['mocha','kjhtml'/*,'dots','progress','spec'*/],
 
    //address that the server will listen on, '0.0.0.0' is default
    listenAddress: '0.0.0.0',
    //hostname to be used when capturing browsers, 'localhost' is default
    hostname: 'localhost',
    //the port where the web server will be listening, 9876 is default
    port: 9876,
    //when a browser crashes, karma will try to relaunch, 2 is default
    retryLimit:0,
    //how long does Karma wait for a browser to reconnect, 2000 is default
    browserDisconnectTimeout: 5000,
    //how long will Karma wait for a message from a browser before disconnecting from it, 10000 is default
    browserNoActivityTimeout: 10000,
    //timeout for capturing a browser, 60000 is default
    captureTimeout: 60000,
 
    client: {
      //capture all console output and pipe it to the terminal, true is default
      captureConsole:false,
      //if true, Karma clears the context window upon the completion of running the tests, true is default
      clearContext:false,
      //run the tests on the same window as the client, without using iframe or a new window, false is default
      runInParent: false,
      //true: runs the tests inside an iFrame; false: runs the tests in a new window, true is default
      useIframe:true,
      jasmine:{
        //tells jasmine to run specs in semi random order, false is default
        random: false
      }
    },
 
    /* karma-webpack config
       pass your webpack configuration for karma
       add `babel-loader` to the webpack configuration
       to make the ES6+ code readable by the browser */
    webpack: {
      module: {
        rules: [
          {
            test: /\.js$/i,
            exclude:/(node_modules)/,
            loader:'babel-loader',
            options:{
              presets:['@babel/preset-env']
            }
          }
        ]
      }
    },
    preprocessors: {
      //add webpack as preprocessor to support require() in test-suites .js files
      './tests/*.js': ['webpack']
    },
    webpackMiddleware: {
      //turn off webpack bash output when running the tests
      noInfo: true,
      stats: 'errors-only'
    },
 
    /*karma-mocha-reporter config*/
    mochaReporter: {
      output: 'noFailures'  //full, autowatch, minimal
    }
  });
};

3.필요한 폴더구조

  • 필요하다면 basePathexcludes속성, files patter속성, 그리고 preprocessors속성를 수정하라.
  • 폴더배열구조는 아래로 되어있다고 가정한다:
┌ karma.conf.js
├ package.json
├ webpack.config.js
├ src
│  ├ index.js
│  └ another_module.js
└ tests
   ├ spec_a.js
   └ spec_b.js

4.너의 test files에 임의의 specs를 추가하라

tests/spec_a.js
const myModule = require('./../src/index.js');
describe("Module should return", function () {
  it("some number", function () {
    expect(myModule()).toEqual(10);
  });
});
src/index.js
module.exports = ()=> 10;

5.tests실행

  • 터미널에서 karma start로 실행하거나,
  • package.json“scripts”: { “test”: “karma start” }를 추가하고, npm test를 실행

karma

karma.conf.js의 구성

  • basePath : 모든 패턴(files, exclude등)의 경로를 결정하는데 사용되는 기본경로
  • frameworks는 테스트 프레임워크 이름를 설정하는데 jasmine문자열로 자스민 프레임워크를 사용한다고 설정했다. 다른 것을 (jasmine, mocha, qunit등) 지원한다.
  • files는 테스트와 테스트 대상이 되는 파일, 그리고 필요하면 제이쿼리같은 써드파티 라이브러리등 테스트에 필요한 파일 목록을 나열한다. 나는 src 폴더에는 소스코드, test 폴더는 테스트 코드로 분류했다.
  • browsers는 테스트할 브라우저를 기술한다.카르마는 크롬(Chrome), 파이어폭스(Firefox), 사파리(Safari), 인터넷 익스플로러, 오페라 등 설정한 모든 브라우저를 자동으로 실행한다. 추가로 팬텀JS(PhantomJS)나 슬리머JS(SlimerJS)로 헤드리스(headless) 환경에서 테스트할 수도 있다. 이걸로도 충분치 않다면 브라우저스택(BrowserStack)이나 소스(Sauce)로 묶어 가능한 모든 브라우저에서 테스트할 수도 있다.
  • autoWatch는 테스트 종료후 계속 파일 변화를 감지하면서 테스트를 자동으로 재실행하는 옵션이다. 모카의 –watch 옵션과 같은 기능이다.

files

files배열은 브라우저에 포함된 파일과 karma가 보고, 제공하는 파일을 결정합니다.

files: [
 
  // Detailed pattern to include a file. Similarly other options can be used
  { pattern: 'lib/angular.js', watched: false },
  // Prefer to have watched false for library files. No need to watch them for changes
 
  // simple pattern to load the needed testfiles
  // equal to {pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true}
  'test/unit/*.spec.js',
 
  // this file gets served but will be ignored by the watcher
  // note if html2js preprocessor is active, reference as `window.__html__['compiled/index.html']`
  {pattern: 'compiled/index.html', watched: false},
 
  // this file only gets watched and is otherwise ignored
  {pattern: 'app/index.html', included: false, served: false},
 
  // this file will be served on demand from disk and will be ignored by the watcher
  {pattern: 'compiled/app.js.map', included: false, served: true, watched: false, nocache: true},
      {pattern: 'src/**/*.spec.js', watched:true, served:true, included: true},
      {pattern: 'src/**/*.spec.ts', watched:true, served:true, included: true},
      {pattern: 'test/**/*.js', watched:true, served:true, included: true}
      /*parameters:
          watched: if autoWatch is true all files that have watched set to true will be watched for changes
          served: should the files be served by Karma's webserver?
          included: should the files be included in the browser using <script> tag?
          nocache: should the files be served from disk on each request by Karma's webserver? */
      /*assets:
          {pattern: '*.html', watched:true, served:true, included:false}
          {pattern: 'images/*', watched:false, served:true, included:false} */    
 
],

추가 패키지

karma-jasmine: 카르마에서 자스민을 사용할 수 있다. jasmine-core: karma-jasmine은 카르마가 자스민을 사용할수 있도록 하는 어답터 역할만 한다. 자스민 코드가 있는 jasmine-core를 추가해야 한다. karma-chrome-launcher: 테스트 브라우져로 크롬을 선택했으면 이 플러그인을 설치해서 카르마가 크롬을 사용할 수 있도록 해야한다. 이것도 어답터라고 보면 되겠다.

mamajs의 karma.conf.js

karma.conf.js
// Karma configuration
// Generated on Mon Jun 03 2019 23:19:22 GMT+0900 (대한민국 표준시)
const path = require('path');
var webpackConfig = require('./webpack.config')
 
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'],
 
    // list of files / patterns to load in the browser
    files: [
      {pattern: 'src/**/*.spec.js', watched:true, served:true, included: true},
      {pattern: 'src/**/*.spec.ts', watched:true, served:true, included: true},
      {pattern: 'test/**/*.js', watched:true, served:true, included: true}
      /*parameters:
          watched: if autoWatch is true all files that have watched set to true will be watched for changes
          served: should the files be served by Karma's webserver?
          included: should the files be included in the browser using <script> tag?
          nocache: should the files be served from disk on each request by Karma's webserver? */
      /*assets:
          {pattern: '*.html', watched:true, served:true, included:false}
          {pattern: 'images/*', watched:false, served:true, included:false} */    
    ],
 
    // list of files / patterns to exclude
    exclude: [ ],
 
    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],
 
    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,
 
    client: {
      //capture all console output and pipe it to the terminal, true is default
      captureConsole:false,
      //if true, Karma clears the context window upon the completion of running the tests, true is default
      clearContext:false,
      //run the tests on the same window as the client, without using iframe or a new window, false is default
      runInParent: false,
      //true: runs the tests inside an iFrame; false: runs the tests in a new window, true is default
      useIframe:true,
      jasmine:{
        //tells jasmine to run specs in semi random order, false is default
        random: false
      }
    },
    // 여기부터 기본 init에서 수정 사항
    // 웹팩 설정 가져오기?? 아까 설치한 모듈('karma-webpack')
    webpack: {
      mode: 'development',
      //module: webpackConfig.module,
      resolve: webpackConfig.resolve,
      module: {
        rules: [
          {
            test: /\.jsx$/i,
            include: [
              path.resolve(__dirname, 'src')
            ],
            exclude: [/node_modules/],
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env'],
               // plugins: ['@babel/plugin-proposal-class-properties']
              }
            }
          },
          {
            test: /\.tsx?$/i,
            include: [
              path.resolve(__dirname, 'src')
            ],
            exclude: [/node_modules/],
            use: {
              loader: 'ts-loader'
            }
          },
          {
            test: /\.css$/i,
            use: ['style-loader','css-loader'],
          }
        ]
      }
  },
 
  // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'src/**/*.js': ['webpack'], // test/*spec.js을 실행하기 전에 'webpack'을 선행
      'src/**/*.ts': ['webpack'],
    },
 
    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['kjhtml','mocha'/*,'mocha','dots','progress','spec'*/],
 
 
    // 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,
    logLevel: config.LOG_ERROR,
 
    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,
 
    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

Jasmine

Behavior-Driven JavaScript

  • example source
function helloWorld(){
  return 'Hello world!';
}
  • jasmine test spec
describe('Hello world', () => { -- 해설-1
  it('says hello', () => { -- 해설-2
    expect(helloWorld()) -- 해설-3
        .toEqual('Hello world!'); -- 해설-4
  });
});
  1. describe(string,function)함수는 개별 Test Specs의 집합이라 부르는 Test Suite를 정의한다.
  2. it(string,function)함수는 하나이상의 Test Expectations을 갖는 개별적인 Test Spec을 정의한다.
  3. expect(actual)수식은 Expectation라 명명한다. Matcher연결되는 이것은 application에서 기대되는 행위(결과?)의 일부(조각)를 기술한다.
  4. matcher(expected)수식은 Matcher라 명명한다. 이것은 expected값을 expect에 넘겨주는 actual값을 비교하는 논리비교이며, 만약 그것이 실패이면 spec실패이다.

Built-in matchers

Jasmine은 몇가지 미리만들어진 matcher들을 가지고 있다.

expect(array).toContain(member);
 
expect(fn)toThrow(string);
expect(fn).toThrowError(string);
 
expect(instance).toBe(instance);
 
expect(mixed).toBeDefined();
expect(mixed).toBeFalsy();
expect(mixed).toBeNull();
expect(mixed).toBeUndefined();
expect(mixed).toEqual(mixed);
expect(mixed).toMatch(pattern);
 
expect(number).toBeCloseTo(number, decimalPlaces);
expect(number).toBeGreaterThan(number);
expect(number).toBelessThan(number);
expect(number).toBeNaN();
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledTimes(number);
expect(spy).toHaveBeenCalledWith(...arguments);

Jasmine

study/script_test.txt · 마지막으로 수정됨: 2025/04/15 10:05 저자 127.0.0.1