1 00:00:00,520 --> 00:00:04,840 こんにちは、今回は Pharo の sUnit テストフレームワークでの 2 00:00:05,000 --> 00:00:08,720 ユニットテストを見てみましょう。 3 00:00:08,880 --> 00:00:13,200 テストフレームワークはアジャイル開発を 支援するために使われます。 4 00:00:13,360 --> 00:00:16,560 インクリメンタルな開発をして 5 00:00:16,720 --> 00:00:18,720 定期的にコードをテストして 6 00:00:18,880 --> 00:00:23,240 コードの修正でコードに求められる特性や 不変条件を壊していないかを確認します。 7 00:00:23,400 --> 00:00:25,240 変化に備えるということです。 8 00:00:25,400 --> 00:00:28,160 コードを修正したらテストを書いて 9 00:00:28,320 --> 00:00:30,520 テストを再実行することで 10 00:00:30,680 --> 00:00:33,680 どこか壊してしまったり、変えてはいけない 部分を変えてしまっていないかチェックします。 11 00:00:33,880 --> 00:00:38,520 自動化されたテストはこの種のプログラミング を支援する上でとても重要です。 12 00:00:38,680 --> 00:00:42,680 sUnit フレームワークはテストを書くための 特別なフレームワークです。 13 00:00:42,840 --> 00:00:46,400 sUnit は 4 つのクラスで実装されています。 とてもシンプルです。 14 00:00:46,560 --> 00:00:48,960 sUnit は最初、ケント・ベックによって 開発されました。 15 00:00:49,120 --> 00:00:52,960 そして他の言語の数々のテストフレームワーク を生むきっかけになりました。 16 00:00:53,120 --> 00:00:55,040 例えば、JUnitもその1つです。 17 00:00:55,840 --> 00:00:57,440 では、テストとは何でしょう? 18 00:00:57,600 --> 00:01:00,080 テストを書くには 3 段階があります。 19 00:01:00,240 --> 00:01:04,960 第 1 段階では、コンテキストを作ります。 例えば、空集合です。 20 00:01:05,120 --> 00:01:07,480 第 2 段階では、刺激を作ります。 21 00:01:07,640 --> 00:01:11,960 ここでは、さきほど作った集合に 22 00:01:12,120 --> 00:01:14,840 同じ要素を 2 度追加しようとしています。 23 00:01:15,000 --> 00:01:18,760 そして第 3 段階では 得られた結果をテストして 24 00:01:18,920 --> 00:01:23,160 この集合が要素を 1 つだけ含んでいる ことを確かめます。 25 00:01:23,320 --> 00:01:26,960 集合オブジェクトは同じ要素を 1 つしか 持つことができません。 26 00:01:27,120 --> 00:01:28,680 同じ要素は 2 つ持てないのです。 27 00:01:28,840 --> 00:01:32,520 なので、結果をテストして 不変条件が破られていないことを確認します。 28 00:01:33,120 --> 00:01:35,320 テストを書く例題です。 29 00:01:35,480 --> 00:01:40,760 TestCase のサブクラスを書きます。 ここでは SetTestCase です。 30 00:01:40,920 --> 00:01:44,480 集合をテストするものです。 testAdd メソッドを定義します。 31 00:01:44,640 --> 00:01:47,240 テストメソッドの名前は test で始まります。 32 00:01:47,400 --> 00:01:48,960 まず、コンテキストを設定します。 33 00:01:49,120 --> 00:01:52,200 Set クラスのインスタンスを作ります。 空集合です。 34 00:01:52,360 --> 00:01:55,840 同じ要素を 35 00:01:56,000 --> 00:01:59,240 2 回追加します。 36 00:01:59,400 --> 00:02:03,360 5 を 2 回。 ここと、ここで。 37 00:02:03,520 --> 00:02:06,000 そしてチェックします。 38 00:02:06,160 --> 00:02:08,600 チェックには assert: を使います。 39 00:02:09,920 --> 00:02:12,840 集合のサイズが 40 00:02:13,000 --> 00:02:16,480 1 であれば、テストは成功です。 要素が 1 つだけ追加されたということです。 41 00:02:16,640 --> 00:02:19,320 この式を使って 42 00:02:20,720 --> 00:02:24,280 テストを実行することができます。 このテストで条件が守られているかを 43 00:02:24,440 --> 00:02:28,760 つまり assert: の式が true であるか テストします。 44 00:02:29,560 --> 00:02:30,880 名前が test で始まるメソッドは 45 00:02:31,080 --> 00:02:34,960 テストであることを表します。 46 00:02:35,120 --> 00:02:39,640 そしてそれらはテストランナーというツールで 自動的に実行されます。 47 00:02:40,440 --> 00:02:44,480 全ての結果を見ることができます。 テストメソッドの全ての実行の 48 00:02:44,640 --> 00:02:48,040 結果が集計されて 49 00:02:48,200 --> 00:02:52,560 TestResult クラスのインスタンスに 集約されます。 50 00:02:54,120 --> 00:02:55,760 別の例をお見せします。 51 00:02:55,920 --> 00:02:59,920 この例では、名前が test で始まる テストメソッドがあります。 52 00:03:00,080 --> 00:03:03,560 これがメソッド名ですが 53 00:03:03,720 --> 00:03:07,240 testAdjacentRunsWithEqualsAttributesAreMerged 54 00:03:07,400 --> 00:03:12,960 ここにコンテキストがあります。 オブジェクトを作ります。 55 00:03:13,120 --> 00:03:14,720 ここに刺激があります。 56 00:03:14,880 --> 00:03:18,640 addLast:times: メッセージを 57 00:03:18,800 --> 00:03:22,760 3 回送ろうとしています。 1 回目はここにあります。 58 00:03:22,920 --> 00:03:26,880 2 回目がここにあり 59 00:03:27,040 --> 00:03:28,640 3 回目は 2 回目と同じです。 60 00:03:28,800 --> 00:03:31,560 ここでテストします。 61 00:03:31,720 --> 00:03:35,760 要素数が 2 であることを確認します。 いいですか? 62 00:03:35,960 --> 00:03:40,960 同じ要素を 2 回続けて追加する ことはできませんでした。 63 00:03:41,720 --> 00:03:46,320 テストを実行する上で いくつかのシナリオがありえます。 64 00:03:46,640 --> 00:03:50,720 1 つ目のシナリオは「失敗」です。 65 00:03:50,880 --> 00:03:53,720 つまり、表明(assert:)のどれかが 66 00:03:53,880 --> 00:03:56,560 false の場合です。 67 00:03:56,720 --> 00:04:01,560 そういう場合には「失敗」になります。 68 00:04:01,720 --> 00:04:03,600 それは予期された問題です。 69 00:04:03,760 --> 00:04:09,240 潜在的にそういうことが起こり得ると 予期しているわけです。 70 00:04:09,600 --> 00:04:13,160 そして「エラー」があります。 これはチェックしようとしていたものではなく 71 00:04:13,320 --> 00:04:17,240 何かが起こってしまった場合です。 テストを書いた時には 72 00:04:17,400 --> 00:04:20,480 想定していなかった 例外が発生した場合などです。 73 00:04:20,640 --> 00:04:22,480 これらの 2 つのものは別々のものです。 74 00:04:23,120 --> 00:04:27,640 あるコードが例外を発生させることを 75 00:04:28,480 --> 00:04:32,000 確認するためのテストは どう書くのでしょう? 76 00:04:32,160 --> 00:04:36,680 例えば、 Set new remove: 1 をテストしたい時 77 00:04:36,840 --> 00:04:40,120 このコードは NotFound 例外を 挙げるでしょう。 78 00:04:40,280 --> 00:04:42,520 Set new は空集合なので 79 00:04:42,680 --> 00:04:44,640 そこから要素を取り出すことは 80 00:04:44,800 --> 00:04:47,600 無理です。 NotFound 例外が挙がることになります。 81 00:04:47,760 --> 00:04:50,800 これをテストするには should:raise: を使います。 82 00:04:50,960 --> 00:04:53,600 ブロックを渡して そのブロックの実行中に 83 00:04:53,760 --> 00:04:55,240 例外が挙がるかを確認します。 84 00:04:55,400 --> 00:04:59,440 この場合、例外は NotFound です。 このテストはグリーンです。OK です。 85 00:05:00,920 --> 00:05:02,280 反対のことをテストすることもできます。 86 00:05:02,440 --> 00:05:04,680 あるコードが例外を挙げないことを 確認します。 87 00:05:04,840 --> 00:05:08,440 この場合 self shouldnt:raise: を使います。 88 00:05:08,600 --> 00:05:12,880 つまり、このコードは NotFound 例外を 挙げないことを確認します。 89 00:05:14,000 --> 00:05:16,960 テストを沢山書いていると 90 00:05:17,120 --> 00:05:19,480 テストのコンテキストに 91 00:05:19,640 --> 00:05:21,600 沢山の重複ができることがあります。 92 00:05:21,920 --> 00:05:23,880 例えば ここで集合について 93 00:05:24,040 --> 00:05:26,120 もう 1 つテストを書きます。 testOccurrences です。 94 00:05:26,280 --> 00:05:31,800 するとコンテキストで 空集合をまた作ろうとしています。 95 00:05:31,960 --> 00:05:35,120 テストを書くたびに 96 00:05:35,280 --> 00:05:37,880 テストのコンテキストで Set new を書くことになります。 97 00:05:38,040 --> 00:05:41,920 毎回毎回この行を繰り返したくはありません。 98 00:05:42,080 --> 00:05:45,120 繰り返さないためには 99 00:05:45,280 --> 00:05:48,080 それを括り出してしまえば解決します。 100 00:05:48,240 --> 00:05:52,280 sUnit では setUp メソッドに 101 00:05:52,440 --> 00:05:57,160 テストを実行する前の全ての初期化を 括り出します。 102 00:05:57,320 --> 00:05:59,680 こうすることで 103 00:05:59,840 --> 00:06:02,280 テストを実行する直前に 104 00:06:02,440 --> 00:06:05,560 つまり test で始まるメソッドを 実行する直前に 105 00:06:05,720 --> 00:06:08,760 setUp メソッドを実行します。 106 00:06:08,960 --> 00:06:11,200 その setUp メソッドの中で コンテキストを書きます。 107 00:06:11,360 --> 00:06:15,320 テストを通して刺激や 108 00:06:15,480 --> 00:06:17,280 チェック、つまり表明をして 109 00:06:17,440 --> 00:06:20,200 テスト実行の最後で 110 00:06:20,360 --> 00:06:22,360 テストが成功であろうが失敗であろうが 111 00:06:22,520 --> 00:06:24,880 tearDown メソッドを実行します。 112 00:06:25,040 --> 00:06:26,960 tearDown メソッドで全ての 113 00:06:27,120 --> 00:06:29,520 解放すべきリソースをきれいにします。 114 00:06:29,680 --> 00:06:33,360 複数のテストメソッドの実行は簡単です。 115 00:06:33,520 --> 00:06:35,400 まず setUp の実行があり 116 00:06:35,560 --> 00:06:37,720 最初のテストメソッドが実行されて 117 00:06:37,880 --> 00:06:41,360 tearDown を実行して片付けます。 そして新しい setUp の実行があり 118 00:06:41,520 --> 00:06:44,720 新しいテストが実行され tearDown、setUp 119 00:06:44,880 --> 00:06:47,760 テストの実行、そして tearDown という具合です。 120 00:06:47,920 --> 00:06:50,960 こうすることでコンテキストの実装と リソースの片付けを 121 00:06:51,120 --> 00:06:55,040 setUp と tearDown の 2 つのメソッドに括り出すことができます。 122 00:06:56,240 --> 00:06:58,560 どんな風になるでしょうか? 123 00:06:58,720 --> 00:07:01,440 SetTestCase の例では 124 00:07:01,600 --> 00:07:04,640 setUp メソッドを定義して 125 00:07:04,800 --> 00:07:07,320 そこで empty := Set new とします。 126 00:07:07,480 --> 00:07:11,840 つまり empty は SetTestCase の インスタンス変数になります。 127 00:07:12,520 --> 00:07:14,560 そしてテストメソッドの中では 128 00:07:14,720 --> 00:07:18,080 すぐにインスタンス変数 empty を 使うことができます。 129 00:07:18,240 --> 00:07:21,880 testOccurrence を実行する前に setUp メソッドが実行されるので 130 00:07:22,040 --> 00:07:26,800 empty は既に正しく初期化されています。 131 00:07:29,680 --> 00:07:33,040 sUnit のコアのクラス構成を見ると 132 00:07:33,200 --> 00:07:37,600 クラスが 4 つしかありません。 133 00:07:37,760 --> 00:07:41,440 1 つは TestCase です。 TestCase は単に 134 00:07:41,600 --> 00:07:43,560 あるコンテキストにおいて 135 00:07:43,720 --> 00:07:47,000 条件を満たすかどうかを検証するものです。 各 TestCase は 136 00:07:47,960 --> 00:07:50,280 setUp メソッドと tearDown メソッドと 137 00:07:50,440 --> 00:07:52,840 一連のテストメソッドを持っています。 138 00:07:53,000 --> 00:07:57,480 実際に TestCase の新しいサブクラスを 書くことになります。 139 00:07:57,640 --> 00:08:00,520 それらのテストケースは 140 00:08:00,680 --> 00:08:05,080 TestSuite に併せられます。 141 00:08:05,240 --> 00:08:08,560 そして一揃いのテストの実行を行います。 142 00:08:08,720 --> 00:08:11,640 一揃いの実行をすると、結果が得られます。 143 00:08:11,800 --> 00:08:16,040 その結果は TestResult のインスタンスで 144 00:08:16,200 --> 00:08:19,120 何個のテストが合格して 145 00:08:19,280 --> 00:08:22,800 何個のテストが実行されて 146 00:08:23,480 --> 00:08:26,240 何個のテストが失敗やエラーとなったか を持っています。 147 00:08:27,160 --> 00:08:29,560 TestResource というものもあります。 148 00:08:29,720 --> 00:08:33,960 TestResource は TestSuite で使う リソースを定義します。 149 00:08:36,040 --> 00:08:39,760 TestCaseの各サブクラス は 1 つのテストを表して 150 00:08:39,920 --> 00:08:44,040 その test で始まるメソッドが 1 つのテストを表します。 151 00:08:45,360 --> 00:08:47,360 TestSuite は一連のテストで 152 00:08:47,520 --> 00:08:52,320 そのテストケースのテストメソッドから成ります。 153 00:08:52,480 --> 00:08:56,880 TestResult は複数のテスト実行の結果で 154 00:08:58,160 --> 00:09:02,040 TestResource は 155 00:09:02,600 --> 00:09:05,120 一連のリソースの初期化をします。 156 00:09:05,280 --> 00:09:07,520 その初期化というのは通常は 157 00:09:07,680 --> 00:09:10,280 一連のテストで1度だけ初期化したい リソースの初期化です。 158 00:09:10,440 --> 00:09:14,400 TestResource がリソースを 1 度初期化して 沢山のテストを実行して 159 00:09:14,560 --> 00:09:17,440 そして最後に解放します。 160 00:09:17,640 --> 00:09:20,320 今回学んだことは 161 00:09:20,800 --> 00:09:24,520 テストの書き方です。 テストを書くのはとても単純です。 162 00:09:24,680 --> 00:09:27,480 TestCase クラスのサブクラスを書いて 163 00:09:27,640 --> 00:09:31,240 test で始まるメソッドを定義します。 164 00:09:31,400 --> 00:09:33,440 そこにコンテキストの設定を書いて 165 00:09:33,600 --> 00:09:36,960 刺激を与え、表明を検査します。 166 00:09:37,800 --> 00:09:39,720 コンテキストを再利用するには 167 00:09:39,880 --> 00:09:42,240 複数のテストメソッドから 168 00:09:42,400 --> 00:09:45,640 setUp メソッドに括り出すことで おこないます。 169 00:09:47,000 --> 00:09:52,080 まとめると、今回は sUnit テストフレームワークを見ました。 170 00:09:52,240 --> 00:09:54,360 とても簡単に使うことができ 171 00:09:54,520 --> 00:09:57,560 アジャイル開発を開始する上で とても効率的です。 172 00:09:57,720 --> 00:10:01,520 sUnit を使うよう、強く勧めます。 テストはとても簡単に定義できます。 173 00:10:01,680 --> 00:10:04,840 sUnit を使うことで 1 つのテストを作ったら 174 00:10:05,000 --> 00:10:10,400 百万回それを実行できます。 どこかコードを修正した時に 175 00:10:10,560 --> 00:10:13,360 コードがまだ正常に動くことを とても手軽に検査することができます。 176 00:10:13,520 --> 00:10:16,640 テストを最新に保つことで 177 00:10:16,800 --> 00:10:20,720 もしどこか壊れても それを即座に発見できます。 178 00:10:20,880 --> 00:10:25,320 さらに他のフレームワークで テストを書くこともできます。 179 00:10:25,480 --> 00:10:28,640 例えば BabyMock のような Mock フレームワークなど 180 00:10:28,840 --> 00:10:33,440 異なるスタイルのテスト手法があります。 181 00:10:34,480 --> 00:10:38,720 プログラムを書く時には沢山のテストを 書くことを強くお勧めします。