本セッションのレギュレーション

和田卓人氏:よろしくお願いします。みなさん、こんばんは。和田卓人です。今日は「サバンナ便り」というタイトルで、自動テストに関する知見についてお話ししたいと思います。

まず今日のレギュレーションといいますか。どんどん話していくんですが、オンラインの講演はライブ感とかリアルタイム感とか、そういったところがとても大事になってきます。

なので、みなさんもTwitterで「QiitaConference」というハッシュタグでの実況ツイートとか、あるいはZoomチャットとかで、ばんばん賑やかに実況してもらえるととてもありがたいです。

私もオンラインで講演しているわけですが、オンライン講演って基本的になんというか、孤独なものなんですね。壁に対してしゃべっているみたいな感じになってしまいがちなので、実際にこの壁の向こうにみなさんがいて、リアルタイムにこの講演を聞いていて、おもしろいなと思ったり「ここはもうちょっと聞いてみたいな」と思ったり。そういった感想をもらえるのをとても楽しみにしているし、講演者側としては心の支えにしています。今はZoomでもチャットがガーッと盛り上がって大変助かりますが、こんな感じでやっていきたいと思っています。

ということであらためましてタイトルです。「サバンナ便り」というタイトルです。「なんでこんなタイトルなの?」というのはのちほど話しますが、雑誌で自動テストに関するコラムを連載しています。このコラムの連載において得られた知見をまとめて、あらためてみなさまに届けたいと考えています。

今日の講演自体は、スクリーンショットを撮ってもらって、#QiitaConferenceのタグを付けてばんばんツイートしてもらってかまいません。というようなレギュレーションでやっていきます。

和田氏の自己紹介

ということで自己紹介です。和田卓人です。インターネット上だと和田卓人というより“t_wadaさん”と呼ばれています。紛らわしいことに“t_wadaさん”にも数種類あって。最初にHatenaアカウントで、当時使っていたメールアドレスからt-wadaというアカウントを取ったんですね。

それがTwitter時代になって「Twitterを始めるか」となったんですが、ハイフンが使えないんですよね。ということで、アンダースコアのt_wadaを取ることになりました。

そのあとGitHubでオープンソースソフトウェアの開発をする時代になると、今度はアンダースコアが使えないので、なしになるみたいな感じで。最初に記号付きのアカウントを使っちゃったがために、こんな感じの紛らわしいID運用を迫られることになってしまった。

ということなのでみなさん、「これからソーシャルアカウントをどんどん使っていくぞ」という人は、記号なしのアカウントを取るのがいいんじゃないかなと思っています。これが私からの最初のアドバイスです。

あらためて、(本セッションでは)スクリーンショットをばんばん撮ってもらってかまいません。資料はのちほど公開します。みなさまの手元での録画だけはご遠慮くださいというような感じでやっていきます。

ということで、私は今「壁に向かってしゃべっているようだ」と言ったんですが、講演はいつもメインのマシンを全画面にしてやっているんですね。サブのPCが僕の斜め前にあって、そこにZoomのチャット欄とTwitterのハッシュタグを開きっぱなしにしちゃいます。

そこでワイワイやっているかとか、リアクションが見えることが私の心の支えになって講演を前に進ませてくれるので、ぜひぜひワイワイよろしくお願いします。

なぜセッションテーマが「サバンナ便り」なのか

ということでサクッといきましょう。本業はコンサルタントでありプログラマーなんですが、副業として技術書の出版に関わっています。現在書店で手に取れる本としては4冊あり、いろいろやっているという感じですね。今日の講演内容は3冊目に翻訳した『テスト駆動開発』という本にもけっこう深く関わっています。

今日の講演の「サバンナ便り」というタイトルなんですが、「何がサバンナ便りなの?」というと、雑誌のコラムの連載タイトルが「サバンナ便り」で。2ヶ月に1回発行されている技術の技術評論社から出ている『WEB+DB PRESS』という雑誌でコラムの連載をしています。このコラムの連載タイトルが和田卓人の……。「和田卓人の」は紹介だけか。「サバンナ便り」というタイトルなんですね。

「何がサバンナなの?」というと、私はテスト駆動開発、テスト・ドリブン・デベロップメント……。「プログラマーも自動テストを書きながらコードを書いていこう、開発をしていこう」という一種のプログラミング手法について日本で紹介を始めて、だいたい16、7年くらいになるんですね。

「テストを書いてガンガンやっていこう」というイベントを開いたり講演をしたり、いろいろやっていくうちに、一種の悪ふざけですが、いつのまにか僕の友人が「2ちゃんねる」発祥のライオンのアスキーアートと私を結びつけて、雑コラを作るという事件がありました。その雑コラが拡散して独り歩きをして、「t_wada」で画像をググるとひどいことになる感じなんですね。

(スライドを示して)これはソフトウェアテストの技術者である知り合いの方に『ジョジョの奇妙な冒険』風の画風で紹介画像を作ってもらって。これが私の自己紹介の最後のページでかつ(この絵は)家宝なんですが、こんな感じでやっていきます。

手を動かしながら学んでいくための「学習用テスト」

ということで、始めたいと思います。今日のアジェンダは連載の各回のテーマに沿ってだんだん立体的に作り上げていくことをやっています。なので連載第1回、第2回、第3回みたいな感じで。さらに今書店で発売されている最新号の話を盛り込んで、最後にプラスαで話します。

ということで最初のテーマ。これは学びを自動テストとして書く、学習用テストという考え方です。「学習用テストって何?」というと、我々ソフトウェアエンジニアは技術を学んでいく際に、手を動かしながら学んでいくことがとても大事なんですよね。

それだけじゃなくて、あの時に学んだことを今も再現できるかどうか、学んだ内容を今まさに同じかたちで再現できるかどうかという、再現性を確保しながら学んでいくのもとても大事です。それを自動テストでやろうというのが学習用テストという考え方です。

例えば実際に私が学習用テストを書いた例としては、PHPに関する講演を行う時に、PHPのDateTimeクラスとDateTimeImmutableクラスを調べたことがあるんですね。最近のプログラミング言語は、状態の変化を排するような、つまり初期化時に状態が確定したらそれ以降状態が変わらないようなスタイルを好むようになってきているんですね。

それがイミュータブルなんですが、歴史の長いプログラミング言語で、JavaScriptもそうだしPHPもそうですが、例えば日付クラスというものが可変だったりするんですね。setDateとかsetTimeみたいなやつができるみたいなところだったりするわけですよ。

ということで、可変のDateTimeクラスと不変のDateTimeImmutableクラスというものがある。「本当かいな?」ということを調べてみようというのが、学習用テストです。

(スライドを示して)実際に私がある講演のためにDateTimeとDateTimeImmutableの動きの違いを調べてみたのがこちらです。例えばここでいうと、DateTimeのインスタンスにaddメソッドを呼ぶと、自分自身の状態、日付も変わるんですね。

それに対して「DateTimeImmutableのインスタンスに足し算、addを行うと自分の状態は変えずに日付が変わった新しいDateTimeImmutableが返される」とドキュメントには書いてあるんだけど本当かな? と。調べてみないといけないわけですよね。ということで「本当かな?」ということを自動テストで書く。

その時に学びの内容をテストの上に書いておく。これもとても大事だし、それだけじゃなくて、「これは学習用テストですよ」と見分けるコツは、タグを付けることです。テストにタグを付けるやり方はいろいろな言語のフレームワークでいろいろあります。

例えば今画面で見えているPHPにおいては、@groupというアノテーション、これが実質的にはタグです。「learning、学習用テストですよ」というタグを付けて見分けられるようにするし、なんなら学習用テストは自分が作りたいもののテストではないので、あとから消すとかスキップすることもできるようなメタデータを付けておくというのが、学習用テストの最初の考え方です。

「学習用テスト」では疑問をテストにすることもできる

疑問をテストにもできます。例えばタイムゾーンがありますよね。日付のクラスとかを扱っている時に必ず出てくる、タイムゾーンという概念。同じ時刻を指しているんだけどタイムゾーンだけ違うこともありえる。

例えば9時間違いとか普通にあり得ますよね。9時間違いでUTCとAsia/Tokyoの時刻は同じ瞬間を指し示しているわけですが、これが日付のインスタンスとして等価であるか等価ではないかは、解釈の分かれるところです。

どちらでも正しいと言えますよね。どちら(か)が正しい振る舞いというものではないです。でもある1点を示しているインスタンス同士が等価かどうか。これは調べてみるしかないですよね。

ちなみに確かこれはドキュメントにはなかったと思うんですが、テストで聞いてみれば一発なわけです。PHPにおいてこれはイコールであるということがわかったわけですね。こういうのも学習用テストの良いところです。疑問をテストにしていく。

「学習用テスト」では驚きをテストに翻訳していくこともできる

驚きをテストに翻訳していくこともできます。どんな驚きか。例えばPHPに関して講演していく時に発見してしまった驚きがあって。それはPHPのコンストラクタ(です)。PHPというのはオブジェクト指向サポートがあとから追加されたので、Pythonもそうなんですが、「内部的にはコンストラクタはこの関数が呼ばれます、メソッドが呼ばれます」みたいなものがあるんですね。それを明示的に呼ぶと、2回以上呼べてしまうみたいなことがあります。

(スライドを示して)ちなみにこれは『BLEACH』のセリフです。「本当かいな? やってみよう」というところですね。

やってみるとやはり呼べちゃうんですよね。こういうことが調べられるのも、学習用テストの良いところです。PHPにおいては、__constructというメソッドがnewをすると間接的に呼ばれるコンストラクタのメソッドです。

なのでこれを明示的にもう1回呼ぶと、先ほどはImmutable、不変クラスだと言っていたのに、もう1回コンストラクタを呼ぶと可変にできてしまうわけですね。

これは裏口から手を突っ込んでいるようなもので、バグかバグじゃないかというのが……。ちなみにこのページが話題になってPHPの開発元にissueが報告されて、「これはバグなのか」「それとも直接コンストラクタを呼ぶというのはイレギュラーな振る舞いなんだから、これはできてしかるべき・このままで良い(のか)」という議論が行われたりしました。

というのも、実際に再現性のある自動テストとして書いておくと、このまま一種のエラーレポートというか、「こうなりましたよ」というかたちで共有できるという例になっています。

私が書いたテストコードがきっかけになっていろいろ議論が呼ばれたということで、思い出深い出来事だったりします。驚きを学習用テストにすることもできるという感じですね。というのが第1回でした。

(次回につづく)