このビデオで紹介するのは
パッケージやクラスを作って テストを記述する方法です。
まず最初に システムブラウザを開きます。
システムブラウザを使って パッケージをブラウズすることができます。
ここにあるのがパッケージです。
最初に、パッケージを作ります。
「Add package」をクリックして、 「MyCounter」と。
パッケージは沢山あるので 全部を見たくはありません。
パッケージをフィルターするといいでしょう。
私たちの 「MyCounter」パッケージがあります。
そして、クラスを定義します。
「Counter」です。 インスタンス変数は「count」です。
ここがオレンジ色になっているのは コードがまだセーブされていないことを示しています。
ここで、「Accept」機能で コードをコンパイルします。
さあこれで Counter クラスが コンパイルされました。
システムが調べて
アドバイスしてきます。これは後で説明します。 とりあえず今は気にしなくて結構です。
赤い「!」記号がありますが これはコメントを書いていないからです。
では、書いてみましょう。
コメントは
「I'm a simple counter…」 （私は簡単なカウンタです…）
簡単な例題を書いてみましょう そうするとカウンターは自分が
どう動作するかわかるようになります。 Counter new
Counter increment increment Counter
count. これで 2 になるはずです。
またもや、テキストはまだセーブされていません。 コンパイルします。
これでセーブされました。
では、アクセサを定義しましょう。
アクセサは一般的には accessingプロトコルに入れます。
countはcountをリターンする、と書きます。
同じように、aNumberを引数にして
セッターを書きます。
おわかりのように 私はcountメソッドを修正ました。
countメソッドが無くなってしまった ように思うかもしれませんが、大丈夫です。
メソッドを変更する時に 違うメソッド名になっていると
新しいメソッドが作られます。
新しいメソッドをコンパイルすると、 count はちゃんとここにあります。
ここで、テストとして 小さなプログラムを書いてみましょう。
Playground を開きます。
カウンタを作って、と。 次の行で
値を入れます。
C count: 7と。 ここで値を訊いてみると
何を返してくるでしょうか？ 「7」が返ってきます.
さて、ここで本当に書きたいのは
テストです。 この書き方では実行できません。
自動的に実行できるようにしたいのです。
テストケースを作ります。
Pharo ではどうやって テストクラスを作るのでしょうか？
スーパークラスを変更して、 継承元を
TestCase にします。 これでテストクラスとしてCounterTestを
定義します。
これをコンパイルします。
システムに新しく CounterTest クラスが できました。
新しいメソッドを定義しましょう。 プロトコルを追加します。
tests プロトコルです.
ここで新しいメソッドを定義します。
Tests のメソッド名は 「test」で始まらなければなりません。
そして TestCase クラスから継承している 必要があります。
メソッド名は testCounterisSetAndRead
とでもしましょう。 これでほとんど完成したようなものです。
必要なことはほとんど書きました。
インデントを整えて
カウンタを作って
ここで self assert
equals 7 この文は
self assert C count = 7 と全く同じです。
ただし、1つ目の文のほうが便利です。 返ってきた値が間違っていた場合に
もっと賢い報告をしてくれます。
コンパイルします。
これでテストを実行して、
テストはグリーンです。 テストがあり、そしてグリーンなので
あなたの製品、つまりコードを セーブするのに良いタイミングです。
Pharo では、イメージをセーブします。
ここではイメージをセーブしますが
イメージのセーブで満足ではありません。
そこでコードを
バージョン管理システムに保存します。
ここで、私はあなたがインターネットに アクセスきでるかわかりませんので
ローカルなキャッシュを使います。
おわかりでしょうか。 このディレクトリには
全てのパッケージが表示されていて
どれがロードされていて どれがロードされていないか判ります。
ここに、変更が保存されていないパッケージが
表示されています。
最初の2つは気にしなくていいです。
MyPackage に星印がついています。 これは、イメージの中のコードが
まだ保存されていないことを示しています。
では保存しましょう。 Saveをクリックして
レポジトリを選択します。
saveをクリックします。
"first version with accessors and a （アクセサ付きで、
green test". テストがグリーンの最初のバージョン）
acceptします。 これで1つのパッケージを保存しました。
確認しましょう。
このディレクトリを開きます。 すると、システムにロードされた
沢山のパッケージが入っています。
フィルタすると、
さきほどのパッケージとそのバージョンが 見つかります。
新しい機能を追加するたびに 保存することを助言します。
これからそうしましょう。
さあ、ここで新しいテストを
実装の前に作ってみましょう。
これからテストを書きます。
カウンターのインクリメントについて
「TestIncrement」 何を書きましょう？
書きたい内容は
カウンターを作って
デフォルト値を代入して
このカウンタを2回インクリメントします。
何をチェックすべきでしょうか？
カウンターが
正しい値かをチェックします。
コンパイルします。テストは
レッドです。まだカウンターを 実装していませんから。
インクリメントとデクリメントは カウンターの操作(operations)です。
operationsを追加します。 increment。
何をしましょう？
self count 2: self count + 1
アクセサーを使うかどうかは
状況次第で スタイルの問題です。
decrementも
同じように定義します。
incrementについては テストがあるので
実行できます。 テストはグリーンです。
これで2つのテストがちゃんと動きます。
テストクラスを見れば 全てのテストがグリーンです。
何をしましょう？
保存します。新規保存します。
「incrementとdecrementを追加した」 と書きます。
さあ、これで 2つのバージョンができました。
パッケージのバージョンです。
「decrement」のテストも書きます。
書かない理由がありませんから。
「Decrement」 例えば
値を2として
2回decrementしたら 0になるはずです。
テストはグリーンです。
なので、保存します。
ここで、欲しい機能があります。
「Counter new」と書いて 「Print it」すると
カウンターが表示されますが 値がわかりません。
あまり便利ではありません。
ここを改良したいと思います。
そこで、メソッドを追加します。
「PrintOn:」です。 「printing」プロトコルに定義します。
「PrintOn:」は
表示するたびにシステムから 利用されます。
引数は「aStream」です。
何をしましょうか？
カウンターだとわかるように
元の機能を使います。
ここで
ちょっと追加して
書きます。
例えば「with value:」（値は） 「self count」
こうすることで 数を
表記できます。
そして「cr」と。
コンパイルします。
システムはもっといい方法があると 言ってきますが、まあいいでしょう。
今回は気にしないでおきます。
「Counter new」と書いてみます。
ほら、値がnilのカウンターだと 表示されました。
これは正常です。 初期化してませんから。
では、初期化に対応しましょう。
まずはテストを書きます。
AtCreationTimeIsZero （カウンターを生成した時の値は
ゼロ）、と。
さあどうしましょう？
「self assert:」として
チェックするのは「Counter new
count = 0」。
これでどうでしょうか？
テストは失敗です。なぜでしょう？
これを実行したら nilが得られるからです。
ここで、Counterはクラスで CounterTestクラスのインスタンス変数には
アクセスしていないので
この表現式を選択して 直接実行することができます。
このテストはまだ正しくないですが
どうしたらいいでしょうか？
initialisation（初期化）プロトコルに initializeメソッドを追加します。
そして、このメソッドで 何をしたらいいでしょう？
「super initialize」と書いて そして
countは0と。
このメソッドは「new」メソッドが 使われるたびに実行されます。
さて、テストを見てみましょう。 グリーンです。
同様に、「Counter new count」は 0になります。
もう一度保存します。 printOnを追加、と。
initializeとテストを追加。
さあ、ここで興味深いのは
ここまでのヒストリーを 見ることができるところです。
さらにこのヒストリーの中を 見てブラウズすることができます。
「version」をクリックすると これら2つの違いが見れます。
バージョン3とバージョン4の違いは
「initialize」「printOn」とテスト。
バージョン2とバージョン4の
違いを見ます。
これらの変更をみんな見ることができます。
さて、これで やり残したことは1つです。
オブジェクトを作る方法を 少し変えます。
まず最初にテストを書くことで
何をするのかを明確にします。 テストを定義します。
「AlternateClassCreation」です。
さて、何がしたいのでしょう？
確認したいことは、
「Counter withValue: 19」を
インクリメントして
値を取り出したら 20が返ってくるということです。
よし、と。
ここに括弧を入れましょう。 そのほうがいいです。
テストはまたもや 成功ではありません。
「未知のメッセージを送っています」 と言っています。
「withValue:」というメッセージは
オブジェクトではなく クラスに送られます。
つまり、このメッセージを
クラスに定義する必要があります。 クラスを選択して
クラスレベルに行って 追加します。
プロトコルは 「instance creation 」
「withValue: aNumber」 さあ、何をすべきでしょう？
最初にすることは
カウンターを生成することです。 変数counterに
…じっくり書いています…
「self new 」 これでカウンターを作って
「self count: aNumber」 と書きます。
そしてこのカウンターを返します。
もっと短く書くこともできますが
とりあえずは単純に書きましょう。
メソッドをコンパイルします。
さて、これでメッセージを送れます。
ほら、このボタンをクリックすると
クラスレベルから
インスタンスレベルに移動します。
これでクラスレベルから
インスタンスへ送られるメッセージ に戻ってきました。
どういうことでしょう？ つまり
「Counter withValue: 18」 とすると、何が得られるでしょう？
Counterクラスのインスタンスが 得られます。
値が18のカウンターが得られます。
そして、ここで decrementできます。
リフレッシュすると 17になります。
ここでテストを見れば
全てのテストはOKです。 なので、ここでまた
保存して、これで完了です。
インスタンス生成のAPIと テストを追加。
今回は以上です。