No.5 コンポーネントのテスト
前回のステップで、アプリケーション上でのユーザ操作(マウス操作やキーボード操作)をエミュレートする方法について触れました。 操作のエミュレートを学んだところで、続いてはコンポーネント(今回利用するのはExt JS)のテスト方法を見ていきましょう。
Modelのテストを行う
前回作成したサンプルアプリケーションで利用していたフォームコンポーネントに合わせた User Model
を新たに定義し、モデル自身のテストケースを作成してみましょう。
前回の利用したコンポーネント
今回の利用するコンポーネント
今回は新たにグリッドコンポーネントを追加して、テストを行っていきます。
フォームに合わせたモデルの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Ext.define('SiestaSample.model.User', { extend: 'Ext.data.Model', fields: [ 'id', 'first', 'last', 'tel', 'mail', 'address1', 'address2' ], proxy: { type: 'memory' } }); |
合わせてストアも作成しておく
1 2 3 4 5 6 7 8 | Ext.define('SiestaSample.store.Users', { extend: 'Ext.data.Store', requires: [ 'SiestaSample.model.User' ], model: 'SiestaSample.model.User', storeId: 'Users' }); |
各コンポーネントのテストに入っていく前に、まずはこのモデルのテストケースを実装してみましょう。
tests/component1/101_component.t.js
requireOk
を利用して、必要なソースコードを読み込んでからテストケースの実行を行います。
まず最初のUserモデルの生成テストで行っているのは、モデルを生成し、実際にちゃんとインスタンスが生成されているか、生成されたクラス名などは正しいかなどの非常に簡単なチェックを行っています。
その後、予め作成しておいたダミーデータを元にモデルのインスタンスを作成し、想定している各フィールドが正常に設定されているかを、それぞれ t.is
を利用して確認していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | StartTest(function(t) { var _data = { first: 'ゼノフィ', last : 'xenophy', tel : '000-111-2222', mail : 'test@abc.com', address1: 'サンプル住所1', address2: 'サンプル住所2' }; t.describe('Userモデルの生成テスト', function(t) { t.requireOk([ 'SiestaSample.model.User' ], function() { t.diag('サンプルデータを元にUserモデルの生成'); var model = Ext.ModelManager.create({}, 'SiestaSample.model.User'); t.ok('正常にモデルが生成されているか', model); t.is(model.$className, 'SiestaSample.model.User'); }); }); t.describe('Userモデルのフィールドテスト', function(t) { t.requireOk([ 'SiestaSample.model.User' ], function() { t.diag('サンプルデータを元にUserモデルの生成'); var model = Ext.ModelManager.create(_data, 'SiestaSample.model.User'); t.diag('Userモデルの各プロパティに正常に値が反映されているか'); t.is(model.get('first') , _data.first); t.is(model.get('last') , _data.last); t.is(model.get('tel') , _data.tel); t.is(model.get('mail') , _data.mail); t.is(model.get('address1') , _data.address1); t.is(model.get('address2') , _data.address2); }); }); }); |
軽く利用しているメソッドを見ていきましょう。
- describeメソッド
- テストケースのグループ化を行うためのメソッド
- 第1引数:グループ化時の名称
- 第2引数:関数設定
- テストケースのグループ化を行うためのメソッド
- requireOkメソッド
- 引数に指定したクラスファイルの読み込みが完了したタイミングで、引数に設定した関数を実行する
- 第1引数:読み込むクラスファイルの配列
- 第2引数:第1引数で指定したクラスファイルの読み込み完了後、実行する関数
- 引数に指定したクラスファイルの読み込みが完了したタイミングで、引数に設定した関数を実行する
- diagメソッド
- テスト実行時にラベルのようなものを表示する
- 第1引数:画面に表示するためのラベル
- テスト実行時にラベルのようなものを表示する
- isメソッド
- 第1引数と第2引数に渡された値が等しければ、テスト通過
それらを実行した結果が次のようになります。
全てのテストケースを正常にパスすれば、上記のような画面になっているはずです。
Componentのテストを行う
tests/component1/102_component.t.js
続いて、フォームコンポーネントを利用したモデルのテストを実装していきたいと思います。
テストケースの実装の流れについては、先ほどと変わりません。
ただ、今度はフォームコンポーネントと合わせてテストを行いますので、コンポーネントもテストケース上で生成していきます。
コンポーネントを生成後、サンプルデータを用いて生成したレコードをフォームコンポーネントに読み込ませ、フォームコンポーネント上にレコードの値が正常に読み込まれているかの確認を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | StartTest(function(t) { var _data = { first: 'ゼノフィ', last : 'xenophy', tel : '000-111-2222', mail : 'test@abc.com', address1: 'サンプル住所1', address2: 'サンプル住所2' }; // ------ step 1 t.requireOk([ 'SiestaSample.view.Form', 'SiestaSample.model.User' ], function() { // ------ step 2 var model = Ext.ModelManager.create({}, 'SiestaSample.model.User'), form = Ext.widget('app-form', { width: 500, height: 400, renderTo: Ext.getBody() }); t.diag('フォームコンポーネントに空レコードのロード'); // ------ step 3 form.getForm().loadRecord(model); t.diag('フォームにロードされたレコードが生成した空レコードと等しいか'); // ------ step 4 t.is(form.getForm().getRecord(), model); // ------ step 5 model = Ext.ModelManager.create(_data, 'SiestaSample.model.User'); t.diag('フォームコンポーネントに定義済データのロード'); // ------ step 6 form.getForm().loadRecord(model); // ------ step 7 t.is(model.get('first'), form.down('textfield[name=first]').getValue()); t.is(model.get('last'), form.down('textfield[name=last]').getValue()); t.is(model.get('tel'), form.down('textfield[name=tel]').getValue()); t.is(model.get('mail'), form.down('textfield[name=mail]').getValue()); t.is(model.get('address1'), form.down('textfield[name=address1]').getValue()); t.is(model.get('address2'), form.down('textfield[name=address2]').getValue()); }); }); |
利用しているメソッドについては、前のステップでご説明したものになります。
流れとしては(上記ソースコードに次の一覧に合わせて番号を振っています)
- Userモデルとフォームコンポーネントを読み込む
- Userの空レコードを作成し、合わせてフォームコンポーネントを生成
- フォームコンポーネントに空のレコードを読み込ませる
- 空のレコードとフォームにセットされているレコードが等しいかを比較
- サンプルデータを利用して、データが入っているレコードを作成
- フォームコンポーネントに上記レコードを読み込ませる
- 各フィールドコンポーネントから値を取り出し、元のレコードの各フィールドと値が一致しているかを比較
テストを実行した次のようになるはずです。
tests/component1/103_component.t.js
次に行っていくのは、グリッドコンポーネントのテストを行っていきます。
今回のテストで行うのは、グリッドコンポーネントの正常な表示の確認と、データ追加時に正常にグリッドに値が追加されるかの確認を行っていきます。
新たに作成したGrid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | Ext.define('SiestaSample.view.Grid', { extend: 'Ext.grid.Panel', xtype: 'app-grid', initComponent: function() { var me = this; Ext.applyIf(me, { title: '一覧', store: 'Users', columns: [{ dataIndex: 'first', text: '姓' }, { dataIndex: 'last', text: '名' }, { dataIndex: 'tel', text: '電話番号' }, { dataIndex: 'mail', flex: 1, text: 'メールアドレス' }, { dataIndex: 'address1', flex: 1, text: '住所1' }, { dataIndex: 'address2', flex: 1, text: '住所2' }] }); me.callParent(arguments); } }); |
流れとしては、前のステップと同じように予めストアとグリッドコンポーネントを生成し、必要なテストを実装していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | StartTest(function(t) { var input = { first: 'ゼノフィ', last : 'xenophy', tel : '000-111-2222', mail : 'test@abc.com', address1: 'サンプル住所1', address2: 'サンプル住所2' }; t.requireOk( [ 'SiestaSample.view.Grid', 'SiestaSample.store.Users' ], function() { t.diag('Userレコード表示用グリッドコンポーネントテスト'); var store = Ext.create('SiestaSample.store.Users'), grid = Ext.create('SiestaSample.view.Grid', { height: 400, width: 600, renderTo: Ext.getBody(), store: store }); t.diag('初期表示直後は空であることを確認'); t.is(t.getRow(grid, 0), null); store.add(input); t.diag('追加したデータが正常に表示されているか確認'); t.matchGridCellContent(grid, 0, 0, input.first); } ); }); |
ここで新たに出てきたメソッドについて見ていきましょう
- getRowメソッド
- 第1引数:グリッドコンポーネント
- 第2引数:Rowインデックス
- 指定した行のレコードデータを抜き出すためのメソッド
- matchGridCellContentメソッド
- 第1引数:グリッドコンポーネント
- 第2引数:Rowインデックス
- 第3引数:Columnインデックス
- 第4引数:比較値
- 指定したセルの値と、第4引数に指定した比較値の値が一致していればテスト通過
全体的なテストの流れは、先ほどのフォームコンポーネントの際と似ており、グリッドコンポーネント自体のテストとしては
- グリッド生成直後、中身が空であることを確認
- バインドしているストアにデータを追加した際に、正常に表示されていることを確認
といった流れになります。
こちらを実行してみると
組み合わせてテストを行う
最後に今まで1つ1つのコンポーネントで行ってきたテストを、合わせてやってみたいと思います。
テスト内容としては、フォームコンポーネントで入力値を登録し、登録した内容がストアに追加されるとともにバインドされているグリッドに内容が正常に表示されることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | StartTest(function(t) { var input = { first: 'ゼノフィ', last : 'xenophy', tel : '000-111-2222', mail : 'test@abc.com', address1: 'サンプル住所1', address2: 'サンプル住所2' }; t.requireOk( [ 'SiestaSample.view.Form', 'SiestaSample.view.Grid', 'SiestaSample.store.Users' ], function() { var store = Ext.create('SiestaSample.store.Users'), wrap = Ext.create('Ext.Panel',{ title: '組み合わせてテスト', height: 600, width: 600, renderTo: Ext.getBody(), layout: { type: 'vbox', align: 'stretch' }, defaults: { flex: 1 }, items: [{ xtype: 'app-form', autoScroll: true }, { xtype: 'app-grid' }] }), form = wrap.down('app-form'), grid = wrap.down('app-grid'), model = Ext.ModelManager.create({}, 'SiestaSample.model.User'); t.diag('フォームからデータを登録し、グリッドに反映されることの確認'); form.loadRecord(model); // formのコンポーネント作成 var first = form.down('textfield[name=first]'), last = form.down('textfield[name=last]'), tel = form.down('textfield[name=tel]'), mail = form.down('textfield[name=mail]'), reset = form.down('button[name=reset]'), submit = form.down('button[name=Submit]'), inputCheck = form.down('checkbox[name=input-check]'), address1 = form.down('textfield[name=address1]'), address2 = form.down('textfield[name=address2]'); t.chain({ // テキストフィールドに入力 action : 'type', target : first, text : input.first }, { // テキストフィールドに入力 action: 'type', target: last, text: input.last }, { // テキストフィールドに入力 action: 'type', target: tel, text: input.tel }, { // テキストフィールドに入力 action: 'type', target: mail, text: input.mail }, { // チェックボックスチェック action: 'click', target: inputCheck }, { // テキストフィールドに入力 action: 'type', target: address1, text: input.address1 }, { // テキストフィールドに入力 action: 'type', target: address2, text: input.address2 }, { // テキストフィールドに入力 action: 'click', target: submit }, function(next){ t.waitForRowsVisible(grid, function() { t.is(grid.store.getCount(), grid.getView().getNodes().length, '全てのデータがグリッドに表示されています'); t.matchGridCellContent(grid, 0, 1, grid.store.first().get('last'), '名フィールドに正常な値が設定されています'); }); }); } ); }); |
フォームへの登録は、前回の記事のものを流用します。
- 必要なクラスの読み込みを行い
- フォーム、グリッド、ストア、モデル等の必要なインスタンスを生成しておきます
- フォームに対して、空のレコードを読み込ませる
- フォームに対して自動入力を実行
- submitボタン押下後、グリッドにデータが描画されたタイミングで各テストを実行
- ストアに格納されているデータが全て描画されているか確認
- フォームから登録したデータが正常に描画されているか確認
新しく出てきたメソッド
- waitForRowsVisibleメソッド
- 第1引数:グリッドコンポーネント
- 第2引数:コールバック関数
- 引数に設定したグリッドにレコードが描画されたタイミングでコールバック関数を実行
実行した結果が次の画像になります。
今回はここまでになります。
Siestaには様々な機能があり、今回のステップでは説明しきれていないですが、この後のステップでどんどん紹介していきたいと思います。
もし今すぐ知りたいという方は、Siestaのリファレンスが用意されていますのでそちらをご覧ください。
- Siesta API リファレンス