単体テスト。 チップチューニング

画像







テストの作成時にどのアプローチが使用されるかは関係ありません:TDD、BDD、またはその他。 単体テストは、バグの回避に役立つ主要な保護バリアです。 また、よく説明されているケースは、同僚がプロジェクトで何が起こっているかを理解するのに役立ち、コードのfireを壊すことはありません。







ポイントに行きましょう:







特定の問題があります:5k +単体テストは12分で合格します-これは、パッケージとアセンブリ自体をインストールする時間の2倍です。







これはたくさんあります。







各アセンブリが1日にこれを行うのにどれくらいの時間がかかるかを把握すると、悲しくなります!







画像







問題ごとに各テストを選択しても、それほど変わりません。 テストを破棄することはできませんが、時間を短縮する必要があります。







小さくて便利なプラグインkarma-shardingがあります。これにより、複数のブラウザーを並行して実行できます。これらのブラウザーでのテストケースの配布は、開発者の負担になります。







ウェブパックとカルマを備えた格納庫のスターターでの単体テストの通常の構成は、簡単に次のようになります。







karma.conf.js karma configは、処理されるファイルを設定します。







files: [ { pattern: './config/spec-bundle.js', watched: false }, { pattern: './src/assets/**/*', watched: false, included: false, served: true, nocache: false } ]
      
      





次に、webpack config webpack.test.jsのプリプロセッサを接続します







 preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] }
      
      





spec-bundle.jsファイルが2回表示されることに注意してください。







このファイル内では、次のことが起こります。







最初のステップは、必要な依存関係をインストールすることです。これがないと、角度コードはテストで開始されません。







 Error.stackTraceLimit = Infinity; require('core-js/es6'); require('core-js/es7/reflect'); require('zone.js/dist/zone'); require('zone.js/dist/long-stack-trace-zone'); require('zone.js/dist/proxy'); // since zone.js 0.6.15 require('zone.js/dist/sync-test'); require('zone.js/dist/jasmine-patch'); // put here since zone.js 0.6.14 require('zone.js/dist/async-test'); require('zone.js/dist/fake-async-test'); require('rxjs/Rx'); var testing = require('@angular/core/testing'); var browser = require('@angular/platform-browser-dynamic/testing'); testing.TestBed.initTestEnvironment( browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting() );
      
      





ファイルの2番目の部分は、単体テストファイルのコンテキストです。 このコンテキストでwebpackをビルドすると、すべての解決済みファイルが定期的にロードされます。 これらは、カルマが開始するまさに単体テストです。







 /** * Ok, this is kinda crazy. We can use the context method on * require that webpack created in order to tell webpack * what files we actually want to require or import. * Below, context will be a function/object with file names as keys. * Using that regex we are saying look in ../src then find * any file that ends with spec.ts and get its path. By passing in true * we say do this recursively */ var testContext = require.context('../src', true, /\.spec\.ts/); /** * Get all the files, for each file, call the context function * that will require the file and load it up here. Context will * loop and require those spec files here */ function requireAll(requireContext) { return requireContext.keys().map(requireContext); } /** * Requires and returns all modules that match */ var modules = requireAll(testContext);
      
      





開発モードではすべてのテストを一度に実行する必要はないため、1つのモジュールで十分であり、そのようなモジュールのテスト実行時間に問題はありません。 すべてが十分に速く起こります。







これらの非常に12分間が本番/ビルドテストです。 この特定のケースを検討します。







問題を解決するために、N個のブラウザーのすべてのテストを並列化します。 karma-shardingプラグインを接続するのに多くの操作は必要ありません。







最初に、フレームワーク内のフレームワークにカルマを追加します







 frameworks: [..., 'sharding']
      
      





第二に、これはプラグイン設定自体を追加しています







 sharding: { specMatcher: /(spec|test)s?\.js/i, base: '/base', getSets: function(config, basePath, files) { // splitForBrowsers - some util function return splitForBrowsers(files.served) .map(oneBrowserSet => [someInitScript].concat(oneBrowserSet)); } }
      
      





デフォルトでは、構成は定義できません。 ただし、テストが含まれるファイルがいくつかある場合は、基本構成でのみ機能します。







 [a1.spec.js, a2.spec.js, … aN.spec.js]
      
      





N個のブラウザのセットは次のようになります。







 [a1.spec.js], [a2.spec.js], … [aN.spec.js]
      
      





およびN / 2の場合、それぞれ次のようになります。







 [a1.spec.js, a2.spec.js], [a3.spec.js, a4.spec.js], … [aN-1.spec.js, aN.spec.js]
      
      





そして、すべてがシンプルですが、Angularとwebpackの場合はそうではありません。 1つのテストファイルは2つの部分で構成されます。







 1 -   //some setup code 2 -  - //require.context('../src', true, /\.spec\.ts/);
      
      





アプリケーション全体をテストする場合、さまざまなテストセットを備えたこのようなファイルがいくつか必要になりますが、そのようなファイルのアセンブリはすぐには行われないため、多くの時間がかかります。 たとえば、Webpackモジュールに変換されたそのような必要な依存関係の結果のコードは、10万行に近づきます。







しかし、カットします!







つまり、このような独立した各ファイルを2つの部分に分割します。1つ目は必要な依存関係と設定すべて-setup.js、2つ目はwebpackコンテキストを介して接続されたテストスイート-testsN.jsです。 setup.jsはインストールの一般的なセットであり、テストケースのすべてのセットで同じなので、そのようなファイルが1つあります。







その結果、次の一連のファイルを取得する必要があります。







setup.js

tests1.js

tests2.js

...

testsN.js







次のセットで収集する必要があるもの:







 [setup.js, tests1.js], [setup.js, tests2.js], … [setup.js, testsN.js]
      
      





ステップ1







最初のステップは、ユニットテストですべての必要なファイルを検索してコード全体を調べ、それらを複数のファイル(testN.js、使用する予定のブラウザーの数に応じて)、いくつかのNに分けます。たとえば、同じtest1.jsなどのファイル次のようになります。







 require('/Users/guest/test-project/src/modules/accounts/accounts.spec.ts'); require('/Users/guest/test-project/src/modules/cards/cards.spec.ts'); require('/Users/guest/test-project/src/modules/users/users.spec.ts'); ...
      
      





もちろん、ファイルごとのケースの配布は、必要に応じて実装できます。 私たちの場合、これは* .spec.tsファイルのケース数のほぼ均一な分布です。







必要なすべてのファイルを、都合の良い任意のフォルダー(特定のtmpディレクトリー)に収集します。

その後、webpackを次のエントリに設定します。







 entry: { entry = fs.readdirSync(path.join(tmp)).reduce((entries, fileName) => { entries[fileName] = path.join(tmp, fileName); return entries; }, {setup: path.join(tmp, 'setup.ts')}); },
      
      





共通のチャンクとしてセットアップを構築することが重要です。その後、各テストセットの前にセットアップをロードできます。







 new CommonsChunkPlugin({ name: 'setup', minChunks: module => /setup.test/.test(module.resource) })
      
      





そのため、webpackを実行した後、コンパイル済みのsetup.jsおよびNファイルとテストケースを取得します。 この実行は、テストを実行するときの2つの最初のステップになります。







ステップ2







これがカルマとカルマのシャーディング設定です。 既に説明したように、多くの設定はありません。 最も興味深いのは、一連のテストケースgetSetsを収集する関数です。







 const {splitArray, isSpecFile} = require('karma-sharding/lib/utils'); … function getSets(config, basePath, files) { const setupScript = files.served.find(file => file.path.indexOf('setup') > -1); const specs = files.served .map(file => return config.base + file.path) .filter(filePath => isSpecFile(filePath, config.specMatcher) && !/(setup)/.test(filePath)); return splitArray(specs, config.browserCount).map(set => { return set.concat([config.base + setupScript.path.replace(basePath, '')]); }); }
      
      





SpecMatcher config-ここでは、コンパイルされたsetup.jsおよびすべてのtestsN.jsファイルがtmpディレクトリにあります。







これで、カルマの構成の準備が整いました。

次に、webpackを起動してテストをビルドし、karmaを起動します







さて、もちろん数字:







5k +単体テスト

前:1つのブラウザで-12分

後:10個のブラウザで-3分







4回、カール!








All Articles