ファシリテーター自己紹介

新井成一氏(以下、新井):ではさっそく始めたいと思います。よろしくお願いします。「AKIBA.MAD」ということで、「実戦から学ぶ AWS Lambdaのテスト戦略」というウェビナーを開催します。

本日ファシリテーターを担当している、新井と言います。よろしくお願いします。私は、クラスメソッド株式会社のCX事業本部MADチームで、サーバーサイドエンジニアやっています。ふだんは IoTやAPIのバックエンドの開発を担当しています。

AKIBA.MADの趣旨

まず、この勉強会の趣旨みたいなところをお話しします。一言で言うと、弊社クラスメソッドという会社のCX事業本部MADチームが主催する勉強会になります。基本、技術寄りのセミナーで、パネルディスカッション形式で、1つのテーマを数人でわいわい話す感じの会にできればと思っています。

適宜から質問も随時募集しています。もしちょっと反応がよければ、定期開催も考えています。

まとめると、“ナレッジを共有し合う場”と捉えてもらえればいいかと思っています。事前に準備したスライドをもとに発表するのではなく、口頭ベースで、パネラー同士や、視聴者のみなさんが、意見交換し合う場として捉えてもらえればと思っています。

AKIBA.MADのルールです。あくまで僕らの中のルールで、あまりみなさんには関係ないかもしれませんが、「一応こんなスタンスでやっていますよ」ということだけ、少し伝えられれば思っています。基本楽しくやりましょう。凝った準備はしないでやりましょう。わからないことがあっても、気にせず、それ自体が学びの場になればいいと思っています。

基本、参加者数やアンケート数にあまり囚われないでやってこうと思っています。以上です。

パネラー自己紹介

本日のお品書きですが、このあとパネラーの紹介をして、本日のテーマを紹介して締めたいと思います。では、パネラーの紹介にいきます。まずは、和田さんから自己紹介お願いします。

和田:MADチームの和田です。いろいろとアプリケーションのかたちがあると思いますが、私は最近よく、AWSのサーバーレスでアプリケーションを組むことが多くて。それに関するテストの話がちょっと多くなるかもしれませんが、やっていければと思っています。

サーバーレスに関しては、(スライドの)下に載せているようなところで、いろいろと話したり、Twitterでも絡んでいる方もいる思うので、内容が重複するかもしれませんが、今日のテーマに沿って話ができればなと思います。よろしくお願いします。

新井:では次、加藤諒さん、自己紹介お願いします。

加藤諒氏(以下、加藤):加藤諒です。バックエンドエンジニアですが、もともとはインフラエンジニアとしてキャリアをスタートしていました。インフラからバックエンドに、レイヤーが上がってきたような感じです。ふだんはTypeScript、Python、Goあたりで、バックエンドAPIを作っています。サーバーレス開発することが多いですが、今はECSやコンテナを使って、Goでアプリケーションを書いたりしています。よろしくお願いします。

新井:では次、佐藤智樹さんです。

佐藤智樹氏(以下、佐藤):佐藤智樹です。自分だけ、IoTというチームにいます。MADの案件にちょっと関わっているので、呼んでもらった感じです。前職では、SIerのSEで4年ぐらい、大規模な業務システムのシステムテストの設計とかをよくやっていました。現在はサーバーサイドエンジニアをやっています。

好きなサービスは、LambdaやCDKです。今日はテストに関する話、Lambdaに関する話をできればと思っているので、よろしくお願いします。

テストコードに関するアンケート

新井:ということで、以上3名のパネラーの方と一緒に始められればと思っています。さっそくですが、ちょっとみなさんのことを知りたいなと思っていて。今からアンケートに答えてもらえればと思います。みなさんが、どれくらいテストコードを書いているのかみたいなところを知りたい。

和田:これはLambdaでいいですか?

(一同笑)

新井:今回はLambdaに絞っています。バシバシ来ていますね。すごい。そろそろ締め切りたいと思います。では投票終了します。

和田:ありがとうございます。Pythonなんですね。

新井:次点でNode.jsという感じですね。

佐藤:どこかでTwitter投票があったときに、前もだいたいこんな感じか、Goがある程度多かったぐらい。やはりPythonが多いですね。

新井:多いですね。割合的には、テストコードは書いてないほうが多いですね。

和田:そもそもLambdaファンクションが、テストが必要になるレベルのコードを書くか、という話もありますから。

新井:確かに。ありがとうございます。ちょっと続きをいきたいと思います。

「モック」「Spy」「Fake」の定義

本日のテーマですが、AWS Lambdaのテスト戦略です。トピックを一応3つ用意しています。どういった領域でテストしているのか、テストで便利な使っているツールの話、あとはソフトウェア設計の話です。用意しましたが、あまりこれに囚われなくてもいいと思っていて。盛り上がった話題を、どんどんみんなでわいわい話せればと思っています。一応、仮で置いている感じです。

その前に、ちょっと言葉の定義だけ僕から少しだけ説明します。“これが正しい”というわけではありませんが、よくテストを書くときに、モック、Spy、Fakeとあると思いますが、今回、モックは「テスト対象が呼び出す依存コンポーネントをコードで疑似的に作成すること」。これはよく「モック化」「モックする」と言うと思いますが、こういう定義にします。

似たような言葉で、「スタブ」というのがあると思いますが、モックツールがスタブの機能を兼ね備えていたり、けっこうややこしいです。そのため、今回はそのモックとスタブの細かい違いについてはいったん無視して、同じものとして扱ってもらえればと思います。Spyは、テスト対象が呼び出す依存コンポーネントへの呼び出し回数や、入力値などの細かいところを観測するためのものだと思ってもらえればいいです。

最後にFakeです。AWSだと、FakeはLocalStackなどを使うと思います。そういったものを指します。

佐藤:自分もこのあたりの話をお客さんにするときに、「マーティン・ファウラーさんが声を出しているから、とりあえず見てみて」と言われて話をしてましたが、実際チームでコードを書き始めるとき、最初にこういう話をしますか? 和田さんとか、加藤さんとか、どうなんだろうなと思って。

和田:必要になったときに話すぐらい。このあたりの用語の説明は、けっこうツールに任せています。

佐藤:そうですね。

和田:例えば、JESTなどを使うと、spyメソッドを使ったらもう動きはモック的になるし、呼び出しした回数も記録できるSpyの役割も兼ねるので、そのあたりのJESTのSpyを使ってくださいみたいな。そういうフレームワーク依存の会話することが多いです。このあたりの「そもそもモックって……」「そもそもSpyって……」などの会話するのは、僕はあまり記憶にないです。加藤諒さんはどうですか?

加藤:モック、Spy、スタブは、一緒に捉えてやっていることがたぶん多いです。和田さんから話があったように、そこはわざわざ分けて考えるほうがつらいので、分けないで考えて。例えば、Fakeとの違いだけはけっこう露骨に変わってくるので、テストを書くタイミングなどで少し話したりはします。

佐藤:なるほど。Spyがモックの機能を持っていたりするから、ややこしそうですね。「切り分けて話せないからな」みたいになって、ちょっと迷走していたので気になりました。

加藤:そうですね(笑)。

新井:すごく気持ちわかります。

加藤:最近Goを書いていて、gomockを使っていますが、普通に入力値のチェックができるので。普通にモックの名前だけど、Spyが入っていたりするので、あまり分けて考えてはいません。

佐藤:アーキテクトみたいな感じで入ったので、「一応こういうものです」みたいな話をしなきゃいけなくなったとき、どうやっているのかちょっと気になった感じです。

加藤:確かに。

新井:すごくいい話題だと思います。

(一同笑)

「単体テスト」「結合テスト」「E2Eテスト」の定義

新井:ちょっと引き続きいきたいと思います。言葉の定義の続きです。単体テスト、結合テスト、E2Eテストとありますが、いったん僕のほうで、今日はこんな感じで定義させてください。単体テストは関数単位で行う、スモールサイズテストと思ってもらえればいいかと思います。基本関数ごと、ファンクションごとのテストのようなイメージです。

インテグレーションテストに関しては、関数やクラスを結合したかたち、複数結合したかたちで、アプリケーション全体をテストするようなイメージ。どれぐらい結合するのかという問題がありますが、いくつか結合した状態でのテストという感じです。Lambdaの入力値に対するテストのようなものを想定しています。

E2Eテストです。クラスメソッドの社内では、けっこうこの言葉が使われていると思っているんですが、実際のサービスと組み合わせた状態のテストです。よくやっているのが、Lambdaを作って、API Gateway、Lambda、DynamoDBのようなリソースをAWS上に上げた状態で、ローカルからや、CI上でテストを投げて入出力を確認するみたいな。これを社内ではE2Eテストと、けっこう呼んだりしています。

佐藤:正直、API GatewayとLambda、DynamoDBといったら楽ですが、IoT Coreとかを使いだすと、どこからどこについてやればいいのか悩むんですよね。

新井:そうですね。キューとかを挟むと。

(一同笑)

IoT Coreが絡んだテスト

和田:僕は佐藤さんに聞きたいんですけど、僕もIoT Coreを触ってシステムを組んだときがあって。「テストどうするんだろう?」とずっと思っていたんですが、実際にIoT Coreなどが絡むと、テストとかってどうやっていますか?

佐藤:前の案件でやっていたときは、IoTルールに対してペイロードを投げて、その他のDynamoDBに保存されるなら、保存されるまで確認するようなE2Eテストをやっていたり。だいたいIoTルールに対するテストぐらいしか書けていなくて、証明書などの部分はあまりやっていませんでした。

和田:そうですよね。あれ、ごめんなさい。証明書を登録するのと、IoTルールを作るのは、分けてできるんでしたっけ?

佐藤:ちょっと曖昧ですが、できたと思います。

和田:そうなんですね。登録するところのテストがすごく大変だった記憶があって。「これを果たしてテストするのか」「いったい、今何をやっているんだろう」となった気がするんです。

佐藤:どうしても混ざってしまうとは思いますが、1回確認できればOKなものは、手動でやったり。

和田:そうですよね。そのあたりを混ぜることに関してはいいと思います。ただ、IoTはエンドポイントがAWSアカウント1個だけなのも、テストをけっこうやりにくくしている1つの要因なのではという気がしていて。そのあたりもけっこう大変ですよね。

佐藤:そうですよね。書くたびに、どうやったらうまく書けるんだろうな、と。結局ちょっと時間を待ったりするところを書いたりするところがあるので、非同期の部分とか、「これうまく書けないのかな」と悩んだりします。

和田:そうですね。

非同期部分の処理

佐藤:ちょっと派生してしまいますが、非同期の部分の処理はどうしていますか? スリープさせるしかないときは、正直スリープさせてしまっているのですが、「これはうまくいった」というものがあったら聞いてみたいです。

和田:加藤諒さん、どうですか?

加藤:今出しているIoTまわりでいくと、MQTTを使うような非同期のものは、私も昔案件でやったときはスリープをかけていた気がします。あとは割り切って「Lambdaで書くには、ハンドラ関数が呼ばれたあとからテストをしよう」みたいな。E2Eより前段階のテストでは、マネージドな部分は試しようがないという感じで、やらない。あとはサービスによると思いますが、AWS SDKの定義がしっかりしているもの。強いようなものであれば、SDKを信じてそのとおりに書く、というように割り切ってやっているところもあります。

佐藤:なるほど。けっこう悩むのが、インテグレーション見てあまり書いてなかったときに、DynamoDBのパラメータが間違っているものがけっこうあって。自分がしょぼいのもありますが(笑)。実際に流してぜんぜん動かないことが何度もあって。何度もデプロイしてリトライ、みたいなことをやってしまっていて。そういうのはありますか? どう対策しているとか、あったりします?

加藤:メチャクチャわかります。DynamoDBなどは、LocalStackでFakeとして立ち上げて叩くことを私はやっています。

新井:僕も基本Fakeを使う感じです。Fakeにサービスがなければ、もう実際の開発用のAWS環境につなぎにいってしまうことをよくやります。

佐藤:E2Eだけを書いていると、集中が途切れちゃうので難しい。3、40個とか、Lambdaがけっこう増えてくるとなかなか時間がかかって難しい。ちゃんとスタックを切れてなかったのかもしれませんが、時間がかかってしまって、難しいなと思っていました。

新井:そのあたりは、はたぶん共通の悩みどころですね。

(一同笑)

(次回につづく)