SharePoint Framework で gulp test を使って自動テストを実行してみる
はじめに
SharePoint Framework でも自動テストを実施したい場合があります。公式ドキュメントでは Jest を使ってテストを実施する方法が紹介されています。
この方法では package.json を書き換えて既定の gulp test ではなく Jest を直接呼び出すようになっています。それでも問題ありませんが、既定の gulp test のままで実施できないかと思い、試してみました。
サンプルコード
実行手順
まず、gulp test が何をするのかを理解する必要があります。SharePoint Framework のツールチェーンでは @microsoft/gulp-core-build パッケージに定義されているタスクを実行しています。
@microsoft/gulp-core-build パッケージのソースを辿ると JestTask というタスクが見つかります。これが実行されているようです。
一般的に Jest を使って TypeScript のコードをテストする場合は ts-jest を使って内部的にトランスパイルします。gulp test によるテストの場合、事前の gulp タスクで tsc や webpack が実行され、lib フォルダーに格納されたコードに対してテストが行われます。
単純なテストを実施する
全体の流れが分かったので、実際にテストコードを書いていきます。まずは @types/jest をインストールします。@microsoft/gulp-core-build が使っている Jest のバージョンが 23.6.0 なので、バージョンを合わせる必要があります。
npm install @types/jest@23.3.14 --save-dev
tsconfig.json で Jest が型解決できるようにします。
"types": [
"es6-promise",
"webpack-env",
+ "jest"
],
components フォルダーに SampleApplicattion.test.tsx というファイルを作成し、テストコードを追加します。
// 必ず PASS するテスト
it('test1', () => {
expect(true).toBe(true);
});
gulp test を実行すればテストが実行されるはずですが、実際に試すと実行されません。JestTask のコードには isEnabled という設定があり、これを true にする必要があります。そのため、config フォルダーに jest.json を追加します。今回は coverage を使わないので false にしておきます。
{
"isEnabled": true,
"coverage": false
}
これで再度 gulp test を実行するとテストが実行されます。
[00:00:00] Starting subtask 'jest'...
PASS lib\webparts\my-application\components\MyApplicattion.test.js
[00:00:00] Finished subtask 'jest' after 1.5
スナップショットテストを実施する
基本的なテストは実施できました。次に React のスナップショットテストを実施します。まずは React をテストできるようにセットアップします。
必要なパッケージをインストールします。
- babel-jest@22.4.4
- react-test-renderer@16.8.6
- @types/react-test-renderer@16.8.3
- babel-preset-env
- babel-preset-react
npm install babel-jest@22.4.4 react-test-renderer@16.8.6 @types/react-test-renderer@16.8.3 babel-preset-env babel-preset-react --save-dev
.babelrc を追加します。
{
"presets": [
"babel-preset-env",
"babel-preset-react"
]
}
テストコードを追加します。
import * as React from 'react';
import { create } from 'react-test-renderer';
import SampleApplication from './SampleApplication';
import { ISampleApplicationProps } from './ISampleApplicationProps';
// スナップショットを作成するテスト
it('test2', () => {
const props = {} as ISampleApplicationProps;
const tree = create(<SampleApplication {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});
この状態でテストを実行するとエラーが発生します。
[00:00:00] Starting subtask 'jest'...
FAIL lib\webparts\my-application\components\MyApplicattion.test.js
● Test suite failed to run
SyntaxError: Unexpected token .
5 | container: 'container_835912dc',
6 | row: 'row_835912dc',
> 7 | column: 'column_835912dc',
8 | 'ms-Grid': 'ms-Grid_835912dc',
9 | title: 'title_835912dc',
10 | subTitle: 'subTitle_835912dc',
at ScriptTransformer._transformAndBuildScript (node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:316:17)
at Object.<anonymous> (lib/webparts/my-application/components/SampleApplication.module.scss.js:7:1)
at Object.<anonymous> (lib/webparts/my-application/components/SampleApplication.js:11:28)
at Object.<anonymous> (lib/webparts/my-application/components/MyApplicattion.test.js:9:22)
[00:00:00] Error - 'jest' sub task errored after 1.86 s
Jest tests failed
[00:00:00] 'test' errored after 8.45 s
[00:00:00]
[00:00:00] ==================[ Finished ]==================
Error - 'jest' sub task errored after 1.86 s
Jest tests failed
これは CSS ファイルを require しようとして失敗しているため、モックを追加します。
config/jest フォルダーに jest.config.json を追加します。
{
"moduleNameMapper": {
"\\.css$": "<rootDir>/__mocks__/cssmock.js"
}
}
__mocks__ フォルダーに cssmock.js を追加します。
module.exports = '';
これでテストが成功します。
[00:00:00] Starting subtask 'jest'...
PASS lib\webparts\my-application\components\MyApplicattion.test.js
[00:00:00] Finished subtask 'jest' after 1.53 s
[00:00:00] Finished 'test' after 7.64 s
おわりに
やれば実現できますが、手間がかかるため、通常は Jest を直接使う方法をおすすめします。
Discussion