2016-04-16 9 views
2

私はreact/redux/webpackでアプリを書いています。私はカルマ、モカとのテストを構築しており、テストカバレッジのためにイスタンブールを使いたいと思っています。カルマ・カバレッジで動作するようにカバレッジを取得しようとする試みで、私はkarma.config.jsイスタンブールのテストカバレッジリアクション - _registerComponent(...):ターゲットコンテナはDOM要素ではありません

var argv = require('yargs').argv; 
var path = require('path'); 
var webpack = require('webpack'); 

const PATHS = { 
    test: path.join(__dirname, 'test'), 
    app: path.join(__dirname, 'app'), 
} 

module.exports = function(config) { 
    config.set({ 
    // only use PhantomJS for our 'test' browser 
    browsers: ['PhantomJS'], 

    // just run once by default unless --watch flag is passed 
    singleRun: !argv.watch, 

    // which karma frameworks do we want integrated 
    frameworks: ['mocha', 'chai'], 

    // include some polyfills for babel and phantomjs 
    files: [ 
     'node_modules/babel-polyfill/dist/polyfill.js', 
     './node_modules/phantomjs-polyfill/bind-polyfill.js', 
     // './test/**/*.js', // specify files to watch for tests, 
     'test/index.js', 
    ], 

    preprocessors: { 
     // these files we want to be precompiled with webpack 
     // also run tests through sourcemap for easier debugging 
     // 'test/*.spec.js': ['webpack'], 
     'test/index.js': ['webpack', 'sourcemap'] 
    }, 

    // A lot of people will reuse the same webpack config that they use 
    // in development for karma but remove any production plugins like UglifyJS etc. 
    // I chose to just re-write the config so readers can see what it needs to have 
    webpack: { 
     devtool: 'inline-source-map', 
     resolve: { 
     // allow us to import components in tests like: 
     // import Example from 'components/Example'; 
     root: PATHS.app, 

     // allow us to avoid including extension name 
     extensions: ['', '.js', '.jsx'], 

     // required for enzyme to work properly 
     alias: { 
      'sinon': 'sinon/pkg/sinon' 
     } 
     }, 
     module: { 
     // don't run babel-loader through the sinon module 
     noParse: [ 
      /node_modules\/sinon\// 
     ], 
     preLoaders: [ 
      // instrument only testing sources with Istanbul 
      // { 
      //  test: /\.js$/, 
      //  include: path.resolve('app/'), 
      //  exclude: /node_modules/, 
      //  loader: 'istanbul-instrumenter' 
      // } 
      { 
       test: /\.jsx?$/, 
       exclude: [/node_modules/, /test/], 
       loader: 'isparta-instrumenter-loader' 
      }, 
     ], 

     // run babel loader for our tests 
     loaders: [ 
      { 
      test: /\.css$/, 
      loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' 
      }, 
      { 
      test: /\.jsx?$/, 
      loader: 'babel', 
      exclude: /node_modules/, 
      query: { 
       presets: ['es2015', 'react', 'survivejs-kanban'] 
      } 
      }, 
     ], 
     }, 
     // required for enzyme to work properly 
     externals: { 
     'jsdom': 'window', 
     'cheerio': 'window', 
     'react/lib/ExecutionEnvironment': true, 
     'react/lib/ReactContext': 'window' 
     }, 
    }, 
    // displays tests in a nice readable format 
    reporters: ['spec', 'coverage'], 
    webpackMiddleware: { 
     noInfo: true 
    }, 
    // tell karma all the plugins we're going to be using to prevent warnings 
    plugins: [ 
     'karma-mocha', 
     'karma-chai', 
     'karma-webpack', 
     'karma-phantomjs-launcher', 
     'karma-spec-reporter', 
     'karma-sourcemap-loader', 
     'karma-coverage' 
    ] 
    }); 
}; 

カルマのエントリポイント以下に設定しているだけでtest/index.jsです。このように見えるのは

// require all the tests so they will run. 
const testsContext = require.context('.', true, /spec/); 
testsContext.keys().forEach(testsContext); 

// require all the .js and .jsx files in app so they will be included in coverage 
const componentsContext = require.context('../app/', true, /jsx?$/); 

// Date: April 16 2016 
// Author: Benjamin Conant 
// componentsContext.keys() is an array that includes file paths for all the 
// .js and .jsx files in ./app .... karma fails with 
// PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR 
// Invariant Violation: _registerComponent(...): Target container is not a DOM element. 
// at /Users/benconant/Dev/MyFin/my-fin-front-end/test/index.js:15283 <- webpack:///~/react/~/fbjs/lib/invariant.js:45:0 
// if the entry point index.jsx file is included. Seems to have somthing 
// to do with trying to actually write to the DOM. So, I filter out index.jsx and the tests run very well. 
// This means that we will probubly not be able to test index.jsx until this is solved. 

let componentsContextKeysWithoutIndexJsx = componentsContext.keys().filter(function (filePath) { return filePath !== './index.jsx' }); 
componentsContextKeysWithoutIndexJsx.forEach(componentsContext); 
// componentsContext.keys().forEach(componentsContext); --- the way it should be if we did not have to remove ./index.jsx 

日付のコメントから分かるように、 index.jsxは、私は私が手テスト...

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR 
    Invariant Violation: _registerComponent(...): Target container is not a DOM element. 
    at /Users/benconant/Dev/MyFin/my-fin-front-end/test/index.js:15283 <- webpack:///~/react/~/fbjs/lib/invariant.js:45:0 

を実行すると、ここで私が反応し、生態系の中に一週間程度だのでほぼ確実にやっている参照

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux';; 
import { createStore, combineReducers, applyMiddleware } from 'redux'; 
import { Router, Route, Link, browserHistory, hashHistory, IndexRoute } from 'react-router'; 
import { syncHistoryWithStore, routerReducer } from 'react-router-redux'; 

import injectTapEventPlugin from 'react-tap-event-plugin'; 
injectTapEventPlugin(); 


import configureStore from './store/configureStore'; 
import todoApp from './reducers'; 
import App from './containers/app/App'; 
import IntroSlides from './containers/IntroSlides'; 
import LandingPage from './containers/LandingPage'; 

let store = configureStore(); 

const history = process.env.HASH_ROUTING ? syncHistoryWithStore(hashHistory, store) : syncHistoryWithStore(browserHistory, store); 


ReactDOM.render(
    <Provider store={store}> 
    <Router history={history}> 
     <Route path="/" component={App}> 
     <IndexRoute component={LandingPage} /> 
     <Route path="intro" component={IntroSlides}/> 
     </Route> 
    </Router> 
    </Provider>, 
    document.getElementById('app') 
) 

のための私のindex.jsxがあり、含まれている場合何かばかげているが、これは多くの時間を費やしており、大いに助けになるだろう!

+0

この質問は非常に関連していますhttp://stackoverflow.com/questions/30751385/karma-coverage-and-babelbrowserify-preprocessing –

答えて

1

私はReactがHTMLをレンダリングする必要があった要素を見つけることができなかったため、私の場合も同じ問題が発生しました。

は、私は私のメインのjsファイルに次のif文を追加することにより、クイックフィックスが見つかりました:

if ($('#app').length <= 0) { 
    $('body').prepend('<div id="app"></div>'); 
} 

ReactDom.render(
    <App />, 
    document.getElementById('app') 
); 

私は、これはそれを固定する最善の方法であってはなりません承知だけど、少なくともそれは今のために働きます。誰かがもっと良い方法を知っているなら、私たちに知らせてください!

私はあなたのコメントに記載されたスレッドにこのソリューションを掲載しました。

関連する問題