2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
佐藤智樹氏(以下、佐藤):視聴者の方でも(Lambdaを)大量に使っている方は、「ここを困っていました」とか言ってもらえると共感できそうです。
新井成一氏(以下、新井):願わくば、公式でそういうFakeを出してもらうのが、僕は一番いいんじゃないかと思っています。
佐藤:確かに。LocalStackとかありますが、IoTサービス系とか「IoT」とかだけ書いてあって。これは何が使えるのかな。すみません、なんか言い過ぎた気が……。
(一同笑)
和田祐介氏(以下、和田):これは叩けばもっと出てきそうだ。
佐藤:ちょっと取っておきますか。
新井:ではせっかくなので、質問がきているのでいくつか答えてみますか? 「E2Eテストのあとに全体テストがあるのでしょうか?」。和田さん、まずこれどうですか?
和田:やっています。実際にはAPIだけで完結するシステムもあると思いますが、それ以外の画面はくっついてくる話だと思うので。APIに対するテストは、コードを書いてJESTなどをやっていますが、僕の携わっている案件は、古き良きスプレッドシートにテストケースを書いて、愚直に目視で確認していくようなパターンもけっこう多いです。
画面はいろいろフィードバックがあって、ガチャガチャ動かしたりすることもあります。コード化してどれだけうれしいかを考えたときに、自分の感覚の中の話になりますが、まだ労力のわりには得られるものが追いついていない感触があるので。E2Eテストのあとは画面テストをやっていますが、今はちょっとテストケースを愚直に書いてやっています。
新井:なるほど。画面という観点もあると思いますが、マイクロサービスとして1つサービスとして作ったものの、APIがあって、別のサービスから呼び出されるようなケースもあるのかなと思って。そうなってくると、E2Eのあとのテストはけっこうしんどいのかなと少し思ったりもしました。
和田:そうですね。今のところ、そこは画面のテストで包含している感じです。ファクトやマイクロサービス間のテストの考え方は、一般的にはもちろんありますが、やはり限られた期間、限られた予算の中でどこまでできるかを考えたときに、ちょっと今は画面側に任せてしまっているところも多いです。
新井:なるほど。ありがとうございます。次、「E2Eテストも自動化を行っているのでしょうか?」。これは加藤さんどうですか?
加藤諒氏(以下、加藤):はい、行える範囲でがんばって自動化しています。もうちょっと話を広げると、認証まわりはふだんAuth0などのSaaSを使うことが多いです。クレデンシャルなどを使い、いい感じにIDトークン、アクセストークンを発行できるようにして、実際にそのトークンを使って、認証をかけながらE2Eを自動でやることをがんばっています。
新井:認証部分も含めて、E2Eでなるべく自動化してやっている感じですね。
加藤:そうです。
新井:ありがとうございます。次、「どこまで単体テストするかの基準はあるのでしょうか?」。これはわかりみの深い質問ですね。これは佐藤さんお願いしてもいいですか?
佐藤:めっちゃ嫌なんですけど、この質問(笑)。実際にコードを書くときには、和田さんが書いていたハンドラ層、ユースケース層、インフラ層みたいなものに分けてLambdaのコードを書いて、その層単体ぐらいはテストはします。インテグレーション的なものは、今はちょっと案件で書いていますが、ハンドラ全体をとおしては書かなかったりとに分かれる感じです。
新井:今画面に表示しているレイヤーの層の内部は、ユニットテストの対象にする感じですね。
佐藤:そうですね。層の内部で閉じるようにテストを書くような、モックなどを使ってやることをやっています。それだと結局SDKのテストがうまくできなくて、DynamoDBに送るパラメータが間違ってこけることがけっこうあったなと。
新井:SDKが絡む部分は、本当に悩みどころですね。
佐藤:DynamoDB以外はそんなにないかと思いますが。DynamoDBは自分がパラメータをぜんぜん覚えられなくて、毎回「あれ? こういう感じじゃなかったっけ?」みたいな。書き方を間違えて失敗することがけっこうあったので。
加藤:基本、ユニットテストをがんばって書く派ですが、リポジトリ層のDynamoDBは、ユニットテストを書いても意味がないので、「Fakeでテストするでいいや」と書きません。
佐藤:そうですよね。あまりできていませんでしたが、そのほうが効率が良さそうな。
新井:次ですね。「DynamoDBに流し込むテストデータはどうやってますか?」。これは和田さんどうですか?
和田:ほとんどのテストで愚直にJESTなど、before(:all)やbefore(:each)でテストの事前準備を定義できると思いますが、そこでテストデータを実際に作っています。
僕はいわゆるLocalStackなどはあまり使わず、実際にデプロイした環境でE2Eテストをやってしまいます。もちろん既存のデータをバッティングしないように気をつけて、実際の環境にテストデータを流し込んで、そのデータに対して実際にAPIを叩いてGETできるか、createできるかなどのテストはやります。
新井:なるほど。テストの前後処理でけっこうしっかりテストデータの作成とクリアをちゃんとやれば、いける感じですね。
和田:そうですね。あえて言うことがあるとすれば、CRUDのAPIをよく作ると思いますが、GETのAPIをテストするときに、CREATEのAPIを使わないことは気をつけています。それぞれ独立してテストをできるようにするのはやっています。だから、直接DynamoDBのSDKを呼んで、PutItemでアイテムを作ってからGET APIを呼ぶようなことをやっています。ちょっと回答になっているか微妙ですが、そんな感じです。
新井:なるほど。確かに事前にテストコード内でデータの前後処理のようなものをやるのもありかとは思いますが、シナリオテストのようなかたちでGETを呼んで、みたいなものもあるのかなと聞いていて思いました。
和田:そうですね。そういうのもやる価値はあると思います。
新井:回答になっていることを期待して、これは完了にします。どんどん行きましょう。「FakeのDynamoDBテーブルの定義はどう管理していますか?」。これは加藤さんどうですか?
加藤:今の和田さんの回答とけっこうつながってくると思いますが、私は普通にテスト用のコードの中で、beforeAllみたいなところで、Fakeに対してテーブルを作ってデータを投入してを、開発している言語で書いています。
本来テストはパラレルで動くようにしたほうがいいとは思いますが、いちいちテーブルなどを作ってデータを投入している関係で、Fakeを触るような部分はパラレルでは動かなくなってしまいますが、そこは割り切ってます。たぶんもうちょっとがんばって、テストごとに個別のテーブル生成などをすれば、パラレルでもできなくはないと思います。
新井:これはもしかしたら意図としては、テーブル定義のようなものをテストコード側で管理しているのか、CDKの内部のコードをうまくパースしてテストコードで使うようなことを想定しているのかな、と若干思っているんですが。
加藤:そういう意味で言うと、個別管理しています。
新井:実際に、何かCDKのコード側で管理するようなことってできたそうですか?
加藤:例えば、AWSが出しているNoSQL Workbenchという、DynamoDBの定義などをGUIで作ってJSONに吐き出せるものがあるので、それで定義を作ってJSONで吐き出して、テスト側でもCDK側でも読み込むようなライブラリを作ればできるとは思います。ただ、けっこうGSIまわりはCloudFormationのつらいところで、一度に2つ変更できないなどがあったりするので、スクリプトで自動でやるようなことはたぶんきつくなると思います。
新井:確かに。JSONで管理し出すと、CDKのうまみなどがなくなってしまう気もします。
加藤:あと、たぶん今言った複数デプロイ。結局「あ……」みたいなことになる。
和田:あまりそういうことを考えたくないから、僕はFakeなどはあまり使わないところは正直あります。
(一同笑)
新井:なるほど。回答ありがとうございます。次です。「CI/CDはどのテスト種類を実施していまか?」。これは佐藤さんどうですか?
佐藤:自分はCI/CDはユニットテストだけをやっています。インテグレーションテストも、組んでいるときはやっています。E2Eに関しては、手動でやっています。非同期実行のせいで、どうしても安定しないところがあって。ネットワークの原因などもあるようですが、そういうのがどうしてもあるので。E2Eは自動のみ載せて本当にうまくいくのかはちょっと怪しくて、そのままやっていませんでした。
和田:「非同期だからうまくいかないことがある」というのは、具体的にどういう処理ですか?
佐藤:単純に、API Gatewayを叩いてLambdaを実行して、DynamoDBでデータを取ってくることですが、うまくいかないときがあって。
和田:なるほど。3回チャレンジなどは特に入れていないですか?
佐藤:やっていなかったです。そのときは、1回チャレンジして失敗したらエラーみたいな。
和田:E2E要素がけっこうそうですね。何回までチャレンジできるようにするのは、けっこう便利ですね。
佐藤:その観点はありますね。どうでもいい話ですが、昔、家のネットの回線が昔悪くて、そのせいでE2Eが見たこともないエラーで失敗することもかなりあって。SDKで書き込みに行くのが失敗するような。foreachで書こうとするけど、それで失敗していて、よくわからない。
和田:なるほど。IoTの世界って、潤沢なネットワーク帯域があるとは限らない場合もあるので、そういうケースでのテストもできるという考え方もできますよね(笑)。
佐藤:そうですね(笑)。お客さまにもそういうことを言わましたが、「そもそもテストできないからどうしよう」みたいな。
和田:開発するという観点では、すごくやりにくいと思います。すみません(笑)。ありがとうございます。いったんこれは完了にして、「E2E テスト実施時には、mablなどのツールを使用しているのでしょうか?」。これ知っている方いますか? 知らなくてすみません。みなさんよく知っていますね。
加藤:これはフロントから全部できるやつなのかな。私たちはバックエンドエンジニアなので、APIのテストにけっこう突出していることが多くて。フロントからテストすることもなくはないけれど、さっき和田さんが言ったようにふだんから頻繁にはしないから、スプレッドシートで書いて、手でチャックしていることが多いかと思います。
新井:なるほど。我々はあまり使わない感じですね。
和田:ちょっと手軽に試せるものがあって、加藤諒さんが試していたのがあったと思います。Auth0の認証まわりなどで、けっこう苦労していましたよね。
加藤:ドメインが切り替わったりとかしたら、けっこう大変だった記憶があります。
新井:「Lambdaのユニットテストですが、VSCodeやEclipseでテストをしていますか?」。これは、じゃあ加藤さん。
加藤:私は、プルリク(プルリクエスト)を上げる前に、手元でテストをしています。ただ、あまり強制はしなくてもいいんじゃないかなと思っていて。プルリクがマージされる前に強制的に実行できるようになっていれば、それでいいんじゃないかと思います。ローカルで動かすのが嫌だと思っている人もいると思うので。CI/CD上では、絶対強制的にテストをさせる。普通に手元でも回せるように書いているので、私は一応手元で回します。
佐藤:自分も手元で一応動かせるようにしてCI/CDで組んでおいて、プルリク作ったら実行して、エラーだったら落とすような感じです。
新井:なるほど。では手元で実行しています、ということで完了で次に行きましょう。「DynamoDBやS3のように、可用性の高いサービスを使うとき、そのサービスが落ちたときを想定したテストはやはり書きますか?」。これは順番的には佐藤さんですが、いかがでしょう?
佐藤:正直そこまで意識できているかというと、微妙です。
和田:これは確かにあると思いますが、これが起きたということは、たぶんアプリケーションコードでどうにかできる世界ではないと思います。たぶん、いろいろなステークホルダーを巻き込んで立ち向かわなければならない話になってきそうなので、果たして想定するかどうかは確かにあります。
新井:想定して書いたテストコードに対するメリットみたいなところを、やはり考えてしまいますね。
加藤:そういう意味で言うと、たぶんみんなSDKまわりとかを聞いたときに、エラーハンドリングなどはしっかりと書いていて。想定できるエラー+unknownエラーを吐いた場合のハンドリングまでは書いて、でもそこをエラーを通るテストまでは、私は書いていません。
和田:それを書けるということはもう(笑)。
加藤:結局、そこを書いても正直あまりなので。エラーを拾ってログには残るようにして、適宜改善していけばいいぐらいに捉えています。
和田:そうですよね。想定できてない事態が発生しているのだと思うので、500が返ってきたときは問題で。ログを出して500で返すとしておけば、あとは追調査するのでいい気はします。
新井:確かにそのとおりですね。ユニットテストでは、僕はよくわからない系のエラーは全部拾うように書いていました。ログに出して、クライアントには500系で返すみたいな。ではこれも完了です。
「ユニットテストでは、AWS APIテストを行うという理解で合っていますか?」。
和田:あくまで僕たちの考えでは、という枕詞がつきますが、ユニットテストでは、基本的に通信は行わない方針です。Googleのガイドラインなどでもネットワークを使うか使わないかのガイドがあったと思いますが、ユニットテストでは基本的には外部と通信しない。その代わり、手元などで実行しやすくするのを方針としているはずなので、それにのっとったかたちで、ユニットテストでSDKで通信したりは今はしません。お二人も同じですか?
加藤:同じですね。ついでに、チャットに和田さんが言ったGoogleのテスト指標を貼っておきました。
和田:ありがとうございます。
加藤:ユニットテストはSmallだからという話ですよね。
和田:そうそう。Smallだから。
加藤:私も完全同意です。
新井:ありがとうございます。ではそんな感じで、回答OK。先ほどのサービス、MinIOですね。ごめんなさい、言い間違えました。では最後、「Fakeのテストをやったあとに実際の本番サービスを使ってテストをしますか?」。これは加藤さんどうですか?
加藤:Fakeテストはあくまでインテグレーションテスト。先ほどのものでいうと、Mediumで捉えて、E2Eは別途やります。「例えば、ローカルDynamoDBを使ったテストをやってOKであっても、クラウドの DynamoDBをつかった同じテストをやるのかなどです」。同じテストではないです。あくまでFakeはインテグレーションテストで、その実際のDynamoDBを使うのはE2Eテストと捉えています。
テストコードの内容も違って、インテグレーションテストをやるときは、単純に1つのAPIを通すような感じのテストしか書かないことが私は多くて。対して、E2Eはわりとシナリオを作って、シナリオの中でDynamoDBをユーザーが当然触ることをフォーカスをして書く書き方をしています。
(次回につづく)
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.12
今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05