皆様こんにちは、ハヤシです。 2025年5月30日(金)に開催された、JaSST2025東北に参加してきました。 初めての仙台、JaSST、新幹線などでいろんな経験ができました! それでは基調講演とワークショップで行った活動をもとに参加レポートを作成いたします。 JaSST東北とは JaSST東北とは、NPO法人ASTER (ソフトウェアテスト技術振興協会) が主催する「Japan Symposium on Software Testing (JaSST)」の東北地方での開催を指します。 JaSSTは、ソフトウェアテストに関する最新の情報やノウハウを共有し、ソフトウェア業界全体のテスト技術向上を目指したシンポジウムです。( JaSST公式サイトより ) JaSSTの開催地 JaSST公式サイトより JaSST東北の流れ 以下は今年のJaSST東北の正式名称とテーマ、テーマ概要、プログラム概要です。 正式名称: JaSST’25 Tohoku ソフトウェアテストシンポジウム2025東北 【やってみよう!テスト開発 〜チームで育てるテスト観点〜】 テーマ: 「テスト設計」 テーマ概要: JaSST東北、本年のテーマは「テスト設計」です。 シンポジウム後半には、テスト設計を体験できるワークも用意されています。そこで本セッションでは(主にテストの)「設計技術」について、お話します。 ご参加のみなさまの理解をより深めていただくために、背景となるテスト設計のモチベーションや、技術の世界観全体感をつかむためのテスト設計プロセスの話題も盛込んで、設計の話を展開します。また設計技術を学んでいくためのヒントも提供できればと思います。 JaSST’25 Tohoku公式サイト より プログラム概要: 基調講演→ワークショップ(全体説明)→ワークショップ1→ワークショップ2 ※参加前に心掛けていたこと 僕自身去年の4月に新卒で入社後、今までの案件でテスト設計を一からからやったことはなかったので(1回は以前あった設計を元にアップデートされた内容を追加して修正するだけでした。)将来担当することになるテスト設計のために、「実践で使えるテスト設計インサイト」を確実に自分のものにして帰ろう、という気持ちで参加いたしました。 基調講演「テ。ーテストの設計についてー」 今回の基調講演に登壇された方は近美克行さん(シーイーシー/ディペンダビリティ技術推進協会/ASTERテスト設計コンテスト)でした。セッションが始まる前からテストに関するすごい情熱が伝わってきて本当にプロフェッショナルな方だと感じました。 基調講演では全部話しきれない分量のプレゼンテーション資料でしたが、テスト設計における重要なポイントを中心に講演してくださいました。(テストに関する愛を感じました!) 講演の流れ 講演の流れは以下のような流れでした。 PART1. なぜ、わざわざ(テストの)設計を行うのか? 設計の目的(ゴール)を知る PART2. 設計技術を構成する技術要素や原則を知る そして設計のご利益を知る PART3. 設計技術を磨くアイデアを考える PART1.なぜ、わざわざ(テストの)設計を行うのか?(テスト)設計の目的(ゴール)を知る テスト設計を行う理由を理解するために本講演のPART1ではまず、ソフトウェア開発で設計が行われなかった時にどのような困りが生じるかについて考えることから始めました。 以下は本講演で述べられた設計を行わなかった時の困りごとです。 事前検証機会の喪失(作ってからじゃないと設計の良し悪しが判断できないため) 知識共有機会の喪失(設計レビューの形で有職者の支援が受けられない) コミュニケーション機会の喪失(設計書というドキュメントの形で情報を残さないことにより、未来の自分、他の設計者、実装者、テスト担当、保守担当者に設計知見や意図が伝達できない) たしかに…と考えました。設計をしてドキュメントの形で保存すると上記全てをある程度未然に防ぐことができるかと。なんとなくわかってはいたものの、確実にまとめて説明して頂いてきれいな形で頭の中に整理される感じでした。 では、設計をすることによって得られる利益は以下となります。 事前検証機会確保によるフィードバックループの短縮→速度向上 知識共有機会確保による「既知・確実」情報の共有 コミュニケーション機会確保による合意形成達成・説明責任の達成 困りごとと連携される利益でとてもわかりやすく、設計を行うことによるメリットとデメリットが確実に理解できました。 そこからテスト設計の場合どのようになるかをみると… 事前検証機会の確保 製品出荷以前にテストの有効性を判明し、致命的な有効性不足を判明できる 知識共有機会の確保 最近のソフトウェアは一人で作成、実施、検証するには規模が大きすぎるため、知識共有機会の確保により、多数人でプロジェクトを行える コミュニケーション機会の確保 もし、テストを一人でできたとしても、利害関係者への説明は必要となる このように、テスト設計は絶対的に必要なプロセスだということがわかりました。 PART2.設計技術を構成する技術要素や原則を知る。そして設計のご利益を知る PART2ではテスト開発プロセスを重点に講演が進みました。以下星マークがついてる部分がこの講演で重点的に扱われた部分です。 テスト開発プロセスにおける、 ☆ テストの目的は? テストのINPUTは? テストベース テストのOUTPUTは? テストケース ☆ テストの構成要素(情報要素は?) ☆ 構成要素間の相互作用は? のうち、星マークがついてる部分を講演の内容を元に解説していきます。 1. テストの目的は? 欠陥の修正(QC)への貢献と品質保証(QA)への貢献 欠陥の修正(QC)への貢献 いかに少ないコスト (人的リソース、時間、スキルニーズ、精神力など)で、是正に つながる 欠陥を発見できるか? NGが発生する条件を絞り込めるような十分な情報提供ができるか? 欠陥であることが正しく判断しやすいか? 品質保証(QA)への貢献 開発とテストプロセスがどの程度うまくいっているか? についてのフィードバックに使う すべての利用者、利用状況、ユースケースの組み合わせは現実的に検証不可能であるため、品質保証目的、目標のモチベーション(テスト結果を証拠として、検証したい内容)を定義し、それにあわっせて適切な品質保証戦略(論証戦略=説明ロジック)を構築する 2. テストの構成要素(情報要素は?) テスト要求とテスト条件の集合 テスト目的に関する情報要素:テスト要求 (品質論証の論証ゴールと論証の有効範囲を表現したもの) →テストの目的のパートで解説したもの テストケース実装に関る情報要素: テスト対象とテスト対象の持つI/Fに関連する情報 3. 構成要素間の相互作用は? テストフレームやテストコンテナで表現されるテストケースやテスト条件の依存関係 テスト同士に依存関係がある場合、複数のテストケースをまとめて管理/実行する必要 があります。そのため、テストコンテナやテストフレームといった単位で整理します。 こうした単位でまとめる際に、「どのような目的・利益を得たいか」を明確にすることも、テスト活動において重要なポイントです。 PART3.設計技術を磨くアイデアを考える PART3では、設計技術を磨くポイントとしていくつかをご紹介くださいました。 各ポイントは以下になります。 夢は大きく! 設計を学ぶ際のポイント 続けるのは楽しさ(そして達成感) ひとつずつ述べて自分の感想を加えていきます。 1. 夢は大きく! 目指すは全自動! すごく共感しました。全自動を目指していたら、もし全自動にならなかったとしても、テストの全体的なプロセスのうち大多数が自動化できるのは可能かと考えました。 自然言語や図のコンピューター解析技術も進歩している 最近のAI技術の成長から見て私も近未来では人でしか対応できなかったテストをAIに任せられる日が来るのではないかと考えました。 2. 設計を学ぶポイント 設計の目的を意識する 一番大事かと思います。常に目的を意識してると必要なことに早く気が付き、自ら学ぶのではないかと考えました。 ゼロから考えることは大変なためパターンやベストプラクティスを学ぶ パターンやベストプラクティスを学ぶことによって一番正解に近い設計になると考えました。加えてその数が多ければ多いほど精度はより高くなるのではないかと考えました。 しかし、真似するだけでは成長できないのでそれらはあくまでも一例として、現場、コンテキストに合わせて使う必要があることも伝えてくれました。 3. 続けるのは楽しさ(そして達成感) 仲間を持つ 一人ではできないことも多数では行けるので大切だと考えました。仲間自体がモチベーションになることは自分も経験したことがあり、すごく共感しました。 継続は力 継続することにより、習慣になり、携わっていた絶対的時間が増えることで結果も残り、続けられる力になると考えました。 ワークショップ VSTePとは? VSTeP(Viewpoint-based Software Test Engineering Process)とはテスト技法の一つで簡単に説明すると「テストケースをざっくり考えてから具体化する方法」になります。 いきなり細かいところから考えると大きな抜け漏れが発生しやすいので、一例としてブレインストーミングのような形で出来るだけ多くの観点を出し、UMLっぽい図を用いて(わかりやすくするため)どんどん具体化していく形です。 以下はVSTePの簡単な流れとなります。 テスト要求分析(テスト観点を出す)→テストアーキテクチャ設計(テストコンテナ設計)→テストアーキテクチャ設計(テストフレーム設計)→テスト詳細設計(テストケース作成)→テスト実装 (テストスクリプト作成) 今回のワークショップでは上記の流れのうち「テスト要求分析(テスト観点を出す)」と「テストアーキテクチャ設計(テストコンテナ設計)」の部分を実際やってみました。 各ワークショップで行った活動については下で詳しく説明いたします。 ワークショップ1(テスト観点図作成) ワークショップは4人一組で行うグループ作業でした。(私のチームは3人でした…)各チームごとにファイルボックスがあり、その中に今回行うワークショップの資料が入っていました。(ワークで使用するターゲットユーザの情報、機能設計書等)今回の対象プログラムは「アラームアプリケーション」でした。 運営の方々から「機能設計書はまず詳しく見ずに、アラームアプリケーションで必要だと考える観点をだし、後から機能設計書に合わせて対象外判定など行ってください〜」と言われました。 そこで私達のチームでは「まず各自でできるだけ観点を出して発表し合い、議論して追加すべきと考えられる観点を追加」する方法で行いました。 私は一人で考える時は「アラームアプリケーションで抜けてはいけない」点を中心に観点を作成いたしました。 (作成した観点一例:レイアウト・表示、ボタン挙動、状態遷移、画面遷移、アラーム正常起動、編集機能等) 個人作成の時間が終わり、他のチーム員と作成した観点をすり合わせてみたら…なんと重なる部分と重ならない部分で 5:5 くらいの割合でした。 ある程度自分が考えていなかった観点も出てくることも想定していましたが、自分一人では長く考えても思い浮かばなさそうな観点もあり、集合知性の力を感じました。 その後はお互いの観点とその観点を選んだ理由などを聞き、議論して追加の観点を引き出す作業をおこないました。議論することで、より多くの観点を見つけることができ、自分の視野もどんどん広くなっていくことを感じました。 最後には今まで出した観点を大きな項目で分け、対象外の観点はステッカーで表示し、ツリー構造でまとめることでワークショップ1の作業は終わりました。大きな項目で分ける時は作成した観点を最大限同じカテゴリーの観点とまとめること、大項目の考え方に注意しながら作成しました。 以下は私たちのチームで作成したワークショップ1の成果物です! 作成が終わった後5分ほどで他のチームの成果物を見ることができました。見てから考えたのは「どのチームも同じではないが納得できる、私たちのチームで出なかった観点だけど必要な観点だ」等私たちのチームの改善点、良かった点、悪かった点等をもう一度考えられる良い機会でした。 ワークショップ2(テストコンテナ図作成) ワークショップ2ではワークショップ1で作ったテスト観点図をもとにテストコンテナ図の作成を行いました。 テストコンテナとは? テストコンテナとは、テストタイプやテストサイクル、テストレベルをまとめたもの うまくまとめると全体像を把握しやすくなる JaSST2015東京 より 上記の説明をもとにテストコンテナ図とは、テスト観点を「テストタイプ」「テストサイクル」「テストレベル」などの分類で整理し、図として可視化したものと考えられます。 私たちのチームはワークショップ1で作成した観点をもとにテスト実行手順に沿ってテストコンテナ図を作ることにしました。「どの観点をどのタイミングで実施するか」の判断がとても難しく、議論にも大きな時間がかかりましたが、結果的にはよくまとまってるテストコンテナ図になったのではないかなーと思います。 以下は作成したテストコンテナ図です! ※テストコンテナ図で表現したテストの順序は以下です 「UI、基本機能チェック」→「アラーム作成(基本動作確認)」→「アラーム動作(アラームがなる時の動作)」→「アラーム削除→アラーム動作(アラーム削除後の動作)」→「アラーム編集、詳細設定」→「アラーム動作(詳細設定されたアラームの動作)」→「性能(アプリの性能)」→「異常系」→「アプリ外要因」→「アラーム動作(アプリ外要因によるもの)」 今回もまた他のチームの成果物を拝見できる機会があり、見させていただきました。感想は以下になります。 意外とコンテナが少ないチームもある 私たちのチームは機能的な面を中心に作成したが、非機能のテスト観点を含んでいるチームもあった やっぱりチームによって分類の仕方が大きく異なる。でも全部納得できる。 気づいた点、今後活かせると考えられるポイント 気づいた点 今回のJaSST2025東北を通じて気づいた点は大きく分けて3点あります。 テスト設計が必要な理由の明確化 複数人でテスト設計を行う時の利点、コミュニケーションの重要性 私が属しているチーム以外の成果物から得た気づき まずは1の「テスト設計が必要な理由の明確化」です。いままで漠然と「テスト設計は必要」だと考えていましたが、それがなぜ必要なのか、しなかった時にどのようなことが起きるのかに関して深く考えていませんでした。 しかし、今回その理由とそれにより得られる利点を明確化したことで、今後行うテスト設計の理解を深めることができました。 2の「複数人でテスト設計を行う時の利点、コミュニケーションの重要性」はワークショップでチーム活動を行い、お互いの観点、フィードバックによりどんどん成果物の完成度が上がることを目にしました。 そこで複数人の観点、良いコミュニケーションが合わさったことにより、上がる成果物の完成度は「たし算ではなく掛け算に近い」と感じました。それにより「私の観点を増やす」、「コミュニケーション能力を増やす」ことの重要性にもう一度気づきました。 3の「私が属しているテスト設計チーム以外のチームの成果物をみる利点」は成果物作成後、他のチームの成果物を見ることにより、観点の拡大を感じました。 自分の成果物を見ることが大事なのはもちろんのこと、時には他のチームの成果物を見ることもエンジニアとして成長するために大切な行動であるということにも気づきました。 今後業務で活かせると考えられるポイント 数多くのポイントがありますが、基調講演とワークショップでいくつかを選別して説明します。 基調講演 「テスト設計の方向性、情報の位置付けと関連性」 テスト設計の方向性 設計するテストの目標をしっかり把握し、その目標にたどり着けるテストを設計することでテストの抜け漏れが発生しないようにする 情報の位置付けと関連性 情報同士の位置付けと関連性を考えることにより、テストの網羅性を向上し、設計の一貫性と論理性の向上を得られる。 ワークショップ 「設計時のコミュニケーション、VSTePのやり方」 設計時のコミュニケーション 自分の意見の出し方、他チーム員の意見を受容する姿勢、議論を通じた意見のすり合わせ VSTePのやり方 テスト観点の出し方、出したテスト観点の整理、テストコンテナの設定(どのような形で分けるか) このような点を今後の業務で活かせると考えました。 おわりに 今回JaSST2025東北に参加することにより、参加されえた多数の方たちからたくさんのインサイトを得ることができ、エンジニアとして一歩成長することができたと思います。これを読まれてる皆さんもぜひ機会があれば参加してみると成長につながると思います。 長文を読んでいただき、ありがとうございました。 The post JaSST’25 Tohoku 参加レポート|テ。ーテストの設計についてー first appeared on Sqripts .
前回の連載 では、1人目QAとしてチームを立ち上げていく部分、組織づくりに関する内容についてお伝えしました。 【第1回】QA組織立ち上げの流れと組織の形 以前の連載である1人目QAとしての立ち回りでは、会社や開発組織の1人目QAになった人がどのような活動をするのかや、品質保証を浸透させる際のアプローチなどについて触れました。今回の連載では1人目QAとしてチームを立ち上げていく部分、組織づくりに関して、私が実... 続きを読む Sqripts 筆者はQAエンジニアとして業務をしていますが、特定の開発チームに所属してテスト業務や品質改善を行っている、という動き方が中心ではありません。どちらかといえば、開発チームに対して外から関わり、開発者へのテスト・QA技術の伝達や、効果的に品質向上ができるような支援を行っています。 こうした関わり方について、他社のQAの方から「自分たちもそのような形を目指しているが、うまくいかない」「ヒントがほしい」といった声をいただくことがあります。そのため、自分なりの取り組みについて語ることも意味があるだろう、と思い今回連載のテーマとして選びました。 本連載では、QAチームを立ち上げている間もしくはチームが形になってきたあとで、実際に開発チームに貢献する形の1つとしての「イネイブリングQA」の概念と、メリットや注意点についてお伝えしたのち、開発組織に品質技術を根付かせたその先の姿についても考えてみたいと思います。 「自社でもイネイブリングQAを目指しているものの、開発チームとの連携がうまくいかない」「どのように品質技術を伝達すればいいか具体的な方法がわからない」といった課題を持つQAエンジニアの皆さんへ、本連載が解決の糸口となることを願っています。 イネイブリングQAとはなにか まずはじめに、イネイブリングQAという概念についてご説明します。 イネイブリングQAというのは厳密に定義された用語ではありませんが、私の観測範囲では2023, 4年ごろから用いられているようです。 なぜQAエンジニアがSLO導入をリードしたのか – tebiki_techblog SmartHRのライティング組織の3つの役割|otapo チームメンバー全員で品質を向上させる。タイミーのQA EnablingTeamとは?|Timee 私の考えるイネイブリングQAは、このあとご説明するイネイブリングのスタイルで業務にあたっているQAエンジニアおよび業務そのものを意味しています。 ITエンジニアの界隈で「イネイブリング」という言葉が使われるようになったのは、『チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計』がきっかけでしょう。 ■ チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計 (マシュー・スケルトン 著/マニュエル・パイス 著/原田 騎郎 訳/永瀬 美穂 訳/吉羽 龍太郎 訳/JMAM) この書籍は開発組織のチーム構成を「ストリームアイランドチーム」や「イネイブリングチーム」などの概念で説明していて、イネイブリングチームは以下のように書かれています。 イネイブリングチームは、特定のテクニカル(プロダクト)ドメインのスペシャリストから構成され、能力ギャップを埋めるのを助ける。複数のストリームアラインドチームを横断的に支援し、適切なツール、プラクティス、フレームワークなどアプリケーションスタックのエコシステムに関する調査、オプションの探索、正しい情報に基づく提案を行う。 イネイブリングチームはスペシャリストで構成される小さくて長続きするグループで、ある時点では1チームもしくは少数のチームだけ担当し、チームの能力と認知を向上させることに集中する。 『チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計』が出版されたのが2021年末(※原著は2019年に出版)なので、日本で目にするようになったのはここ数年の間です。 この「特定ドメインのスペシャリストが、開発チームの能力ギャップを埋めるのを助ける」という概念、すなわち開発チームになんらかの技術を伝え身につけてもらうという動き方を私は「イネイブリング」と捉えていて、この概念をQAに当てはめたものを「イネイブリングQA」と読んでいます。 整理すると、イネイブリングQAとは 開発チームに対して自分たちがQA業務を直接担うのではなく 従来であればテストエンジニアやQAエンジニアが行っていた業務の一部やそれを行うためのスキルを 開発者に移譲していく取り組みおよびそれを行うQAエンジニア のことです。たとえば、テスト設計技法やテストプロセスに関するナレッジをまとめて開発者に対してレクチャーを行うなどの活動が該当します。 イネイブリングQAという呼称自体は新しいものの、その概念は以前から存在しており、たとえば1999年出版の『Automated Software Testing』(邦訳:『自動ソフトウェアテスト 導入から、管理・実践まで 効果的な自動テスト環境の構築を目指して』)に登場する「システム方法論およびテスト(SMT)チーム」の活動と共通点が見られます。 SMTチームの活動として チームメンバーは、次から次へとさまざまなプロジェクト開発チームの主任と一緒に作業をして、知識移転、その他の活動を遂行する。 と述べられており、私はイネイブリングQAに近い概念だと捉えています。 このように、イネイブリングQAという呼称自体は『チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計』をきっかけに徐々に出てきている状態ですが、その概念や考え方自体は以前からあるもののようです。 開発組織とQAとの関わり方をイネイブリングQAに転換する動き イネイブリングQAのような形での開発組織への関わり方を目指すのは、どのような理由からなのでしょうか。 ひとつには、採用や体制面の都合があると見ています。 最近はITエンジニア全般的に採用が大変だ、という声を耳にします。QAエンジニアも同様で、募集を出しているけれどもなかなか集まらない、という会社さんもあるようです。システムテストなどテストの実務的な部分を担うエンジニアを、それに足るだけの人数採用するというのは、かなり大変です。そうなると、テスト・QAエンジニアだけではなく、開発者自身がテスト等の業務も行うような業務設計にならざるを得ません。 実態としては、このような会社ではもともと開発者自身でテストなどの品質関連の業務を行っているか、もしくは外部のテスト会社の力を借りている場合が多いようです。とくに前者の場合、内製のQAエンジニア組織を立ち上げることになったとしても、開発者が主体となって品質関連の業務を行っているというメリットは活かしたまま、QAエンジニアを採用してイネイブリングを中心とした活動を行うのは理にかなっていると思われます。 他のパターンとしては、開発組織の中にテスト・QA組織がすでにあるものの、開発効率や品質意識の向上を目指してイネイブリングQAにシフトしていきたい、という場合もあります。 開発チームとテスト・QAチームがある程度別れており、開発プロセスにおいて「後工程での品質担保」が常態化してしまっている場合があります。このような組織では、シフトレフトを目指して開発者を積極的に品質向上に巻き込んでいくため、QAチームの業務をイネイブリング主体に切り替えようという動きが出てきます。 上記のような理由で、QA組織の動き方、とくにテストに関連する部分の動き方を「自分たちがテスト計画から実行・報告までをすべて担う」から「開発者がそれらの活動を行うのを助け、技術移転する」というイネイブリングQAへの転換をする動きが見られています。 今後の連載トピック:イネイブリングQAの課題と考慮すべきこと このあとに続く連載の各回では、以下のトピックについて触れる予定です。 イネイブリングの注意点 イネイブリングに必要なスキル イネイブリングした先の姿 QAは何をイネイブリングされたらいいのか、イネイブリングすることと引き換えに何をするのか 先に挙げた組織課題などに対する解のひとつとしてイネイブリングQAを志向し、実現に向かって動いているQA組織もあるようです。しかし、「QAは手を動かしません」「開発者や他のロールの皆さんを中心に品質を担保します」と宣言するだけでは、おそらくうまくいきません。 「開発者がテストの重要性を理解してくれない」「品質向上に必要なスキル習得に時間を割けない」「QAチームが単なる『口を出すだけの存在』と見なされてしまう」といった問題も発生する可能性があります。 今後の連載においては、そうしたイネイブリングQAを進めていくうえでの注意点や、必要となるスキルについてご説明し、イネイブリングQAを進めた先で我々QAエンジニアはどうなるのかについて考えていきます。 The post 【第1回】イネイブリングQAとは何か?開発組織に品質文化を根付かせる第一歩|QA活動のスキル伝達「イネイブリングQA」 first appeared on Sqripts .
こんにちは!QAエンジニアのK.Kです。 今回はPostmanを使用したAPIのシナリオテストについて解説していきたいと思います。 APIのシナリオテストについて なぜAPIのテストが重要なのか 現代のアプリケーション開発では、APIが重要な役割を果たしています。フロントエンドとバックエンドの連携、外部サービスとの統合、マイクロサービス間の通信など、APIは様々な場面で使用されており、APIの品質が低いと、アプリケーション全体のユーザーエクスペリエンスに大きな影響を与えてしまいます。 「シナリオテスト」が求められる背景 従来のAPIテストでは、個々のエンドポイントの動作確認が中心でした。しかし、これだけでは以下の問題が見過ごされる可能性があります。 エンドポイント間の連携エラー :前のAPIで取得したデータを次のAPIで正しく使用できない 状態管理の問題 :セッション情報や認証状態の維持ができない データ整合性の問題 :複数のAPI操作後のデータ状態が期待と異なる パフォーマンスの劣化 :連続したAPI呼び出しでの応答時間の増加 実際のユーザーの行動を模擬した一連のAPIリクエストを通じて、上記の問題を見つけ出すことが可能となります。例えば、ブログシステムでは以下のような流れをテストします。 ユーザー情報取得 → 認証・権限の正常性確認 投稿一覧取得 → データ取得とページネーションの動作確認 新規投稿作成 → 作成処理とデータベース登録の確認 投稿詳細取得 → 作成したデータの一貫性と関連情報の整合性確認 投稿更新・削除 → データ変更処理と他機能への影響範囲の確認 この一連の流れを通じて、単体テストでは発見できない「エンドポイント間の連携エラー」「状態管理の問題」「データ整合性の問題」を効率的に検出できます。 APIシナリオテストのメリット シナリオに沿ったテストにおいてE2Eテストも存在しますが、APIレベルでのシナリオテストには異なる価値があります。両者は補完的な関係にあり、適切な使い分けが重要です。 E2EテストとAPIシナリオテストの特徴比較 観点 E2Eテスト APIシナリオテスト 検証範囲 UI操作からデータまでの全体フロー API層のビジネスロジックとデータフロー 実行速度 時間がかかる 高速実行が可能 適用タイミング UI完成後 バックエンド開発完了後すぐ 得意分野 ユーザー体験の検証 データ処理・連携の検証 それぞれの適用場面 E2Eテストが適している場面 ユーザーの操作フローの検証 画面遷移や表示内容の確認 ブラウザ固有の動作検証 統合テストの最終確認 APIシナリオテストが適している場面 ビジネスロジックの詳細検証 データ整合性の確認 マイクロサービス間の連携テスト 継続的インテグレーション(CI)での自動テスト 大量データ処理のテスト APIシナリオテストの特有のメリット 早期テスト開始 :UIが完成する前からバックエンドの品質を検証可能 詳細なデータ検証 :レスポンスデータの詳細な検証が容易で、データ構造や値の妥当性を厳密にチェック 高速実行 :ブラウザやUIレンダリングが不要で、テスト実行時間を大幅に短縮 安定した実行環境 :ブラウザバージョンやOS環境に依存せず、安定したテスト実行が可能 並行実行 :軽量なため、大量のテストケースを並行実行してCI/CDパイプラインに組み込みやすい シンプルなデバッグ :リクエスト・レスポンスが明確で、問題の特定と修正が迅速 効果的なテスト戦略 APIシナリオテストとE2Eテストを組み合わせることで、以下のような段階的なテスト戦略が可能になりますす。 開発初期 :APIシナリオテストでビジネスロジックを検証 統合段階 :E2Eテストでユーザー体験を検証 運用段階 :両方を組み合わせた包括的な品質保証 Postmanとは? Postmanの概要 Postmanは、APIの開発やテストを効率的に行うためのプラットフォームです。 なぜPostmanがシナリオテストに向いているのか 1. 直感的な視覚操作 GUIベースでAPIリクエストを簡単に作成・編集 ドラッグ&ドロップでワークフローを構築 テスト結果をリアルタイムで視覚的に確認 2. 高い再利用性 コレクション機能でテストケースを体系的に管理 環境変数を活用した柔軟な設定切り替え JavaScriptを使用した高度なテストスクリプト 3. AI補助機能 Postbotによるテストスクリプトの自動生成 自然言語でのテスト要件入力 4. 豊富な機能 チーム間でのテストケース共有が容易 CI/CDパイプラインとの統合 環境構築手順 必要なもの Postman Postman公式サイト からデスクトップ版をダウンロード または Web版( https://web.postman.co/ )にアクセス テスト対象API 本記事では、JSONPlaceholder( https://jsonplaceholder.typicode.com/ )を使用します これは無料で利用できるRESTAPIのテストサービスです 注意 : JSONPlaceholderはテスト用のAPIサーバーのため、POST/PUT/DELETEリクエストは実際にはデータベースに反映されません。レスポンスは正常に返されますが、データの永続化は行われないことをご了承ください Postmanによるシナリオテストの実践方法 コレクションとフローの概要・比較 Postmanでは、 コレクション機能 と フロー機能 の2つの方法でシナリオテストを実施できます。 特徴 コレクション フロー 操作方法 リスト形式でリクエストを管理 ドラッグ&ドロップの視覚的操作 学習コスト 低い(従来のAPIテスト経験があれば習得容易) 中程度(視覚的だが新しい概念) 複雑な処理 JavaScriptコードで実装 GUIで条件分岐・ループを設定 デバッグ コンソールログで確認 実行フローを視覚的に追跡 適用場面 CI/CDへの組み込み 非技術者との共有 メリット・デメリット コレクション 学習コストが低い 既存のAPIテスト資産を活用可能 CI/CDとの連携が簡単 複雑な条件分岐の実装が煩雑 フロー 複雑なワークフローを視覚的に表現 非技術者でも理解しやすい エラーハンドリングが直感的 新しい機能であるため学習が必要 コレクションを使った手法 コレクション機能は、関連するAPIリクエストをグループ化し、順次実行するPostmanの基本機能です。フォルダ構造でテストを整理し、環境変数を活用してデータを受け渡しながらシナリオテストを実現します。 例:ブログAPIのシナリオテスト 1. コレクションの作成 まず、新しいコレクションを作成します。Postmanの左サイドバーで「Collections」タブを選択し、「Create Collection」ボタンをクリックします。 作業内容解説 : コレクション名に「Blog API Scenario Test」などの分かりやすい名前を設定 フォルダ構造でテストを分類(認証、CRUD操作、エラーハンドリングなど) 2. 環境変数の設定 環境変数を設定することで、異なる環境(開発、テスト、本番)でのテスト実行や、テスト間でのデータ受け渡しが可能になります。 作業内容解説 : 「Environments」タブから新しい環境を作成 baseUrl にAPIのベースURL( https://jsonplaceholder.typicode.com )を設定 postTitle 、 postBody などのテストデータを定義 実行時に動的に設定される変数( userId 、 postId )用の枠を用意 3. 各リクエストの詳細設定 設定画面(01_Get Users) 作業内容解説 リクエスト名を分かりやすく設定(01_Get Users) HTTPメソッドとURLを指定 「Tests」タブでレスポンス検証とデータ抽出を行うJavaScriptコードを記述 01_Get Users このリクエストでは、全ユーザー情報を取得し、最初のユーザーIDを後続のテストで使用するため環境変数に保存します。 GET {{baseUrl}}/users Tests: pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); pm.test("Response has users", function () { const jsonData = pm.response.json(); pm.expect(jsonData.length).to.be.greaterThan(0); // 最初のユーザーIDを環境変数に保存 pm.environment.set("userId", jsonData[0].id); }); 02_Get Posts 全投稿を取得して、APIが正常に動作することを確認します。 GET {{baseUrl}}/posts Tests: pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); pm.test("Response has posts", function () { const jsonData = pm.response.json(); pm.expect(jsonData.length).to.be.greaterThan(0); }); 03_Create Post 新しい投稿を作成し、前のステップで取得したユーザーIDを使用します。 POST {{baseUrl}}/posts Body (JSON): { "title": "{{postTitle}}", "body": "{{postBody}}", "userId": {{userId}} } Tests: pm.test("Status code is 201", function () { pm.response.to.have.status(201); }); pm.test("Post created successfully", function () { const jsonData = pm.response.json(); // 作成された投稿IDを保存 // pm.environment.set("postId", jsonData.id); // テスト用のAPIサーバであるため投稿したIDが使用できないので100を設定 pm.environment.set("postId", 100); }); 04_Get Created Post 作成した投稿が正しく取得できることを確認します。 ※本来は先ほどの手順で追加した投稿を取得すべきだが、JSONPlaceholderではPOSTで追加した投稿はデータベースに登録されないため、登録済みの投稿を取得 GET {{baseUrl}}/posts/{{postId}} Tests: pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); pm.test("Retrieved correct post", function () { const jsonData = pm.response.json(); pm.expect(jsonData.id).to.eql(100); pm.expect(jsonData.title).to.eql("at nam consequatur ea labore ea harum"); }); 05_Update Post 投稿内容を更新し、変更が正しく反映されることを確認します。 PUT {{baseUrl}}/posts/{{postId}} Body (JSON): { "id": {{postId}}, "title": "{{postTitle}} - 更新版", "body": "{{postBody}} 更新されました。", "userId": {{userId}} } Tests: pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); pm.test("Post updated successfully", function () { const jsonData = pm.response.json(); pm.expect(jsonData.title).to.include("更新版"); }); コレクションランナーでの実行 1. コレクションランナーを開く 作成したコレクションの「…」メニューから「フォルダーを実行」を選択します。これにより、コレクション内の全リクエストを順番に自動実行できます。 2. 実行設定 Iterations :テストを何回繰り返すかを設定 Delay :リクエスト間の待機時間を設定(APIサーバーへの負荷軽減) Data File :CSVやJSONファイルからテストデータを読み込み 3. 実行結果の確認 各テストの成功/失敗状況が一覧表示 レスポンス時間の確認でパフォーマンス問題を早期発見 失敗したテストの詳細情報を確認してデバッグ コレクション手法のメリット 一括実行 :複数のAPIを手動で実行する必要がなくテスト効率が向上 再現性 :同じテストを何度でも同じ条件で実行可能 フローを使った手法 概要 フロー機能は、APIリクエスト間の関係性を視覚的に表現し、複雑なワークフローを構築できるPostmanの新機能です。条件分岐やループ処理をGUIで設定でき、プログラミング知識が少ない人でも複雑なシナリオテストを作成できます。 実践例:条件分岐を含むAPIフロー フローの構成 以下のような条件分岐を含むワークフローを作成します。 Start (初期設定) ↓ Get All Users (全ユーザーの情報を取得) ↓ Get All Posts (全投稿を取得) ↓ Loop 全投稿 └─If (一番最初のユーザーの投稿かどうか) ├─YES → Update Post (投稿を更新) └─NO → 次の投稿へ 作成されたフロー図 作業内容解説 フローの作成 :Postmanで「Flows」タブを選択し、新しいフローを作成 Start ブロック :フロー開始時の初期設定を行う API リクエストブロック :既存のコレクションからAPIリクエストをドラッグ&ドロップで追加 Loop ブロック :全投稿をループ処理するための設定 If ブロック :条件分岐の設定 接続線 :各ブロック間のデータフローを視覚的に設定 フロー手法のメリット 視覚的理解 :複雑な条件分岐も図で一目瞭然 リアルタイムデバッグ :実行中にどのブロックが動作しているかをリアルタイムで確認 エラーハンドリング :エラー時の処理フローも視覚的に設計可能 チーム共有 :非技術者でもワークフローの内容を理解しやすい AI機能(Postbot)の活用 Postbotの概要と機能 PostbotはPostmanに組み込まれたAIアシスタントで、以下の機能を提供します。 1. テストスクリプトの自動生成 自然言語での要件入力 適切なJavaScriptテストコードの生成 ベストプラクティスに基づいたコード提案 不足しているテストケースの提案 2. APIドキュメントの自動生成 リクエスト・レスポンスからドキュメント作成 サンプルコードの生成 API仕様書の自動更新 利用例 テストスクリプトの自動生成 Postbotに以下のように指示: ユーザーが1件以上存在することを検証するためのテストと最初のユーザーのIDを変数に保存するためのコードを書いてください。 自動生成される例: pm.test("Ensure at least one user is retrieved", function () { const jsonData = pm.response.json(); pm.expect(jsonData.length).to.be.greaterThan(0); }); // 最初のユーザーIDを環境変数に保存 pm.environment.set("userId", pm.response.json()[0].id); Postbotに以下のように指示: Add basic tests 自動生成される例: // Check if the response status code is 200 pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); // Check if the response body is an array of users pm.test("Response body is an array of users", function () { const jsonData = pm.response.json(); pm.expect(jsonData).to.be.an('array'); pm.expect(jsonData.length).to.be.greaterThan(0); }); // Check if the user ID is saved in the environment variable pm.test("Save the first user's ID in environment variable", function () { const firstUserId = pm.response.json()[0].id; pm.environment.set("userId", firstUserId); }); APIドキュメントの自動生成 ドキュメントが空の状態から自動生成される例: まとめ APIシナリオテストは、単体テストやE2Eテストでは捉えきれない独自の価値を提供します。本記事の実践を通じて、その真の価値を改めて確認することができました。 APIシナリオテストが解決する主要課題 実ユーザー体験の再現 :単発的なAPIテストでは発見できない、一連のAPI呼び出しで発生するデータ整合性や状態管理の問題を早期発見 システム間連携の信頼性 :マイクロサービス環境での複数サービスを横断する処理の信頼性を確保 データ一貫性の検証 :CRUD操作の流れにおけるデータベース状態の一貫性を継続的に検証 性能問題の早期発見 :連続したAPI呼び出しで発生するセッション管理やキャッシュ関連の性能劣化を特定 開発プロセスへの貢献 UIが完成する前からバックエンドの品質を検証できるため、開発ライフサイクル全体での品質保証を効率化できます。また、CI/CDパイプラインに組み込むことで継続的な品質確保が可能となり、アジャイル開発やDevOpsにおいて重要な役割を果たします。 今回の実践を通じて、APIシナリオテストは現代のソフトウェア開発における品質保証の要となる手法であることを再確認できました。適切なツールの選択と活用により、その価値を最大限に引き出すことが重要です。 The post APIテストを強化する!Postmanのシナリオテスト活用法 first appeared on Sqripts .
QAエンジニアとして、日々の業務に取り組む中で、ふと孤独を感じる瞬間はありませんか? もしかしたら、「この問題意識を持っているのは自分だけだろうか」「この改善に取り組もうとしているのは、もしかして私一人なのではないか」と感じてしまうことがあるかもしれません。 そう感じているのはあなただけではないと私は断言できます。 もしあなたが今、孤独を感じているとしても、あなたは一人ではありません。 世の中には、同じように悩み、学び、高め合おうとしている仲間がいます。 本記事では、QAエンジニアとしてのキャリアをより豊かにするための最終話として、仲間を見つけることの意義と、コミュニティやイベントがもたらす価値についてお伝えしたいと思います。 <QAエンジニアのスタートガイド 記事一覧> ※クリックで開きます 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう 【第7回】良い働き方を継続するためのマインドセット 最終回【第8回】あなたは一人ではない、共に走る仲間を見つけよう コミュニティやイベントという存在 もし、あなたの所属する組織の中に、心を開いて話せる仲間がいないと感じるならば、思い切って社外に目を向けてみることをおすすめします。 幸いなことに、QAやソフトウェアエンジニアリングの領域には、様々なイベントやコミュニティが存在します。 これらの場は、新しい知識や技術を学ぶいい機会となります。 そして、同じ志を持つ人々と出会い、繋がり、「私は一人ではない」という確かな実感を得られる、非常に価値のある場所です。 コミュニティで得られる豊かな学び コミュニティに参加することで得られるものは、単なる情報交換だけではありません。 そこには、あなたのQAエンジニアライフをより豊かにしてくれる、大切な要素が詰まっています。 正統的周辺参加 例えば、コミュニティの場に身を置くことは、「正統的周辺参加」と呼ばれることがあります。 これは、積極的に発言したり、中心的な活動に参加したりしなくても、その場の雰囲気や会話、他の参加者の様子から、自然と多くの学びや刺激を得られるという考え方です。 周囲の人たちの議論を聞いたり、他の人がどんな課題に悩んでいるかを知るだけでも、多くの気づきがあるはずです。 そうした経験を重ねることで、徐々にコミュニティの中心的な活動へ関われるようになっていく、それが正統的周辺参加という考え方です。 第三の居場所 また、コミュニティは、家庭でも職場でもない「第三の居場所」となり得ます。 普段の業務から離れて、共通の興味や課題について気兼ねなく話し合える場所があることは、いいリフレッシュの機会になります。 自分と同じ状況にいなくても、同じような課題や技術を通じて、同じような学びを持つ人たちが集まり、お互いにゆるやかに支え合う場として、コミュニティに参加することは自分のキャリアを充実させるために必要な要素の一つだと考えています。 仲間の存在があなたを引き上げる コミュニティで出会う人たちは、あなたの成長を後押ししてくれる存在です。 同じように品質向上やいいソフトウェア開発を目指して努力している人たち、自分にはない知識や経験を持つ人たち、そして何よりも、あなたの取り組みや悩みに共感してくれる人たちと出会うことができます。 仲間の活躍を見て刺激を受けたり、彼らの視点やアプローチから新たなアイデアを得たりすることもあるでしょう。 仲間の存在が、まるで自然な力のように、あなたをより高いレベルへと引き上げてくれることを実感できるはずです。 コミュニティ参加における注意点 コミュニティに参加することは非常に有益ですが、いくつかの注意点もお伝えしておきたいと思います。 内輪ノリと感じてしまう まず、初めて参加するコミュニティでは、最初は少し居心地の悪さや内輪感を感じてしまうかもしれません。 既に仲の良いグループによる「その場のノリ」ができているように見えたり、話についていけないと感じたりすることもあるかと思います。 これは多くの人が経験することです。 そのような場合でも、気後れしたり斜に構えたりせず、まずはその場の雰囲気を観察し、楽しんでみることをおすすめします。 楽しんでいるうちに、自分自身が気になることもなくなる経験を私はしました。 現場を手放さない 次に意識したいのは、コミュニティでの活動を通じて、普段の自分の仕事を充実させることです。 コミュニティの活動自体を楽しむことも大事ですが、そこで得た学びや刺激を、現場で実践することも重要です。 参加していく中で、「自分の現場ではどのように活かせるだろうか」と考えながら参加することは、より楽しむための有意義な視点でもあります。 現場を悲観的に捉えない 最後に、コミュニティで他の組織や個人の話を聞いた際に、自分の所属する現場と比較してしまいがちになる点には、注意が必要です。 これは、「エンジニアのはしか」 ※ と言われることもあります。 ※参考記事: 「エンジニアのはしか」について|意欲ある若手が陥りやすい?それを乗り越えるには? 「社外の人たちはこんなにキラキラしているのに自社はだめだ」と思ったり、「自分の会社の人は意識が低い」と思ってしまうことがあるかもしれません。 こういった感情を持つことは、実は多くのエンジニアが経験しています。 そして、後になって恥ずかしいと思っている人が多いです。 私もそうです。 「隣の芝生は青い」ということわざがあるように、現場と離れている非日常のコミュニティで話すからこそ、実際よりもキラキラしているように見えているのかもしれません。 しかしながら、キラキラしている人の話を聞いてみると、実際には自分とそう変わらない難しい現場で泥臭くもがいた結果であることも少なくありません。 私が大切にしていることは、「現場ときちんと向き合う」ということです。 「社内の他の人」がいるとして、その人がどのような気持ちで働いているのか、どのような考えを持っているのかについて、社外コミュニティの人と接するのと同じように興味を持ち、共感することです。 そういった中で、「自分は現場の中でどう違う思いを持っているのか」「そんな中で自分は現場でどう貢献できるのか」を真剣に考えることが、私はコミュニティを有効活用する手段だと考えています。 仲間を探せる場所 具体的にどのような場所で仲間を見つけられるのでしょうか? まず、テストコミュニティがあります。これはQAやソフトウェアテストに特化したコミュニティで、専門的な知識や現場の課題について深く話し合うことができます。 例えば、 JaSST というソフトウェアテストシンポジウムや WACATE といったソフトウェアテストに関するワークショップがあります。 これらは一見すると敷居が高いように見えますが、むしろ初参加の人を歓迎したいと思っている人たちが運営していることは断言できます。 私も testingOsaka という大阪のテストコミュニティを運営していますので、ご近所の方はぜひ参加してほしいと思っています。 ソフトウェアテストだけでなく、開発コミュニティに参加するのも非常に良い経験になります。 ソフトウェア開発のプロセス全体への理解を深めることは、QAエンジニアとしての視野を広げ、開発チームとの連携を強化するためにも重要です。 「自分はQAだから開発コミュニティは場違いかも…」と思うことがあるかもしれませんが、意外とそんなことはありません。 私の経験では、「テストの専門家」として話すだけで、良い意味で個性を出すことができます(キャラ立ちします)。 そして、そんな開発系コミュニティの中で、ちょっとしたテストに関する話をするだけで、「参加できてよかった」と言ってくれる人がいます。 私はそんな人が1人でもいるだけで、参加する価値はあると思っています。 イベント告知サイトで「QA」や「テスト」といったキーワードや興味のある内容で検索してみると、多くのコミュニティやイベントが見つかるでしょう。 オンラインで開催されているものも多いので、まずは気軽に参加してみてはいかがでしょうか。 おわりに 〜そして現場と向き合う〜 現場にいると、時に困難で、孤独を感じることもあるかもしれません。 しかし、あなたは一人ではありません。同じように悩み、学び、成長しようとしているたくさんの仲間がいます。 コミュニティやイベントは、そうした仲間と出会い、繋がるための素晴らしい機会です。 そこで得られる繋がりや学び、そして何よりも仲間の存在は、あなたのQAエンジニアライフをより豊かにし、困難を乗り越える勇気を与えてくれるでしょう。 そして、コミュニティを通して、自分の現場についても同じように向き合ってみてください。 また違った視点で現場と向き合えたり、もしかしたら気づかなかった仲間に出会えるかもしれません。 社外のコミュニティに参加する良さとは、 社内に対して新しい視点を得られること だと私は考えています。 QAエンジニアとして充実させるために、繰り返し伝えたいのは、現場に目を向けるということです。 学び続け、仲間と共に、より良い製品を顧客に届けるという目的に向かって、それぞれの現場で頑張っていきましょう。 そしていつか、コミュニティで皆さんとお会いできることを楽しみにしています。 【連載】QAエンジニアのスタートガイド 記事一覧 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう 【第7回】良い働き方を継続するためのマインドセット 最終回【第8回】あなたは一人ではない、共に走る仲間を見つけよう The post 【第8回】あなたは一人ではない、共に走る仲間を見つけよう|QAエンジニアのスタートガイド first appeared on Sqripts .
初めまして。金丸です。 この度、私が参加していたSQiP研究会の研究成果として執筆した論文「繰り返しのテストを要する生成AIテストの効率化 – 類似度算出と同義文判定による検証コスト削減の検討 -」が、幸運にも最優秀賞をいただくことができました。本日は、この研究にどのように取り組み、SQiP研究会でどのような経験を得られたのか、私の視点からお話ししたいと思います。 ※SQIP研究会とは? ソフトウェア品質向上と開発プロセス改善をテーマに、日科技連が主催する実践的な学びの場です。参加者は事例共有や討議を通じて、現場で役立つ知識やノウハウを深め、具体的な課題解決を目指します。 なぜSQiP研究会に参加したのか? 私がSQiP研究会に参加した一番の動機は、日々進化する「AI」に関する最新の動向や技術に対する強い渇望感でした。特に、私たちの主要な事業領域である「ソフトウェアテスト」において、AI、とりわけ生成AIの存在感は無視できないものになってきています。しかし、そのテスト手法についてはまだまだ確立されていない部分が多く、体系的で詳細かつ具体的な知識を身につけたいと考えていました。SQiP研究会であれば、様々なバックグラウンドを持つ専門家の方々と集中的に議論できる機会があると考え、参加を決めました。 試行錯誤から生まれた研究テーマ SQiP研究会は、月1回の定例会を中心に活動が進みます。午前中は特別講義として、ソフトウェア品質に関する第一線で活躍されている講師の方々から、大変示唆に富むお話を伺うことができます。午後は分科会に分かれ、それぞれのテーマに沿った知識共有や活発なディスカッションが行われます。 私たちの分科会には、私と同じようにAI、特に生成AIのテストや品質評価に課題意識を持つメンバーが集まりました。最初は漠然とした問題意識の共有から始まりますが、議論を重ねるうちに、それぞれが抱える具体的な課題の共通点が見えてきます。そこで、似通った課題を持つメンバーでチームを組み、検討するテーマを絞り込んでいきました。 私たちのチームが着目したのは、生成AIの「回答の多様性」がテストの大きな負担になっている、という点でした。同じ問い合わせをしても、AIの回答の表現は毎回異なります。もちろん、その意味内容が同じであれば問題ないのですが、テスト担当者はその都度、回答を読んで内容が正しいかを確認する必要があり、これが繰り返しのテストにおいて膨大な工数を生み出していたのです。 研究の核心:類似度評価はテストを効率化できるか? この課題を解決できないか、という問題意識から生まれたのが、本研究テーマである「類似度算出と同義文判定による検証コスト削減」の検討です。つまり、生成AIが生成した文章の意味的な類似度を機械的に評価し、「これは以前に確認済みの回答と同じ意味内容だ」と判定できれば、人間の確認作業を大幅に削減できるのではないか、と考えたのです。 研究では、この「類似度の数値化」の手法として、文章をベクトル化して類似度を測る「埋め込み表現のコサイン類似度」と、生成AI自身に類似度を評価させるという、ある種ユニークな「生成AIによる類似度評価」の2つのアプローチを取り上げ、どちらがより人間の感覚に近い判定ができるかを比較検証しました。 夏には泊まり込みの合宿を行い、長時間にわたり集中的に議論を深めました。この合宿で、研究の方向性が固まり、その後の実験計画が具体的に定まりました。合宿後は、メンバー間で役割分担を行い、手分けして実験データの準備、実験の実行、そして結果の分析を進めました。 実験の結果、特に生成AIを用いた類似度評価が、人間の感覚により近い評価傾向を示すことが明らかになりました。AUC(曲線下面積)という評価指標で比較しても、生成AIによる評価の方が高い値を示し、テスト効率化の手段として一定の有効性があることが示唆されました 。一方で、文章が長くなると類似度が高く判定されやすくなるなど、課題もいくつか見つかりました 。これらの実験結果に基づき、メンバー3名で分析を行い、追加で検討すべき観点なども取捨選択しながら、研究の論旨をまとめていきました。 論文執筆、そして成果報告会へ 12月頃からは、研究成果を論文としてまとめる作業と並行して、成果報告会での発表資料作成を進めました。論文執筆は初めての経験でしたが、メンバーと協力し、お互いのドラフトをレビューしながら推敲を重ねました。 そして迎えた3月の成果報告会。緊張感のある空気の中、研究成果を発表しました。発表会後に「最優秀賞」という素晴らしい評価をいただき、チームメンバーと共に喜びを分かち合いました。 SQiP研究会に参加して得られたもの、そしてそのメリット・デメリット SQiP研究会に参加して得られたものは非常に大きかったです。まず、最新のAI品質評価に関する国内外の知見や、RAG、Ragas、MCPといった関連技術の情報をキャッチアップできたことは、日々の業務にも直結する大きなメリットでした。また、特別講義や分科会での議論を通して、講師陣や他の参加メンバーからいただいた本質的で的確なレビューやフィードバックは、研究の質を高める上で不可欠でした。 SQiP研究会の大きなメリットとして挙げられるのは、「締め切り駆動で研究を進めることができる」点だと感じています。本業がある中で研究活動の時間を確保するのは容易ではありませんが、定例会や論文提出、発表会といった明確なマイルストーンがあることで、モチベーションを維持し、計画的に研究を進めることができました。そして何より、普段の業務では関わることが難しい、社外の様々なバックグラウンドを持つ方々と深く議論できたことは、自身の視野を広げ、新たな視点や着想を得る上でかけがえのない財産となりました。 おわりに 私の所属している会社ではSQiPでの活動も業務の一環として認められており、この論文以外にも、非常に多くの知識を得ることができました。 今後、それらを社内のAIテストのワーキンググループなどにフィードバックし、よりよいAIテスト手法の構築を目指して行きたいと考えております。 参考文献 繰り返しのテストを要する生成AIテストの効率化 – 類似度算出と同義文判定による検証コスト削減の検討 – (本研究論文)(PDF) AIプロダクト品質保証コンソーシアム ガイドライン 謝辞 最後に、本研究を共に推進し、貴重なご意見とご協力を賜りました共同研究者の皆様に心より感謝申し上げます。 リーダーとして本研究を牽引してくださった 中川 桂 様(東京海上日動システムズ株式会社)、共に研究員として議論を重ねた 多田 麻沙子 様(TIS株式会社) には大変お世話になりました。 主査として的確なご指導を賜りました 石川 冬樹 様(国立情報学研究所)、副主査として本研究をサポートしてくださった 徳本 晋 様(富士通株式会社)、アドバイザーの 栗田 太郎 様(ソニー株式会社) に深く感謝申し上げます。 皆様のご協力なくして、本研究の成果は得られませんでした。この場をお借りして、改めて御礼申し上げます。 The post SQiP研究会で生成AIテストの最前線に挑む:不確実性による評価の壁をどう乗り越えるか? first appeared on Sqripts .
はじめまして。クオリティコンサルタントの つとう工房 です。 ソフトウェア開発における「品質」とは、いったい何を意味するのでしょうか。 PMBOKやISO等の国際的な標準に準拠し、チェックリストを整備し、ルール通りにレビューを行う。確かに、それは品質保証にとって欠かせない取り組みの一つです。しかし、「品質」の問題に関して、私が、現場で常に感じているのは、その取り組みだけでは不十分だということです。 真に求められるのは、現場の実態を理解し、プロジェクトごとの特性を見抜き、表層的な課題の奥に潜む本質を見極める力。言い換えるならば、“イメージ力”と呼ばれるものの重要さです。本稿では、気軽な読み物の体裁を保ちながら、私が、直近対応した大規模プロジェクトの事例をもとに、“イメージ力”がなぜ品質向上に不可欠なのかを掘り下げてみたいと思います。 1. 品質の確保を阻んでいたのは開発に向き合う“体質”だった 現在、私が支援中の案件は、3年にわたる大規模システム開発プロジェクトです。私が参画したタイミングでは、開始からすでに2年以上が経過していましたが、進捗管理も、プロダクトの品質管理もまったく機能していない状態でした。 ヒアリングを開始した当初、関係者からは「うまくいっていないのは外部要因のせい」「人手不足がすべての原因だ」といった声がまことしやかに囁かれていました。 しかし、私は、その言葉を鵜呑みにせず、現場で交わされる会話、提出された資料、ミーティングでの空気感から醸し出される、いわゆる“ノイズ”に注目しました。そうして、時間をかけて丁寧に観察していくうちに、次第にプロジェクトの根本的な問題が浮かび上がってきたのです。 問題の本質は、管理スキルの不足にはなく、開発部門に根付いた“組織体質”にありました。 たとえば、明らかに遅延しているのに「全体的には順調です」と報告されるケースが散見されたり、進捗会議では数値を用いた報告がほとんどなく、問題を報告する文化自体が欠如していたり、さらには、開発メンバーの多くが「自分のタスクだけやっていればよい」という姿勢で、チームとしての一体感が感じられない雰囲気が蔓延していました。 エンドユーザーからは、「遅延の原因を具体的に示してほしい」「今後の改善策を提案してほしい」といった要求が繰り返し出されていましたが、開発側からは具体的な説明もなければ、対策の提示もありませんでした。結果として、ユーザーとの信頼関係は大きく損なわれ、プロジェクトの空気は次第に重苦しくなっていくのが、傍からも感じ取れました。 PMBOK、ISO/IEC25010およびISO/IEC9126に基づく改善提案 私は、品質コンサルタントとして、本プロジェクトの中盤からこの案件に参画させていただき、PMBOK、ISO/IEC25010およびISO/IEC9126などに基づく、A4用紙100枚程度の体系的な改善提案書を作成しました。 そして、その提案書の中で、 進捗管理の可視化 リスク管理の仕組みの提案 レビュー手順の見直し などの提案を展開しました。 しかし、その一方で、その作業を進めながら、この提案だけでは足りないと強く感じながら執筆を進めてもいました。 なぜなら、この現場の品質の根本的な問題は、プロジェクトマネージメントのテクニカルな手法不足に起因しているというよりも、「事実を正しく受け止めようとしない・伝えようとしない」という姿勢の欠如、つまり“ ファクト=事実 ”に寄り添うというごくごく常識的で基礎的な姿勢の欠如にあると痛感していたからです。 レトロスペクティブ文書にまとめる これを受け、私は、テクニカルな提案書とはまた別に、振り返り文書として「レトロスペクティブ文書」をまとめることにしました。 「レトロスペクティブ文書」では、まず、この数年にわたってエンドユーザーが声を上げても、不毛地帯に向かって叫んでいるように実行に結びつかなかった、あたかも“暖簾に腕押し”のように繰り返されてきた虚しいやりとりを、ひとつひとつ議事録から拾い上げ、その実態を示しました。そして、問題の根本原因は、開発担当部門の組織体質に関わる問題であり、プロジェクトの状況をありのままに報告し、解決に向けて真摯に取り組む姿勢がなかったことに起因すると結論付けました。 そして、さらにそれを受け、「進捗を正直に報告する」「問題を隠さずに共有する」「曖昧な表現を避ける」といった、組織として根付かせるべき“行動様式”を示し、「良い報告ではなく、正しい報告が信頼を生む」「実態を変えずに見せかけだけ整えても意味がない」といった箴言も書き添えることにしました。これらの提言は、テクニカルな手法以上に、文化的な改革の重要性を訴えるものでした。 2. 「イメージ力」が導く実践的な品質支援 品質エンジニアが、品質改善を検討する上で最も重視しなければいけないのは、プロジェクトに対して杓子定規に「標準規格を適用する」という点にはありません。もちろん、標準に従うことは大変重要ですが、それ以上に必要なのは、「 現場の実態を正しくイメージし、適切な手を打つこと 」です。それを、私は、“イメージ力”と呼びたいです。 “イメージ力”とは、形式に表れない情報を読み取る力です。たとえば、ある週の進捗会議で「ほぼ予定通りです」と報告されたとします。その言葉の裏に、何があるか。関係者の表情や声のトーン、前週の報告との矛盾、未提出の成果物の存在、些細な変化に注意を向けることで、プロジェクト実態の息遣いを汲み取ることができます。 また、開発メンバーとの雑談の中からも、重要なヒントを得ることがあります。あるメンバーが「最近は、毎晩遅くまで残業していて…」と漏らした一言から、タスクの見積もりに無理があることを察知し、工数再計算の提案をしたこともありました。これは、数値データだけでは決して見えてこない問題です。 また、ドキュメントレビューでも、単に「記載ミスがないか」をチェックするだけではなく、「このドキュメントで次工程の作業者が正しく動けるか」という視点を持ちます。文書が整っていても、読み手の視点を想像しなければ、品質は担保できません。実際、過去にレビューで「問題なし」とされた仕様書が、実装段階で多数の不整合を生んだケースもありました。 こうした経験から、私は、「品質とは、書かれていないものを想像する力」によって左右されるものと考えます。品質エンジニアにとっての武器は、標準規格の知識だけではなく、現場と対話し、空気を読み、背景を推察する“イメージ力”なのです。 以下、ここまで詳述してきた“イメージ力”について、簡潔に要約してみます。 現場とつながり、密に対話する姿勢を持つことの必要性 直接、現場に足を運ぶ、ないし定期的な対話やオンラインでのやり取りを通じて、現場の声や温度感をつかむことの重要性。情報の行間や空気を捉えるには、「話す量」と「聴く姿勢」が何より大切であるということ。 些細な変化や違和感を見逃さない観察眼を持つことの必要性 進捗報告やレビュー内容、メンバーの一言一言の裏にある「兆し」に気づくためには、日頃から注意深く観察し、「あれ?」と感じる感度を磨いておく必要があるということ。 ドキュメントや発言の“先”を読み、次工程や他者の立場を想像することの必要性 成果物は、次工程の作業者にどう伝わるか? 実際に手を動かす人の視点を想像することで、形式だけではない「本当に使える品質」を見極めることが可能になるということ。 標準の適用に捕らわれ過ぎず、柔軟に現場に合わせた対応を心掛けることの必要性 いうまでもなく標準は重要ですが、それをどう現場に馴染ませるかが、品質エンジニアの腕の見せ所。常に、現場の実態を起点に考える姿勢が、品質改善の鍵になるということ。 私が、本稿でお伝えしたい“イメージ力”は、上記のような形に要約できるかと思います。 3. 前職のQA統括部門に抱いた違和感 私の前職では「QA統括部」という部門があり、全社の品質保証活動を担っていました。部門としての体制は整っており、各プロジェクトに対して一律の品質ガイドラインを適用するスタイルでした。 しかし、私は、その部門の品質に対するアプローチに対して、長年、強い違和感を抱いていました。なぜなら、その施策の多くが“目的化”しており、本来支援すべき現場の実態と乖離していたからです。 たとえば、ある小規模な改善プロジェクトでは、ステークホルダーが限られており、関係性も非常に安定していたにもかかわらず、「PMBOKに記載されているから」という理由だけで、「ステークホルダー・エンゲージメント・アセスメント・マトリックス」の提出が求められたことがありました。担当PMは、「この作業、誰のためにやるんでしょうか…」とこぼしていたものです。(デヴィッド・グレーバー博士の“ブルシットジョブ —— クソどうでもいい仕事”が産み落とされた瞬間!) また、プロジェクトに重大な品質リスクが発生した際にも、「定期レビューに合格しているから問題はない」と判断され、現場の悲鳴は聞き流されたこともありました。形式的なレビュー手続きが、実態を覆い隠す盾となっていたのです。 私は、QA部門こそが、最も柔軟であるべきだと考えています。プロジェクトごとに状況を見極め、何が本当に必要なのかを見出す。それは、画一的な知識ではなく、経験と洞察と対話から生まれる対応力です。つまり、ここでも“イメージ力”が問われているのです。 QA部門が、ただ規格を押し付ける存在ではなく、「現場のパートナー」として機能するようになれば、品質文化は劇的に変わるはずです。そのためには、制度やチェックリストよりも、現場に寄り添う姿勢が求められます。 まとめ 言うまでもなく、われわれは、品質エンジニアのプロとして、お客様や、そこらのソフトウェア開発ベンダーが足元にも及ばないくらい、ソフトウェア品質に関しての専門的な知見を保有していなくてはいけません。しかし、品質とは、標準規格による単なる文書管理やレビュー手続きの整備ではありません。それに加え、現場に入り込み、プロジェクトの実像を“イメージ”し、必要な対応を的確に提案できることを併せ持つことが不可欠なのです。 品質を支えるのは、標準規格ではなく“人”です。だからこそ、QAエンジニアには、机上の知識だけでなく、現場を観察し、対話し、本質を見抜く力が求められます。私は、これからも“イメージ力”を更なる武器に、プロジェクトの実態に即した品質支援を続けていきたいと思います。 そしていつか、形式に縛られず、現場の声を真に受け止められるQA部門が、業界全体に広がっていくことを願っています。品質の本質は、形式ではなく、“想像と行動”の中にあると考えるからです。 ——しかし、いったんそんな風に結論付けてはみたものの、その理想郷を目指そうとする姿勢自体が、かつて紀元前の昔、世界最高の知性が独り言ちた、 “The more perfect a thing is, the harder it is to acquire.”(物事が完全であればあるほど、それを手に入れるのは困難である。)—— アリストテレス という、現代に至るまで、人間が性懲りもなく繰り返してきた“退屈な”取り組みそのものを、また繰り返し反芻してしまっていることにハタと思い至り、その結論の凡庸さに、我ながらいささかのうんざり感を覚えつつ、この場はいったん以上で筆を擱きたいと思います。 The post 品質はイメージ力で決まる —現場に寄り添うQAエンジニアの視点 first appeared on Sqripts .
こんにちは、セキュリティエンジニアの河村です。 今回はオライリー出版による「ポートスキャナ 自作ではじめるペネトレーションテスト」の書評をお届けします。本書はペネトレーションテストを初めとするセキュリティ業務では必須なツールと言えるポートスキャナについて、基本的な原理から説明してくれる内容です。 ■ ポートスキャナ自作ではじめるペネトレーションテスト―Linux環境で学ぶ攻撃者の思考 (株式会社ステラセキュリティ 小竹 泰一 著/O’REILLY JAPAN) ポートスキャナ自作ではじめるペネトレーションテスト 本書は、ポートスキャンを用いて攻撃者がネットワークを経由してどのように攻撃してくるのかを具体的な手法を交えて学び、攻撃手法を知ることでセキュリティレベルの向上を目指す書籍です。Scapyを用いてポートスキャナを自作し、ポートスキャンの仕組みや動作原理を... 詳細はこちら www.oreilly.co.jp 本の概要 セキュリティエンジニアが通常、業務でツールを用いるときはsocketモジュールやnmapなどの高度なツールを用います。しかしながら、それらのツールは、多くの人にとって高度に自動化されてるが故に中身がブラックボックスな部分があります。また、特殊なパケットの再現を行いたい場合などでは再現が難しいことがあります。 本書ではサイバー攻撃が具体的に行われるプロセスを表したフレームワーク、Unified Kill Chainの解説から始まり、ScapyというPythonライブラリを通してパケットレベルでSynスキャンなどを体験できるプラットフォームを用意してくれています。第三章以降ではNmap、Nessus、Metasploitとペンテスターにとって基本となるツールの用い方を通して、ペンテスターにとって必要不可欠な攻撃の手順を体系的に学べます。 章ごとの概要 以下に、本書の各章で特に注目したい内容をピックアップしてご紹介します。 第一章 攻撃者はいかにしてシステムを攻撃するのか この章では攻撃者がシステムを侵害していく過程を具体的に学ぶことで、各種セキュリティ対策をより効率的に実施する方法を学びます。 攻撃者がシステムを侵害していく過程を学ぶことは、管理しているシステムの弱点を把握し、セキュリティ対策を効果的に実施する上で重要です。 本章では具体的な事例として2019年の7payが不正利用によりサービス停止となった事件 ※1 、2021年、徳島県の病院で発生したランサムウェアによる電子カルテが閲覧不能になった事件 ※2 、2009年から2010年の間にイランの核燃料施設を攻撃したStuxnet ※3 などが紹介されています。この中でもStuxnetの攻撃は特定の組織を狙って周到に準備した上で実行され、標的型攻撃と呼ばれます。 ※1 「7pay」決済サービス、開始早々の大量不正アクセス,5500万円の被害 ※2 徳島・鳴門の病院にサイバー攻撃 電子カルテにアクセスできず ※3 国家間サイバー戦争の幕開け イラン核施設を攻撃したマルウェア「Stuxnet」(2009~10年) 標的型攻撃の中でも特に高度で持続的に行われるものはAPT(Advanced Persistent Threat)攻撃と呼ばれたりもします。 現在進行形で行われているウクライナでの戦争では現実世界の軍事行動と一体化したハイブリッド攻撃が行われています。このことからわかるように、サイバー攻撃を制す者が現実の戦いをも制す時代になっています。 サイバー攻撃の進行をスケーリングした指標として有名なものがMITRE ATT&CK ※4 やUnified Kill Chain ※5 です。本書ではUnified Kill Chainを用いて説明します。このフレームワークを学ぶことでサイバー攻撃の過程をより分析して捉えることが可能になります。 ※4 https://attack.mitre.org/ ※5 https://www.unifiedkillchain.com/ サイバー攻撃における最初の段階である「初期の足場の確保」から解説します。 初期の足場の確保(Initial Foothold) 流れ:偵察⇒武器化⇒配送⇒ソーシャルエンジニアリング⇒攻撃⇒永続化⇒防衛回避⇒コマンド&コントロール 偵察 Reconnaissance 攻撃者は標的組織の情報を収集し、攻撃に活用出来る情報がないか調査します。この活動で用いる手法はOSINT(Open Source INTeligence)と呼ばれます。 この偵察フェーズは受動的偵察と能動的偵察の2種類に分類出来ます。受動的偵察は標的組織の組織にアクセスしないので、検知されるリスクが低いです。対して、DNS問い合わせ、Nmapなどのポートスキャン行為を行う能動的偵察は直接標的組織にアクセスするため、検知リスクがあります。Subdomain Takeover ※6 などの攻撃の実行可能性はこの段階でわかったりします。 ※6 Subdomain Takeoverについて 武器化 Weaponization 偵察によって得た情報をもとに攻撃に必要な環境を準備するフェーズです。標的組織の環境に合わせてマルウェアを作ることもこのフェーズに含まれます。対象組織がセキュリティ対策を適切に行ってる場合、攻撃に工夫が必要となります。 このような際に必要である検知回避技術にはLOTL攻撃(Living Off The Land攻撃)があります。標的の端末にすでにインストールされているソフトウェアを活用して攻撃を行うことで、検知を回避する手法です。GTFOBins ※7 などにはこのような攻撃を行うのに有用なコマンドが記載されています。 ※7 GTFOBins 配送 Delivery 武器化フェーズで作成したマルウェアを標的組織へ届けるフェーズです。攻撃者この手段として、メールやSNS、USBメモリなど様々な手段を用います。特に特徴的な手法として、 水飲み場型攻撃 サプライチェーン攻撃 があげられます。 ソーシャルエンジニアリング Social Engineering 配送したマルウェアを、メールやSNS等での人を通した会話によって、能動的に起動する手法をソーシャルエンジニアリングと呼びます。ときにはマルウェアの起動をスキップして、直接クレデンシャルを狙う場合もあります。「スミッシング」、「スピアフィッシング」などもソーシャルエンジニアリングにあたります。 攻撃 Exploitation 標的組織にマルウェアを能動的に実行させる方法は前述のソーシャルエンジニアリングの他に「攻撃」があります。例えば、標的にRCE(Remote Code Execution)の脆弱性があれば、それを用いてシステム内でマルウェアを実行させられます。 攻撃フェーズ以前からIPアドレスを偽造したり、SOCKS5プロキシ、Torネットワーク、VPNなどを用いて送信元を偽るケースも多いです。 永続化 Persistence 攻撃者は、システムへの持続的なアクセスの獲得を目的としている場合があり、この場合永続化フェーズが必要になります。永続化の手法として代表的なものに以下の三つがあげられます。 アカウントの操作⇒サーバへの公開鍵の追加など ブートまたはログオンの自動開始実行⇒Linuxでのrcコマンド、Windowsでのスタートアップなど スケジュールされたタスク/ジョブ⇒cronなど 防衛回避 Defense Evasion 攻撃者がセキュリティ製品に検知されないようにとる対策のことです。様々な手法がありますが、本書では5章でMetasploitを用いた防衛回避方法を解説します。 コマンド&コントロール Command and Control 「初期の足場の確保」の最後のフェーズとして、マルウェアは攻撃者の用意したC2サーバ ※8 との通信を確立します。 これらのプロセスではドメインフロンティングやDNSトンネリングなどの隠蔽技術が用いられることがあります。 ※8 C2サーバとは 標的ネットワーク内での被害拡大 標的となるネットワークにアクセスした後、目的の資産を獲得する際の活動をUnified Kill Chainでは「ネットワークを介した拡大」(Network Propagation)と名付けています。 ネットワークを介した拡大フェーズは以下のようなプロセスで構成されています。 流れ:ピボッティング⇒探索⇒権限昇格⇒実行⇒クレデンシャルアクセス⇒横展開 ピボッティング Pivoting 攻撃者は必要に応じて侵害した端末を通じて、直接アクセス出来なかった他のネットワークへ通信をトンネリングし、これをピボッティングといいます。横展開と異なり端末間の移動のみをUnified Kill Chainではピボッティングとしてます。 探索 Discovery 攻撃者が現在ログインしているシステムとそのシステムが接続している内部ネットワークに関する情報を得るために行う活動を探索と言います。検知されないようにPowerShell等、OSにデフォルトで備わってるツールが多用されます。 権限昇格 Privilege Escalation 取得出来た権限が制限されたものだった場合、脆弱性を利用してより高いレベルの権限への昇格を試みます。この活動を権限昇格と呼びます。 実行 Execution コードを実行するのに必要な権限を得た攻撃者は攻撃を実行します。 クレデンシャルアクセス 攻撃者は目的に応じて、クレデンシャルを盗み出そうとします。この活動をクレデンシャルアクセスと呼びます。 ⇒ わざわざ侵入行為を働かなくても、GitHubなどで公開されてるリポジトリから機微な情報を取得出来る場合もあります。 横展開 Lateral Movement 侵入した端末から、同一ネットワーク内の他の端末の権限の取得を試みます。 目的の実行 (Action on Objectives) ここまでのプロセスで攻撃者は標的のネットワークへの足場を広げ、多大な被害を拡大できました。このあと、入手できたデータを収集し、持ち出していきます。 流れ:収穫⇒持ち出し⇒影響⇒目的 収穫 Collection 攻撃者は目的に応じて標的からデータを収集します。システム内のデータ以外にSamba、クラウドストレージから収集したり、キーロガー、Webカメラなどを用いる場合もあります。 持ち出し Exfiltration 目的達成のために収集されたデータを持ち出します。検知回避のためにデータを圧縮・暗号化することも多いです。IDS・IPS回避のための工夫も行われます。この際以下の技術が用いられます。 Smash&Grab Low&Slow 影響 Impact 攻撃者が標的のビジネスプロセスや運用プロセスを操作することで、その可用性や完全性を損なわせる活動です。 目的 Objectives 攻撃者の社会的・技術的な最終目標のことです。以下に例をあげます。 知的財産(ソースコードなど)の奪取 奪取したアカウントの販売 ランサムウェアによる身代金の獲得 第二章 Scapyでポートスキャナを自作して動作原理を知ろう ポートスキャナは前章のUnified Kill Chainの中では「初期の足場の確保」の「偵察」にあたる行為です。この章ではポートスキャナを「Scapy ※9 」というライブラリを用いて自作することを通して、パケットの操作方法を学んでいき、実在する脆弱性に対する攻撃も体験します。 ※9 https://scapy.net/ 実際の業務では基本的にポートスキャナはNmapで十分なのですが、ポートスキャナの仕組みを理解するには自作することは非常に有用です。このようなことを学ぶとセキュリティエンジニアにとって必要なPoCのコードの実装を素早くできたりします。 環境構築の細かいことについては本書を読んで欲しいです。また、ここに掲載してるソースコードは本文が冗長にならないよう概要のみなので、そのままでは動作しないものがあることはご了承ください。更に、外部に対してこれらのコードを実行することは法に抵触する可能性があるため、必ず自分の管理下のネットワークで試してください。 ここでは大まかな流れと概要を伝えます。本書の実習環境は、Docker ※10 を用いており、Scapyが使えるコンテナと各種脆弱性を持ってるコンテナが用意されております。 ※10 コンテナの基本 本書はDockerの知識がない方でも環境を十分に扱えるよう基本レベルからDockerの解説が載っているので安心です。また、Dockerの性質上、Windows、Mac、Linuxのどれでも検証環境は動作します。 Scapyに入門する Scapy は、Pythonでネットワークパケットを操作するための強力なライブラリです。パケットの生成、送信、解析、操作などを簡単に実現でき、ネットワークテストやセキュリティ分析に広く利用されています。使用仕方として、Pythonから呼び出す方法と、インタプリタから使用する方法があります。 Pythonコードから使用する方法 from scapy.all import srl, IP, ICMP のような形で必要な関数、クラスをインポートしてします。 インタプリタから使用する方法 scapyを使用できる環境のコマンドラインから以下のコマンドを押下します(Linux、Macの場合)。 $ sudo scapy インタプリタを終了する場合、exitと入力します。 パケットの送受信 ICMPを題材としたパケットの送受信が紹介されています。インタプリタ版の場合、以下のようにしてICMPパケットを作成します。 >>> req = IP(dst="10.8.9.3")/ICMP() >>> req.show() scapyの基本的な使い方は本書を実際に読むか、もしくは下記などを参考にしてください。 ※11 Scapy入門 https://qiita.com/Howtoplay/items/4080752d0d8c7a9ef2aa パケットキャプチャを行う Scapyのsniff関数を用いるとパケットキャプチャが容易に実装できます。以下のようなコードを用います(詳細は本書P.50)。 from scapy.all import sniff def print_packet(packet): packet.show() sniff(filter='icmp', prn=print_packet, count=5) このPythonスクリプトを実行するとICMPパケットを待ち受けます。 TCP SYNスキャンをScapyで行う SYNスキャンは、TCP 3ウェイハンドシェイクの特性を利用します。以下はその流れです。 3ウェイハンドシェイクの流れ SYNパケット送信 スキャナーがターゲットにTCP SYNパケットを送信します。 応答の受信 SYN/ACK : ポートが「オープン」の場合。 RST : ポートが「クローズ」の場合。 応答なし: ポートが「フィルタリング」(ファイアウォールでブロック)されている場合。 接続の中断 スキャナーは応答を受け取ると、接続を完了せずにRSTパケットを送信して接続を終了します。 SYNスキャンは接続を完全に確立しないため、高速で実行でき、ログに残りにくく比較的検出されづらいことが特徴です。 Scapyにおいては syn_packet = IP(dst=dst_p)/TCP(dport=target_port, flags='S') # SYNパケットの作成 response_packet = srl(syn_packet) # パケットを送信する のように記述することで、SYNパケットオブジェクトを作成出来ます。 これでSYNパケットを送信した後にSYN/ACKパケットが返ってくるかを判別するコードを追加すると、ポートが開いてるか判断出来ます。 if(response_packet.haslayer(TCP) and response_packet[TCP].flags == "SA"): print(f"TCP port {target_port} is open") else: print(f"TCP port {target_port} is closed") TCP ConnectスキャンをScapyで行う TCP Connectスキャンでは3ウェイハンドシェイクを最後まで行うので、SYNスキャンのときのコードにTCPの接続を正常に終了するためのFINパケットの送受信のコードも書き加えます。 3ウェイハンドシェイクを完了するにはシーケンス番号や確認応答番号の設定が必要です。Pythonを用いたら容易に実装できます。 パケットの確認 tcpdumpを使います。 $ sudo tcpdump port <port> and host <ip> socketモジュールを使って実装する より高性能なsocketモジュールならばTCP Connectスキャンの3ウェイハンドシェイクをより簡単に実装できます。 s = socket.socket() errno = s.connect_ex((target_ip, target_port)) # これでTCP Connectを試みます s.close() 特殊なパケットやパケット単位の実装はScapyが便利ですが、それ以外の場合はsocketモジュールが便利だったります。 パケットを工作しないと攻撃出来ない脆弱性 以下の脆弱性の学習にはパケット単位でカスタマイズ可能なsocketモジュールのカスタマイズ性の高さがいきてきます。 ARPスプーフィング ARPスプーフィング(ARP Spoofing)は、コンピュータネットワークにおける攻撃手法の一つで、偽のARP(Address Resolution Protocol)メッセージを送信して、通信を傍受したり改ざんしたりする攻撃です。 この攻撃を行う上で、ARP要求を送信し、偽のARP応答を送りつけてキャッシュを改ざんします。偽のARPパケットはScapyでは以下のようにして送信できます。 arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=dest_ip, op='is-at') send(arp_response) scapyモジュールのARPクラスでは以上のように、容易に改ざんされたARPパケットを作れます。 DoSを引き起こすCVE-2020-8617 CVE-2020-8617 は、BIND(Berkeley Internet Name Domain)に関連する重大な脆弱性です。BINDは最も広く使用されているDNSサーバーソフトウェアの一つで、この脆弱性を悪用されると、リモートの攻撃者がサービス拒否(DoS)攻撃を引き起こす可能性があります。 この脆弱性では細工されたTSIGリソースレコードを含むリクエストを用います。発見者はPython上でバイト列を組み立て、Socketモジュールで送信していますが、Scapyを用いるともっとシンプルに記述出来ます。 DNSRRTSIG(rrname="local-ddns", algo_name="hmac-sha256", rclass=255, mac_len=0, ac_data="", time_signed=0, fudge=300, error=16) 以上のコードの断片がペイロードの一部です。 第三章 デファクトスタンダードのポートスキャナNmap Nmap ※11 の基本的な使い方は以下のような様々なソースで確認出来るので省略します。 ※11 https://qiita.com/kenryo/items/1b49bddce44e9412638f Nmapの機能を拡張するNSE NmapにはスクリプトエンジンであるNSE(Nmap Scriting Engine) ※12 上で動くLua製スクリプトが付属してます。これらを使うことで、コマンド一つでブルートフォース攻撃などを行えます。 ※12 NSEの使い方の参考 NSEの使用例:ミドルウェアへのログイン試行を行うスクリプト $ nmap -p 22 --script ssh-brute 127.0.0.1 有名な脆弱性であるHeartbleedやPOODLE、EternalBlueなどをNSEで調査することも出来ます。 $ nmap -p 443 --script ssl-heartbleed example.com 第四章 既知脆弱性を発見できるネットワークスキャナ Nessus Nessus ※13 の基本的な使い方は以下のような様々なソースから確認出来るので省略します。 ※13 https://qiita.com/mefuku/items/d22a2747bcdb6ff19d75 ネットワークスキャナには他のものもたくさんあります。例として、CloudflareによるFlan Scan、GoogleによるTsunamiなどがあります。 Nmapとの使い分け NessusのBasic Network ScanやAdvanced Scanでは脆弱性をスキャンする前段階でポートスキャンを行います。ただし、出力結果がNmapとは異なったていたりするので、使い分けとして、網羅性を重視するセキュリティベンダの場合、NessusとNmapを併用して両方の差分を確認する場合したりします。 第五章 攻撃コードを簡単に生成できるMetasploit Framework MetasploitはRapid7社が開発してるペネトレーションテストツールです。無料版はCUIでしか基本的に使えませんが、有料版のMetasploit ProはGUIで操作できます。 Metasploitの基本的な使い方は以下のような様々なソースから確認出来るので省略します。 ※14 https://zenn.dev/sanflat/articles/6c9b007c787035 第六章 攻撃者はどのように被害を拡大するか Unified Kill ChainにおけるPost-Exploitationで行う行動をここでは解説しています。 ファイル読み込みを成功させたあと 標的端末のファイル読み込みが出来ただけでは、RCEが出来た場合と比べて出来ることが限られています。そこでまず、端末内の多数の重要なファイルを「収集」します。「収集」ファイルを元に、次のステップであるファイル書き込みに向けての権限昇格を目指します。 ファイル書き込みを成功させたあと RCEへの発展や、マルウェアの書き込みを目指します。Unified Kill Chainでは「初期の足場の確保」の「永続化」にあたります。 以下が具体的に行うことの例です: ・Webシェルの配置 ・SSH公開鍵の配置 ・cronを用いた永続化と権限昇格 RCEを成功させたあと RCEを成功させたということは、任意のコマンドが実行可能です。このフェーズで行いたいことを列挙します。 コンテナエスケープ ⇒既知脆弱性の利用、Dockerソケットがマウントされてる場合、特権コンテナ マルウェアの実行 ⇒Vimプラグインによるキーロガー ⇒LD_PRELOADによる関数フック C2フレームワークによる侵害した端末の管理 C2フレームワークは侵害した端末を遠隔操作するためのツールです。目的達成には侵略した端末をまとめて操ることが必要だったりするので、攻撃において有用な場合が多いです。 OSSのC2フレームワーク: ⇒Covenant、C3、Empire、PoshC2、Sliverなど 商用のC2フレームワーク: ⇒Brute Ratel C4、Cobalt Strikeなど DBにアクセス出来たら DBには重要な情報が格納されてることが多いため、DBにアクセスできる事は目的達成において重要です。 DB内の情報の閲覧 ファイル読み込み ファイル書き込み RCEを行う ⇒ PostgreSQLのCOPYコマンドなど どのようにして他の端末へ被害を拡大させるか ここまでのフェーズで目的を達成できなかった場合、組織が管理しているネットワーク上の他の端末への攻撃を試みます。その方法の例をあげます。 メモリからのクレデンシャルの抽出 既存のセッションの活用 ⇒ ControlMasterによって既存のSSH接続を活用するなど ⇒ 二回目以降のSSH接続ではPWの入力が不要な場合がある 認証情報が弱いサーバや既知脆弱性が存在する端末への攻撃 ⇒後者はスキャナで発見できることがある 本書を読んで 第一章で学ぶUnified Kill Chainはペネトレーションテストのフレームワークとしてはかなり詳細な部類です。これの各フェーズを日本語で丁寧に解説してる文書はインターネット上には少なく、なので本書の解説は貴重で有用だと思いました。ペンテスター向けのフレームワークですが、セキュリティエンジニアは皆サイバー攻撃と何らかの形で関わり、このフレームワークを知ることでサイバー攻撃についての理解が非常に深まると思います。 第二章でのScapyを用いた自作のポートスキャナの章は本書の目玉といえると思います。本書を読む人で3ウェイハンドシェイクを知らないって方はあまりいないと思いますが、実際にパケット単位で操作できる実行環境を作った人は少ないと思います。Socketモジュール等の一般的なモジュールでは、Synスキャンのような基本的なハッキング技術でさえ再現が意外とめんどくさく、比較的低レイヤーの操作が可能なツールScapyの有用性を感じました。私自身も今後より高度なレベルのScapyの使用法を学び、仕事でのPoC作りなどに活かしたいと思いました。 第三章から第五章の内容は非常にメジャーなツールの入門的な使い方なので今回はほとんど省略しましたが、ペンテスト系の学習をしたことがないセキュリティエンジニアにとっては網羅的に学ぶ上でいい教材だと思いました。これらを学習すればハッキングの登竜門であるHack The Boxなどにも挑みやすくなると思います。 第六章は、第二章から第五章までのツールを用いて標的端末へアクセス出来たあとの手順が第一章に登場したUnified Kill Chainフレームワークに基づいて記載されており、非常にためになります。Hack The Box等では端末のルートを取れたら終わりだったりしますが、現実のハッキングでは違います。機密情報の取得だったり、DoSの達成と言った目標達成にはルートの取得後の端末間の垂直・平行移動や情報収集が必要だったりします。 本書は取り扱ってる内容はペンテスト全域に渡っており、ボリュームはかなりありますが、要求レベル的にはLinux(できればPythonも)の基本がわかってれば十分に読める内容だとも思いました。ポートスキャナの原理に限らず、ペンテスターが用いるツールについて学びたい人は是非一読をお勧めいたします。 The post 『ポートスキャナ自作ではじめるペネトレーションテスト』書評 first appeared on Sqripts .
帰納的な推論 と 発見的な推論(アブダクション) は、 私たちがソフトウェア開発の現場/実務で(知らず知らずにでも)駆使している思考の形です(それどころか日々の暮らしでも使っています)。 それほど“自然な”思考の形ですが、どんな考え方で、どんなところに注意すると質の高い思考ができるのか、基本知識を押さえておくと実務のレベルアップにつながります。 <実務三年目からの発見力と仮説力 記事一覧> ※クリックで開きます 【第1回】見つけるための論理【連載初回、全文公開中】 【第2回】 “共通項”を見つけ出す 【第3回】発見はよい観察とよい方法から 【第4回】帰納の仲間と落とし穴 -前編- 【第5回】帰納の仲間と落とし穴 -後編- 【第6回】 なぜ・どのようにを説明したい 【第7回】 仮説の糸を手繰り寄せる 今回は仮説を考える時の進め方の解説です。 仮説は拙速を貴ぶ――とは限らない コニャンくんがソフトウェアXで起こる故障F( 第3回 など参照)の原因について考えを巡らせています(図7-1)。 図7-1 よい仮説を求めて アブダクションは杖ひと振りでよい仮説を手にする魔法ではありませんし、そもそもよい仮説がすぐに見つかることは稀です。 アブダクションの進め方・パースの「ふたつの段階」 ホップ、ステップ、よい仮説 パース( 第6回参照 )は、仮説はふたつの段階を経て形成されるとしています。 (参考: 『アブダクション 仮説と発見の論理』 。以降『アブダクション』) 第1段階:心に思い浮かぶ仮説を列挙する 第2段階:最も正しいと思われる仮説を選ぶ 図7-2 アブダクションのふたつの段階 第1段階 では、対象について考えを巡らせ、判っていることや調べたことをもとに、説明仮説を考えていきます。 この段階で素晴らしい仮説を思いつくかも知れません。 しかしそこで決めてしまうのでなく、事象を説明できる仮説は他にも考えられないか、検討します。 (思いつきがイマイチならなおさらです) 時にはいわゆる閃きや天啓といったものの助けもありますが、それが降りてくるよう、対象を詳しく調べたり理解を深めたりしながら考えることが大切です。 『アブダクション』では 洞察的な段階 とも言っています。 第2段階 では、第1段階で挙がった仮説を、後述の4つの基準で総合的に評価し、最も理にかなっていると思われるものを選定します。 『アブダクション』では 熟考的な段階 とも言っています。 「最も正しいと思われる仮説」の選定基準/条件 「最も正しいと思われる仮説」の選定の基準ないし条件として、パースは次の4つを挙げています。 (参考: 『アブダクション』 ) (1) もっともらしさ(plausibility) 問題となっている事象や因果関係について、理にかなった説明を与えるものであること。 (2) 検証可能性(verifiability) 仮説は事実に照らして検証可能(真偽を判断できる)であること。 反証可能であること(偽であると判定できること)も含みます。 (3) 単純性(simplicity) (1), (2)が同程度の仮説が複数ある場合は、より単純な仮説であること。 (4) 経済性(economy) 仮説の検証にかかる思考の努力や、時間やコストが少なくて済むこと。 総合的に見て「最も理にかなっている」と思えるものを選定します。 これらの基準は、第6回で挙げた 「よい仮説」が持つ性質 に対応します。 (「検証」の意味も第6回に準じます) 図7-3 「よい仮説」の判定基準と、「よい仮説」が持つべき性質 なお、パースのいう 単純性 は、論理的な単純さ(原因から結果まで一本道/短い、過程が入り組んでいない、etc.)よりは「説明が自然で考えやすい」「受け容れやすい」といった“自然さ”を意味しています。 また、 経済性 は第6回で挙げた仮説の性質の4番目とは若干異なりますが、「少数の仮定から整合的に説明できる」ならパースのいう経済性の条件にかなうと言えるでしょう。 念のため 「最も理にかなった仮説」が選ばれたとしても、 それはまだ仮説 です。 仮説が事実に対して正しい(不整合がなく、過程や結果をよく説明している)かどうかは、その後の検証(ソフトウェアの場合、最終的には動的テストなど)に委ねられます。 「ふたつの段階」の取り組み方 二重ループでイテレーティブに 筆者の経験を交えると、次のように考えると取組みやすいでしょう。 第1段階で「仮説を列挙する」際には: 考えやすいところから手をつける。 「説明仮説にはならない」ものを早めに排除して考える範囲を絞るのも大事。 思いついた段階でざっと検証してみる。 現象や結果を説明できるか、ざっと確かめる( 粗い検証 )。 よさそうなら残す。 そうでなければ脇に置いておく。 (忘れ去る必要はなくて、後で修正を施されて“敗者復活”してもよい) これを繰り返す(いわば「 内側のループ 、 小ループ 」)。 最初の仮説で終わらず、「粗い検証」で得たフィードバックも加味して次の仮説を考える。 ある程度考えられた(もう思いつかない)と判断できたら終了する。 第2段階で「最も正しいと思われる仮説を選ぶ」際には: 「1回目の第2段階」で「最も正しいと思われる仮説」が決まらなくてもよい。 (詳しく考えてみると、細部に説明できないことがある場合や、必ずそうなるとは言えない場合もある) そういう場合はもう一度「第1段階」からやる(いわば「 外側のループ 、 大ループ 」)。 図7-4 アブダクションのふたつの段階・変形版 第1段階で心がけたいこと ①原因候補と説明仮説をさまざまな視点・見方から考えてみる。 原因候補が結果(故障や不具合)を引き起こす筋道を、多角的に考えましょう。 図7-1のように、途中で道が塞がっていても、別の道が見つかるかも知れません。 人的要因やプロセス要因の可能性を含めて考えるのがよい場合もあります(作業や確認の漏れ、単純ミス、勘違い、etc.)。 原因候補から結果までの筋道(可能性としての)が一本か、複数あり得るか考えられると、仮説の確からしさを強化できるでしょう。 原因候補を絞り込みたい場合には、差異法や剰余法の考え方が参考になります( 第3回参照 )。 ②大きな“瑕”がある仮説は躊躇なくいったん脇によけておく。 魅力ある原因候補でも、結果に至る筋道を説明しきれない、仮説の通りにならない場合がある、 といった目につく“瑕”があるなら、いったん脇に追いやって別の仮説を考えてみるのがよいです。 いわば「幅優先の探索」です。 原因の候補がいくつも考えられる状況なら、候補から外してよいものと、残しておくものを仕分けるためにも「幅優先」で考えた方がよいでしょう。 幅優先に対して「深さ優先の探索」をしたくなる場合もあります。 “瑕”がなければ最有力になるような原因候補なら、“瑕”をなくせないか時間をかけて考えてみるのもありでしょう。 「粗い検証」 は、①②を柔軟に行なうことを促します。 第1段階の「粗い検証」 机上(ひとり脳内ウォークスルーで可)でよいので、「仮説Hが正しいならば、Cという結果になる」かどうか、先の4つの選定基準/条件をざっと評価します。 大雑把なウォークスルーでも もっともらしさ や 検証可能性 を損ねるような大きな“瑕”が見つかるなら、綿密に検証してみるまでもありません。 また、第1段階で仮説による説明の 単純さ 、 判りやすさ がある程度把握できていれば、第2段階が捗ります。 アイデアを見失わないように ただでさえアイデアは思いついたそばから消えていってしまうものですから、「原因から結果に至る見えない道筋を、結果から遡って考える」作業を頭の中だけで完結させるのは困難です。 思い浮かんだ考えや仮説案は忘れずに書き留めましょう。 考える過程を書き留めること自体が重要ですし、形に表すことで考えがはっきりすることもあります。 (“見込みあり”と光明が差すこともあれば、足りていないところ・弱いところが判明することも) ということで、次回は「アブダクションを支援するのに使える“ツール”」をいくつか紹介する予定です(特定のプロダクトではありません)。 参考文献 米盛裕二 『アブダクション 仮説と発見の論理』 勁草書房 2007 パース(著), 伊藤邦武(訳) 『連続性の哲学』 岩波書店 2001 近藤洋逸, 好並英司 『論理学入門』 岩波書店 1979 図版に使用した画像の出典 Loose Drawing 人物画、電球の絵をお借りしています。 品質探偵コニャン:Produced by Sqripts . No Unauthorized Reproduction. 【連載】ソフトウェアエンジニアのための論理スキル[実務三年目からの発見力と仮説力] 記事一覧 【第1回】見つけるための論理 【連載初回、全文公開中】 【第2回】 “共通項”を見つけ出す 【第3回】発見はよい観察とよい方法から 【第4回】帰納の仲間と落とし穴 -前編- 【第5回】帰納の仲間と落とし穴 -後編- 【第6回】 なぜ・どのようにを説明したい 【第7回】 仮説の糸を手繰り寄せる The post 【第7回】 仮説の糸を手繰り寄せる|実務三年目からの発見力と仮説力 first appeared on Sqripts .
こんにちは!フロントエンドエンジニアのつかじです。 皆さんは日々の開発の中でテスト自動化に取り組んでいますか?手動での繰り返しテストは時間がかかり、ヒューマンエラーも発生しがちです。そこで今回は、JavaScriptベースのE2Eテストフレームワーク「CodeceptJS」をご紹介します。シンプルな記述でありながら、強力な自動テストを実現できるツールです。 CodeceptJSとは? CodeceptJS は、エンドツーエンド(E2E)テストをシンプルに記述できるテストフレームワークです。 主な特徴は以下の通りです。 直感的なDSL記述 自然言語に近いDSL(ドメイン固有言語)を採用しており、テストコードが読みやすく、出力結果も直感的に理解しやすいです このシンプルな記述方法は、BDD(振る舞い駆動開発)の文脈で、テストの意図を明確に伝え、保守性の向上にも寄与します 複数のヘルパーへの対応 Puppeteer、Playwright、WebDriver、TestCafe など、さまざまなブラウザ操作ライブラリをヘルパーとしてサポート ヘルパーを切り替えるだけで、同一のテストコードを異なるバックエンドで実行可能なため、プロジェクトの要件に合わせた柔軟な運用が実現できます 複数ブラウザでのテスト実行 Chromium、Firefox、WebKit など、複数のブラウザ上でテストを実行でき、クロスブラウザテストが容易に行えます エコシステムの充実 豊富なプラグイン群(スクリーンショット自動取得、レポート生成、リトライ機能、データ駆動テストなど)により、様々なニーズに対応可能 カスタムヘルパーやプラグインを自作することも容易で、コミュニティによるサポートも充実しています APIテストへの対応 HTTPリクエストの送信やレスポンスの検証を行うためのAPIヘルパーが用意されており、Webアプリケーションだけでなく、APIテストもシンプルに記述できます モバイルテスト(Appium利用)への対応 Appiumを利用することで、CodeceptJSからモバイルアプリケーションのテストも可能です 同一のDSLで、WebだけでなくモバイルのUIテストも統一的に記述できるため、テスト環境の統合が容易です 他ツールとの比較 Cypress 高速で自動ウェイト機能が強力ですが、対応ブラウザが限定的です。一方、CodeceptJSは複数のドライバーに対応しており、柔軟なテスト環境を提供します。 Selenium ほぼ全てのブラウザに対応する実績がありますが、APIが冗長でテストコードが複雑になりがちです。CodeceptJSは抽象化レイヤーを提供することで、シンプルな記述を可能にします。 Robot Framework 非エンジニアでも扱いやすいキーワード駆動型ですが、JavaScript環境との統合が難しいという点があります。 Playwright/Puppeteer 低レベルのAPIで柔軟な自動化が可能ですが、テスト全体を構築する際に記述量が増えがちです。CodeceptJSはこれらをヘルパーとして統合し、BDDスタイルの簡潔な記述を実現します。 WebdriverIO 柔軟性が高く、多くのプラグインや拡張機能が利用可能ですが、設定が複雑になりがちです。また、BDDスタイルの記述を行うには追加のプラグイン導入が必要な場合があります。 TestCafe インストールや設定が非常にシンプルで、Seleniumを必要としません。自動待機機能が組み込まれており、非同期処理が扱いやすいですが、細かいカスタマイズや多様なブラウザサポートには制限がある場合があります。 Gauge + Taiko Gaugeはシナリオ記述に重点を置いたフレームワークで、Taikoはシンプルな構文でブラウザ操作を実現します。非常にシンプルな記述が可能ですが、CodeceptJSのような豊富なプラグインや柔軟なヘルパーの選択肢は少ないです。 Nightwatch.js Selenium/WebDriverを利用した標準的なE2Eテストフレームワークとして実績がありますが、設定が煩雑になりがちで、BDDスタイルの記述を実現するには追加の工夫が必要です。一方、CodeceptJSは複数のヘルパーをサポートし、シンプルなAPIで記述できる点で差別化できます。 各ツールともに独自の強みがあるが、CodeceptJSはDSLの記述のシンプルさ、多様なヘルパー対応、豊富なプラグインエコシステム、さらにはAPIテストやモバイルテストまでカバーできる点で、非常にバランスの取れたテスト自動化フレームワークと言えます。 CodeceptJSのインストールとセットアップ 必要な環境 Node.js(バージョン12以上) ※ 執筆時(2025/04/03)時点での CodeceptJS 最新バージョン:3.7.3 インストール CodeceptJSは、インストーラーを使用する方法が最も簡単で推奨されています。以下の手順で簡単にセットアップできます: # 新しいディレクトリを作成してインストール mkdir codeceptjs-demo cd codeceptjs-demo npx create-codeceptjs . 特定のディレクトリにインストールする場合は、以下のようにディレクトリ名を指定できます: npx create-codeceptjs e2e-tests デフォルトではPlaywrightがインストールされますが、他のテストエンジンを使用したい場合は、以下のようにオプションを指定できます: # Puppeteerを使用する場合 npx create-codeceptjs . --puppeteer # WebDriverIOを使用する場合 npx create-codeceptjs . --webdriverio その他のインストール方法や詳細な設定については、 公式マニュアル をご参照ください。 セットアップ インストール完了後、以下のコマンドでCodeceptJSのセットアップを行います: npx codeceptjs init 対話形式で以下の設定を行います(本記事のセットアップ内容。テスト対象の機能名以外はデフォルト値です。): # TypeScriptを使用するか? ? Do you plan to write tests in TypeScript? -> No # テストファイルの配置場所 ? Where are your tests located? -> ./*_test.js # 使用するヘルパー(テストエンジン)の選択 ? What helpers do you want to use? -> Playwright # テスト実行時の出力ディレクトリ(スクリーンショットやレポートの保存先) ? Where should logs, screenshots, and reports to be stored? -> ./output # テストの言語設定 ? Do you want to enable localization for tests? <http://bit.ly/3GNUBbh> -> English (no localization) # Playwrightの設定:使用するブラウザの選択 ? [Playwright] Browser in which testing will be performed. Possible options: chromium, firefox, webkit or electron -> chromium # テスト対象のベースURL ? [Playwright] Base url of site to be tested -> <http://localhost> # ブラウザウィンドウを表示するかどうか ? [Playwright] Show browser window -> Yes # テスト対象の機能名(今回は予約機能をテスト) ? Feature which is being tested (ex: account, login, etc) -> reservation # 作成するテストファイルの名前 ? Filename of a test -> reservation_test.js 基本的なテストの作成|CodeceptJS ここでは、日本Seleniumユーザーコミュニティが提供しているデモサイト「予約情報入力」にアクセスして簡単な操作をテストします。 今回は以下のケースを記述します。 トップページを開く 入力フォームに日付、宿泊人数、名前などを入力 「利用規約に同意して次へ」をクリック後、予約内容を確認 「確定」をクリック後、予約完了を確認 ※ デモサイトは現時点で利用可能ですが、将来的にURLが変更される可能性があります。 テストファイル作成 reservation_test.js へ以下のようなテストコードを作成します。 Feature('reservation'); Scenario('宿泊予約ができることを確認する', ({ I }) => { // 1. トップページへ遷移 I.amOnPage('<http://example.selenium.jp/reserveApp_Renewal/>'); // 2. 入力フォームに日付, 宿泊人数, 名前などを入力 // 日付を選択(例: 2025/05/01) ※ 翌日以降3ヶ月以内の日付を指定 I.fillField('#datePick', '2025/05/01'); // 宿泊日を入力(例: 3日) I.selectOption('#reserve_term', '3'); // 人数を入力(例: 2人) I.selectOption('#headcount', '2'); // 名前を入力(例: 山田太郎) I.fillField('#guestname', '山田太郎'); // 3. 「利用規約に同意して次へ」をクリック I.click('利用規約に同意して次へ'); I.see('予約内容'); I.see('2025年5月1日'); I.see('3泊'); I.see('2名'); I.see('山田太郎'); // 4. 「確定」をクリック I.click('確定'); I.see('予約を完了しました'); I.see('ご来館、心よりお待ちしております。'); }); ポイント: CodeceptJSでは、Scenarioの第2引数に{ I }を受け取ることでブラウザ操作APIを利用できます .amOnPage() でページを開き、.fillField() や .checkOption() などでフォーム操作を行います I.see() によってページ上に特定の文字列が存在するかをテストできます I.see() のシンプルな記述方法は、ユーザー視点でページに表示されるテキストの存在をシンプルに確認できるため、テストコードの保守性と可読性を向上させ、BDDの振る舞い記述と非常に相性が良いです。テストの目的に応じて、単にテキストの存在を確認するだけの場合は I.see() を使用し、特定のエリアや要素内でのテキストの存在確認など、より厳密な検証が必要な場合にはセレクタなどを追加するのが望ましいです。 例: // ページ上のどこかに「ログイン成功」が存在すればOK I.see('ログイン成功'); // ヘッダー部分に「ログイン成功」が表示されているかを検証する場合 I.see('ログイン成功', '.header'); テストの実行|CodeceptJS ターミナル上で次のコマンドを実行します。 npx codeceptjs run --steps -stepsオプション: テストの各ステップ(I.fillFieldなど)をコンソールに詳細表示します。 実行結果: CodeceptJS v3.7.3 #StandWithUkraine Using test root "path-to-your-project" reservation -- 宿泊予約ができることを確認する Scenario() I am on page "<http://example.selenium.jp/reserveApp_Renewal/>" I fill field "#datePick", "2025/05/01" I select option "#reserve_term", "3" I select option "#headcount", "2" I fill field "#guestname", "山田太郎" I click "利用規約に同意して次へ" I see "予約内容" I see "2025年5月1日" I see "3泊" I see "2名" I see "山田太郎" I click "確定" I see "予約を完了しました" I see "ご来館、心よりお待ちしております。" ✔ OK in 2197ms OK | 1 passed // 3s 上記のように「OK」と表示されればテスト成功です。もし失敗すると、該当ステップでエラーが表示され、スクリーンショットも自動保存されます(デフォルトでoutputフォルダ内)。 また、言語設定で日本語に設定している場合は、下記のような実行結果になります。(日本語でのテスト記述も可能) CodeceptJS v3.7.3 #StandWithUkraine Using test root "path-to-your-project" reservation -- 宿泊予約ができることを確認する Scenario() 私は ページを移動する "<http://example.selenium.jp/reserveApp_Renewal/>" 私は フィールドに入力する "#datePick", "2025/05/01" 私は オプションを選ぶ "#reserve_term", "3" 私は オプションを選ぶ "#headcount", "2" 私は フィールドに入力する "#guestname", "山田太郎" 私は クリックする "利用規約に同意して次へ" 私は テキストがあることを確認する "予約内容" 私は テキストがあることを確認する "2025年5月1日" 私は テキストがあることを確認する "3泊" 私は テキストがあることを確認する "2名" 私は テキストがあることを確認する "山田太郎" 私は クリックする "確定" 私は テキストがあることを確認する "予約を完了しました" 私は テキストがあることを確認する "ご来館、心よりお待ちしております。" ✔ OK in 1444ms CodeceptJSと他のツールとの連携について CodeceptJSは複数のブラウザ制御エンジン(ヘルパー)に対応しており、以下のように設定を変更するだけでテストが動作します。 Playwright(今回使用) Puppeteer WebDriver TestCafe codecept.conf.jsファイルの中でヘルパーを指定する部分があります。たとえばPlaywrightの場合は以下のようになります。 helpers: { Playwright: { url: '<http://example.selenium.jp/reserveApp_Renewal/>', show: true, browser: 'chromium' } } browserを切り替えるとFirefoxやSafari相当でもテスト可能です。 また、他のプロダクトと連携したい場合(Allureレポート、BDDツールなど)のプラグインも充実しています。 おわりに デモサイトを使った簡単なテストを書くことで、CodeceptJSの導入からE2Eテストの実行までの流れを理解していただけたかと思います。シンプルな記述で強力なE2Eテストが実現できるCodeceptJSは、テスト自動化の強い味方となるでしょう。ぜひ本記事を参考に、あなたのプロジェクトでもCodeceptJSを導入・活用してみてください。 また、今後はAIを活用したテストコードについても解説したいと考えています。CodeceptJSは公式にAI連携機能を提供しており、ChatGPTなどの生成AIを活用したテストコードの自動生成や、自然言語での指示によるテスト作成が可能です。さらに、テスト失敗時の原因分析やテストケースの提案など、AIの力でテスト自動化をさらに効率化できます。CodeceptJSのAI機能を活用すれば、テストコードの品質向上と開発時間の短縮を同時に実現できるでしょう。 The post テスト自動化の決定版!CodeceptJSで実現するメンテナブルなE2Eテスト first appeared on Sqripts .
こんにちわ。 GSです。 今回はGoogle CloudでOpen WebUIを構築する方法を解説します。 本記事では、一つひとつのgcloudコマンドを実行しながらGoogle Cloud上にプライベートなAIチャット環境「Open WebUI」を構築していきます。Terraformのような一括デプロイではなく、各ステップを順に進めることで、Cloud Run、Cloud Storage、Cloud SQLなどのサービスがどのように連携するのかを体系的に理解できます。コマンドを実行し、結果を確認する過程を通じて、Google Cloudの基本から応用まで自然と身につき、最終的にはセキュアで拡張性のあるAI環境を自分の手で構築できる実力が養われます。初心者から中級者まで、実際に手を動かしながらクラウド技術を習得したいエンジニアにぴったりの実践ガイドです。 先に結論 この記事でわかること、得られること。 Open WebUI Open WebUIが使えるようになる Open WebUIのデプロイ設定方法が分かる Google Cloud Google Cloudをgcloudで操作することができる Cloud Runが何となく分かる サイドカーコンテナが何となく分かる 独自ドメインで運用できるようになる Cloud Storageが何となく分かる Cloud Runにマウントして使えることが分かる gsutilでファイルをアップロードできることが分かる Cloud SQLが何となく分かる Cloud Secret Managerが何となく分かる Cloud Runのスケール対応が何となく分かる Google Cloudにおけるプロダクトへのアクセス制限方法について何となく分かる Cloud Armorが何となく分かる Identity-Aware Proxy(IAP)が何となく分かる OAuthやOIDCの設定が何となく分かる VPCが何となく分かる Cloud Load Balancingが何となく分かる 前提条件 以下の必須条件および状況に応じてオプション条件を満たしていることを前提とします。 必須 この記事を作業する人に対して OPENAIのAPIキーがあること Google Cloudのプロジェクトを作成していること Google Cloudリソースを操作できる権限があること オプション この記事では段階的に環境を構築していきます。 Cloud DNSが操作できる権限があること または 扱いたい独自ドメインを管理しているサービスにアクセスできること Open WebUIとは? Open WebUIは、オープンソースのチャットインターフェースで、様々な大規模言語モデル(LLM)と対話するためのウェブベースのユーザーインターフェースです。元々はOllamaのフロントエンドとして開発されましたが、現在ではOpenAIをはじめ、追加の設定を行うことでAnthropic、Google、Mistral AIなど、多くのAIプロバイダーのモデルをサポートしています。 主な特徴 多様なモデルサポート : OpenAI GPT-4/3.5、Anthropic Claude、Google Gemini、Mistral AI、Ollama、その他のローカルモデルなど、様々なAIモデルと接続できます。 RAG(検索拡張生成)機能 : ウェブ検索、PDFアップロード、画像分析などを通じて、AIの回答を外部情報で強化できます。 チャット履歴管理 : 会話履歴を保存し、後で参照したり続きから対話したりできます。 カスタマイズ可能 : テーマ設定、プロンプトテンプレート、システムプロンプトなど、ユーザー体験をカスタマイズできる機能が豊富です。 マルチユーザー対応 : 複数のユーザーアカウントをサポートし、チームでの利用が可能です。 セルフホスティング : 自分のサーバーやクラウド環境にデプロイして、データの管理を自分で行えます。 利用シナリオ Open WebUIは以下のような用途で活用できます: 個人やチームでのAIアシスタントとして 社内向けのプライベートなAIチャットボットとして 複数のAIモデルを一つのインターフェースから利用したい場合 データプライバシーを重視する環境でのAI活用 この記事では、Google Cloud上にOpen WebUIをデプロイする方法を解説します。これにより、セキュアで拡張性の高いAIチャットインターフェースを構築することができます。 SearXNGとは? SearXNGは、プライバシーを重視したオープンソースのメタ検索エンジンです。複数の検索エンジン(Google、Bing、DuckDuckGoなど)から結果を収集し、それらを統合して提供します。Open WebUIには検索機能が統合されていないため、SearXNGを使用して最新のデータを取り込みます。o1のような検索機能がないモデルを利用しつつ、ネット上を検索させ結果を取り込みたいという場合、必須のサービスです。 しかしながら、 GPT-4o searchモデルなどの検索機能があるモデルを利用している場合は、SearXNGを使用する必要はありません。 以下にSearXNGの主な特徴を紹介します: 主な特徴 プライバシー保護 : ユーザーの検索クエリを匿名化し、検索エンジンに対して中継役として機能することで、ユーザーのプライバシーを保護します。 多様な検索ソース : 一般的なウェブ検索だけでなく、画像、動画、ニュース、地図など、様々なカテゴリの検索結果を提供します。 カスタマイズ可能 : 使用する検索エンジンの選択、結果の表示方法、インターフェースのテーマなど、多くの設定をカスタマイズできます。 トラッキングなし : ユーザーの行動を追跡せず、広告も表示しません。 セルフホスティング : 自分のサーバーにインストールして運用できるため、完全に制御可能です。 APIサポート : プログラムから検索結果にアクセスするためのAPIを提供しています。 Open WebUIとの連携 この記事では、Open WebUIとSearXNGをサイドカーコンテナとして配置し連携させて使用します。この組み合わせにより、以下のようなメリットがあります: AIチャットボットが最新の情報にアクセスできるようになります(RAG機能) ウェブ検索結果をプライバシーを保護しながら取得できます 外部依存を減らし、より自律的なAIアシスタント環境を構築できます SearXNGはOpen WebUIのRAG(検索拡張生成)機能のバックエンドとして機能し、AIの回答生成に役立つ最新の情報をウェブから取得します。 サイドカーコンテナとは? サイドカーコンテナは、メインのアプリケーションコンテナと同じPod内で実行される補助的なコンテナです。Kubernetes環境やCloud Runなどのコンテナオーケストレーションプラットフォームで利用される設計パターンの一つです。 サイドカーコンテナの主な特徴と利点は以下の通りです: 共有リソース : メインコンテナとネットワーク名前空間やボリュームを共有できるため、localhost経由で通信が可能です 分離された責務 : 機能ごとに別々のコンテナに分けることで、各コンテナの責務を明確にし、メンテナンス性を向上させます 独立したライフサイクル : メインアプリケーションに影響を与えずに、サイドカーコンテナを更新・再起動できます 専門化されたサービス : ログ収集、モニタリング、プロキシなど特定の機能に特化したコンテナを追加できます 今回のケースでは、Open WebUIがメインコンテナとなり、SearXNGがサイドカーコンテナとして動作します。これにより、Open WebUIはlocalhostを通じてSearXNGの検索機能にアクセスでき、両者が密接に連携しながらも、それぞれのコンテナが独自の責務を持つ構成が実現できます。 この構成により、Open WebUIの更新とSearXNGの更新を独立して行うことができ、また各コンテナが専門の機能に集中することでシステム全体の保守性が向上します。 操作環境 今回は環境の差異をできるだけなくすため、Google Cloud Shellを使用します。 Google Cloudの画面右上にある「Cloud Shellをアクティブにする」ボタンをクリックしてください。 「Cloud Shell の承認」ダイアログが表示されるので、「承認」をクリックしてください。 ブラウザ上で、gcloudやある程度のLinuxコマンドが使えるターミナル環境がブラウザに表示されます。 以降、この記事に書いてあるコマンドは、このターミナル上でコマンドを打っていきます。 gcloudのための環境変数 この記事では多くのコマンドを打っていきますが、そのコマンドを汎用的なコマンドにするために環境変数を使用しています。 以下の環境変数を設定してください。 今回はデプロイ先リージョンをus-central1にしています。 ご利用予定の環境に合わせて変更してください。 export PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)") export PROJECT_ID=$(gcloud config get-value project) export REGION=us-central1 export LOCATION=us-central1 export OPEN_WEBUI_DOMAIN=open-webui-${PROJECT_NUMBER}.${REGION}.run.app export OPENWEBUI_BUCKET_NAME=${PROJECT_ID}-open-webui export SEARXNG_BUCKET_NAME=${PROJECT_ID}-open-webui-searxng-config-bucket 適切に設定できているかを確認してみましょう。 echo PROJECT_NUMBER: $PROJECT_NUMBER \ PROJECT_ID: $PROJECT_ID \ REGION: $REGION \ LOCATION: $LOCATION \ OPEN_WEBUI_DOMAIN: $OPEN_WEBUI_DOMAIN \ OPENWEBUI_BUCKET_NAME: $OPENWEBUI_BUCKET_NAME \ SEARXNG_BUCKET_NAME: $SEARXNG_BUCKET_NAME それぞれの値が表示されれば、環境変数の設定は完了です。 Google Cloud API Google Cloud で必要な API を事前に有効化するための gcloud services enable コマンドがあります。 このコマンドを使用することで、インタラクティブなプロンプトなしに必要な API を事前に有効化できます。 gcloud services enable secretmanager.googleapis.com この記事全体で使う可能性のあるAPIを一括で有効化します。 gcloud services enable \ artifactregistry.googleapis.com \ secretmanager.googleapis.com \ run.googleapis.com \ sqladmin.googleapis.com \ admin.googleapis.com \ iap.googleapis.com \ certificatemanager.googleapis.com \ cloudresourcemanager.googleapis.com \ redis.googleapis.com Artifact Registry Open WebUIは、GitHub Container Registryにイメージが登録されています。 Google Cloudからは、GitHub Container Registryにアクセスできないため、そのミラーをArtifact Registryに作成して使用します。 Artifact Registryリポジトリの作成 リポジトリを作成します。 gcloud artifacts repositories create ghcr \ --repository-format=docker \ --location=${LOCATION} \ --description="Remote repository for GitHub Container Registry" \ --mode=remote-repository \ --remote-docker-repo=https://ghcr.io \ --remote-repo-config-desc="GitHub Container Registry" ### リポジトリの削除 リポジトリを削除したい場合は、以下のコマンドを実行します。 ```bash gcloud artifacts repositories delete ghcr --location=${LOCATION} Artifact Registryリポジトリ一覧の確認 リポジトリ一覧を確認します。 gcloud artifacts repositories list Artifact Registryリポジトリにキャッシュされているイメージ一覧の確認 リポジトリにキャッシュされているイメージ一覧を確認します。 gcloud artifacts docker images list ${REGION}-docker.pkg.dev/${PROJECT_ID}/ghcr サービスアカウント 今回はCloud Runにサービスをデプロイしていきます。そのCloud Runのためのサービスアカウントを作成します。 サービスアカウントとは サービスアカウントは、Google Cloud上でアプリケーションやワークロードが使用する特別な種類のアカウントです。人間のユーザーではなく、サービスやアプリケーションがGoogle Cloudリソースにアクセスするために使用されます。 サービスアカウントの主な特徴 アイデンティティとアクセス管理 Google Cloudリソースへのアクセスを制御するためのIAM(Identity and Access Management)と統合されています 必要最小限の権限を付与する「最小権限の原則」に基づいて設定できます 特定のサービスやリソースに対してのみ権限を付与することが可能です セキュリティ APIキーやパスワードではなく、より安全な認証メカニズムを提供します 自動的にローテーションされる短期の認証情報を使用できます 監査ログによりアクセスの追跡が可能です 柔軟性 複数のサービスアカウントを作成して、異なる役割や責任を分離できます 環境(開発、テスト、本番)ごとに異なるサービスアカウントを使用できます Compute Engine、Cloud Run、Cloud Functionsなど様々なサービスで利用可能です サービスアカウントの使用シナリオ Cloud Runアプリケーションが他のGoogle Cloudサービス(Cloud Storage、Cloud SQL、Secret Managerなど)にアクセスする場合 バッチジョブやスケジュールされたタスクがAPIを呼び出す場合 マイクロサービスアーキテクチャにおける、サービス間の認証 CI/CDパイプラインがリソースをデプロイする場合 サービスアカウントを適切に設定することで、アプリケーションに必要な権限のみを付与し、セキュリティリスクを最小限に抑えながらGoogle Cloudリソースへのアクセスを管理することができます。 サービスアカウントの作成 サービスアカウントを作成します。 gcloud iam service-accounts create open-webui \ --display-name="Open WebUI Service Account" サービスアカウントの削除 サービスアカウントを削除したい場合は、以下のコマンドを実行します。 gcloud iam service-accounts delete open-webui@${PROJECT_ID}.iam.gserviceaccount.com サービスアカウントにIAMポリシーのバインド Cloud RunからGoogle Cloudのサービスにアクセスするためには、サービスアカウントにIAMポリシーをバインドする必要があります。 シークレットマネージャーにアクセスするためのIAMポリシーをバインドします。 gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:open-webui@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" ストレージにアクセスし、ファイル作成編集するためのIAMポリシーをバインドします。 gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:open-webui@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/storage.objectAdmin" Cloud SQLにアクセスするためのIAMポリシーをバインドします。 gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:open-webui@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/cloudsql.client" RedisにアクセスするためのIAMポリシーをバインドします。 gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:open-webui@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/redis.editor" IAMポリシーの削除 IAMポリシーを削除したい場合は、以下のコマンドを実行します。 –roleに削除したいロールを指定します。 以下の例では「secretmanager.secretAccessor」ロールを削除しています。 gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:open-webui@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" Google Cloud Storage gcsにはいくつかの設定やファイルを保存します。今回は ユーザーのアップロードファイル SearXNGの設定ファイル のためのバケットを作成します。 SearXNGのバケットはCloud Run内のコンテナへマウントされて使用されます。コンテナからは通常のファイルやディレクトリとしてアクセスできます。 Google Cloud Storage(GCS)とは? Google Cloud Storage(GCS)は、Googleが提供するオブジェクトストレージサービスです。ファイルをオブジェクトとして保存し、世界中のどこからでもアクセスできるようにします。 Google Cloud Storageの主な特徴 高い耐久性と可用性 データは複数の場所に冗長的に保存され、99.999999999%(11個の9)の耐久性を実現 標準ストレージクラスでは99.99%の可用性を提供 地理的に分散したロケーションにデータを保存することも可能 柔軟なストレージクラス 標準ストレージ : 頻繁にアクセスされるデータ向け Nearline Storage : 月に1回程度アクセスされるデータ向け Coldline Storage : 四半期に1回程度アクセスされるデータ向け Archive Storage : 年に1回未満のアクセスで、長期保存が必要なデータ向け 強力なセキュリティ IAMによる詳細なアクセス制御 データの暗号化(保存時および転送時) VPCサービスコントロールによる境界保護 統合性 他のGoogleサービス(BigQuery、Cloud Run、Compute Engineなど)と簡単に連携 RESTful APIを通じて様々なアプリケーションから利用可能 Google Cloud Storageの利用シナリオ ウェブサイトのコンテンツ配信 データバックアップとアーカイブ ビッグデータ分析のためのデータレイク アプリケーションのユーザーアップロードファイルの保存 機械学習モデルの保存と配布 Cloud RunとGCSの連携 Cloud RunからGCSを利用する方法は主に2つあります: APIを通じたアクセス : Cloud Runのアプリケーションから、GCSのクライアントライブラリやRESTful APIを使用してバケット内のオブジェクトにアクセス マウント : Cloud Storage FUSEを使用して、GCSバケットをファイルシステムとしてマウント この記事では、Open WebUIのユーザーアップロードファイルの保存先としてGCSを利用し、SearXNGの設定ファイルをGCSに保存してCloud Runコンテナにマウントする方法を解説します。 Open WebUIに対するユーザーのアップロードファイル保存バケットの作成 ユーザーのアップロードファイル保存バケットを作成します。 gcloud storage buckets create gs://${OPENWEBUI_BUCKET_NAME} --location=${LOCATION} ユーザーのアップロードファイル保存バケットの削除 上記で作成したバケットを削除したい場合は、以下のコマンドを実行します。 gcloud storage buckets delete gs://${OPENWEBUI_BUCKET_NAME} SearXNGの設定ファイル保存バケットの作成 SearXNGの設定ファイルを保存するバケットを作成します。 gcloud storage buckets create gs://${SEARXNG_BUCKET_NAME} --location=${LOCATION} SearXNGファイル保存バケットの削除 上記で作成したバケットを削除したい場合は、以下のコマンドを実行します。 gcloud storage buckets delete gs://${SEARXNG_BUCKET_NAME} OPENAI Open WebUIでは、OPENAIのAPIを使用して、チャットや画像生成、音声生成などの機能を利用できます。 ここではOpen WebUIで、OPENAIに関する機能を使うための設定を行っていきます。 事前にOPENAIより APIキーを取得 してください。 OPENAI APIキーのシークレットの作成 シークレットを作成します。 YOUR_OPEN_WEBUI_OPENAI_API_KEY部分を実際に利用するキーに書き換えます。 別のキーに更新したい場合も、同じコマンドで更新できます。 ここで作成されたシークレットの値がOpen WebUIのCloud Runの環境変数に設定されます。 echo -n "YOUR_OPEN_WEBUI_OPENAI_API_KEY" | gcloud secrets create open_webui_openai_api_key \ --replication-policy="automatic" \ --data-file=- シークレットの削除 シークレットを削除したい場合は、以下のコマンドを実行します。 gcloud secrets delete open_webui_openai_api_key OAuth OAuthに関する設定をおこないます。 この設定を行うことで、Open WebUIにGoogle Workspaceのユーザーがログインできるようになります。 gcloudである程度の設定を行えますが、機能的に厳しいため、ブラウザでGoogle Cloud Consoleを開いて操作します。 OAuthとは OAuth(Open Authorization)は、ユーザーが自分のアカウント情報を第三者のアプリケーションに直接提供することなく、安全に認証・認可を行うための標準プロトコルです。 OAuth 2.0の主な特徴 安全な認証委任 ユーザーはパスワードを第三者アプリケーションに直接提供する必要がありません 代わりに、信頼できる認証プロバイダー(GoogleやFacebookなど)を通じて認証します アプリケーションはユーザーの同意を得た特定の権限(スコープ)のみを取得できます 柔軟なアクセス制御 アクセストークンを使用して、リソースへのアクセスを制御します トークンには有効期限があり、セキュリティリスクを軽減します 必要に応じてトークンを無効化することも可能です 様々な認証フロー 認可コードフロー:Webアプリケーション向け インプリシットフロー:ブラウザベースのアプリケーション向け クライアントクレデンシャルフロー:サーバー間通信向け リソースオーナーパスワードクレデンシャルフロー:高度な信頼関係がある場合向け OpenID Connectとは OpenID Connect(OIDC)は、OAuth 2.0プロトコルの上に構築された認証レイヤーです。OAuth 2.0が「認可」(何ができるか)に焦点を当てているのに対し、OpenID Connectは「認証」(誰であるか)に焦点を当てています。 OpenID Connectの主な特徴 ID Token : JWT(JSON Web Token)形式で、ユーザーの身元情報を含みます UserInfo Endpoint : ユーザーに関する追加情報を取得するためのエンドポイント 標準化されたクレーム : email、name、pictureなど、ユーザー情報の標準フィールド ディスカバリー : 認証サーバーの設定を自動的に発見する機能 OpenID Connectの利点 シングルサインオン(SSO)の実現が容易になります 標準化されたプロトコルにより、異なるプラットフォーム間での相互運用性が向上します セキュリティが強化され、フィッシング攻撃などのリスクが軽減されます Open WebUIでは、このOAuth 2.0とOpenID Connectを利用して、Googleアカウントでの安全なログインを実現しています。ユーザーはGoogleの認証システムを通じて認証され、Open WebUIはユーザーの基本情報のみを受け取り、パスワードなどの機密情報は一切取得しません。 OAuthブランドの作成 Google Cloud ConsoleでOAuthブランドを作成します。 ブランディングより「開始」ボタンを押します。 アプリ情報と連絡先メールアドレスを入力します。 対象を「内部」に設定します。 連絡先にメールアドレスを設定します。 同意を選択し「作成」ボタンを押しましょう。 以上でブランディングの作成は完了です。 OAuthブランド一覧の確認 作成したOAuthブランドはGoogle Cloud Consoleで確認できますが、以下のコマンドでも確認できます。 gcloud iap oauth-brands list OAuthクライアントの作成 OAuthクライアントはgcloudでも作成できますが、機能的にはGoogle Cloud Consoleで作成した方が良いです。 クライアントメニューより「+ CREATE CLIENT」を選択します。 アプリケーションの種類を「Webアプリケーション」。名前は適切なものを設定してください。 最後に作成ボタンを押します。 OAuth Client IDをシークレットマネージャーへ登録 OAuth Client画面から、Client IDとClient Secretを取得し、その値でシークレットを作成します。YOUR_OPEN_WEBUI_OAUTH_CLIENT_ID部分を実際に利用するキーに書き換えます。 echo -n "YOUR_OPEN_WEBUI_OAUTH_CLIENT_ID" | gcloud secrets create open_webui_oauth_client_id \ --replication-policy="automatic" \ --data-file=- OAuth Client IDシークレットの削除 上記で作成したシークレットを削除したい場合は、以下のコマンドを実行します。 gcloud secrets delete open_webui_oauth_client_id OAuth Client Secretをシークレットマネージャーへ登録 シークレットを作成します。YOUR_OPEN_WEBUI_OAUTH_CLIENT_SECRET部分を実際に利用するキーに書き換えます。 echo -n "YOUR_OPEN_WEBUI_OAUTH_CLIENT_SECRET" | gcloud secrets create open_webui_oauth_client_secret \ --replication-policy="automatic" \ --data-file=- OAuth Client Secretシークレットの削除 上記で作成したシークレットを削除したい場合は、以下のコマンドを実行します。 gcloud secrets delete open_webui_oauth_client_secret Cloud SQL Cloud SQLでPostgreSQLを作成して使用します。 Cloud SQLはOpen WebUIの設定やチャットのデータ管理に使用されます。 Cloud SQLとは Cloud SQLは、Google Cloudが提供するフルマネージドのリレーショナルデータベースサービスです。MySQL、PostgreSQL、SQL Serverなどの主要なデータベースエンジンをサポートしており、インフラストラクチャの管理やメンテナンスの負担を軽減しながら、高可用性と耐久性のあるデータベース環境を提供します。 Cloud SQLの主な特徴 マネージドサービス バックアップ、パッチ適用、レプリケーション、容量管理などの運用タスクを自動化 データベースエンジンのアップデートを自動的に管理 監視とアラートの機能が組み込まれている セキュリティ データの保存時と転送時の暗号化 ネットワークファイアウォールによるアクセス制御 IAMとの統合による認証と認可 Virtual Private Cloud (VPC) 内でのプライベート接続 高可用性と耐久性 リージョン内での高可用性構成(99.95%のSLA) 自動フェイルオーバー機能 定期的な自動バックアップとポイントインタイムリカバリ クロスリージョンレプリケーション(災害復旧用) スケーラビリティ 垂直スケーリング(マシンタイプのアップグレード) 読み取りレプリカによる水平スケーリング ストレージの自動拡張 統合性 Google Cloud内の他のサービス(Cloud Run、Compute Engine、BigQueryなど)との簡単な連携 Cloud SQLプロキシを使用した安全な接続 データベース移行サービス(DMS)によるデータ移行のサポート Cloud SQLの利用シナリオ Webアプリケーションやモバイルアプリのバックエンドデータベース ビジネスアプリケーション(CRM、ERP、eコマースなど)のデータストア データ分析や報告のためのデータウェアハウス マイクロサービスアーキテクチャにおけるサービス固有のデータベース レガシーデータベースのクラウド移行先 Cloud SQLを使用することで、データベース管理の複雑さを軽減しながら、スケーラブルで信頼性の高いデータベース環境を構築することができます。 インスタンスの作成 今回は単純な構成でPostgreSQL 17のインスタンスを作成します。 利用の環境に合わせて、各パラメーターを調整したり、バックアップの設定やリードレプリカの作成などを行ってください。 また、コマンドにある「YOUR_SECURE_PASSWORD」部分を実際に利用するパスワードに書き換えます。 gcloud sql instances create open-webui \ --database-version=POSTGRES_17 \ --tier=db-custom-1-3840 \ --region=${REGION} \ --edition=ENTERPRISE \ --root-password="YOUR_SECURE_PASSWORD" インスタンスの削除 インスタンスを削除したい場合は、以下のコマンドを実行します。 gcloud sql instances delete open-webui データベースの作成 Open WebUIのデータベースを作成します。 gcloud sql databases create open-webui \ --instance=open-webui データベースの削除 データベースを削除したい場合は、以下のコマンドを実行します。 gcloud sql databases delete open-webui \ --instance=open-webui ユーザーの作成 Open WebUIのユーザーを作成します。 また、コマンドにある「YOUR_USER_PASSWORD」部分を実際に利用するパスワードに書き換えます。 gcloud sql users create open-webui \ --instance=open-webui \ --password="YOUR_USER_PASSWORD" ユーザーの削除 ユーザーを削除したい場合は、以下のコマンドを実行します。 gcloud sql users delete open-webui \ --instance=open-webui データベースrootパスワードをシークレットマネージャーに作成 シークレットを作成します。YOUR_SECURE_PASSWORD部分をデータベースrootパスワードに書き換えます。 このシークレットは今回の作業では使うことはありません。 設定したパスワードを記録しておくためだけに作成しています。 ですのでこの工程は省略可能です。 echo -n "YOUR_SECURE_PASSWORD" | gcloud secrets create open_webui_database_root_password \ --replication-policy="automatic" \ --data-file=- データベース接続URLをシークレットマネージャーに作成 シークレットを作成します。YOUR_USER_PASSWORD部分をデータベースアカウント作成時に指定したパスワードに書き換えます。 echo -n "postgresql://open-webui:YOUR_USER_PASSWORD@/open-webui?host=/cloudsql/${PROJECT_ID}:${REGION}:open-webui" | gcloud secrets create open_webui_database_url \ --replication-policy="automatic" \ --data-file=- データベース接続URLシークレットの削除 上記で作成したシークレットを削除したい場合は、以下のコマンドを実行します。 gcloud secrets delete open_webui_database_url SearXNG設定 SearXNGの設定ファイルを保存するバケットを作成します。 以下は一般的な設定です。 細かい制御を行いたい場合は、 SearXNGの公式ドキュメント を参照してください。 limiter.tomlを作成 limiter.tomlを作成します。 cat << 'EOF' >| limiter.toml # This configuration file updates the default configuration file # See https://github.com/searxng/searxng/blob/master/searx/botdetection/limiter.toml [botdetection.ip_limit] # activate link_token method in the ip_limit method link_token = false [botdetection.ip_lists] block_ip = [] pass_ip = [] EOF settings.yamlを作成 settings.yamlを作成します。 cat << 'EOF' >| settings.template.yml use_default_settings: true server: secret_key: "$(openssl rand -hex 32)" search: formats: - html - json safe_search: 0 outgoing: request_timeout: 6.0 max_request_timeout: 15.0 retries: 3 EOF 一部シェルコマンドが含まれているため、以下のコマンドでシェルコマンドを展開します。 envsubst < settings.template.yml >| settings.yml バケットに設定ファイルをアップロード 作成した設定ファイルをバケットにアップロードします。 gsutil cp limiter.toml settings.yml gs://${SEARXNG_BUCKET_NAME}/ 作成したファイルがアップロードされているか確認してみましょう。 gsutil ls gs://${SEARXNG_BUCKET_NAME}/ ファイルが見えれば成功です。 SearXNGの設定ファイルを削除 作成した設定ファイルを削除したい場合は、以下のコマンドを実行します。 gsutil rm "gs://${SEARXNG_BUCKET_NAME}/*" Cloud Run アプリケーションの実態であるコンテナをCloud Runへデプロイします。 Cloud Runとは Cloud Runは、コンテナ化されたアプリケーションをサーバーレスで実行できるマネージドコンピューティングプラットフォームです。 主な特徴 サーバーレス インフラストラクチャの管理が不要 使用した分だけ課金される従量課金制 自動でスケーリング コンテナベース DockerコンテナをそのままデプロイできるためCI/CDとの親和性が高い 言語やフレームワークを問わずアプリケーションを実行可能 コンテナイメージの管理が容易 セキュリティ HTTPSエンドポイントを自動で提供 IAMによる認証・認可の制御 VPCとの接続も可能 運用性 リビジョン管理によるロールバックが容易 ヘルスチェックによる自動復旧 ログやメトリクスの可視化 Cloud Runを使用することで、インフラストラクチャの管理から解放され、アプリケーションの開発に集中することができます。 Cloud Run構成定義yamlファイルの作成 今回はyamlファイルを用いてCloud Runサービスを作成します。 以下のコマンドで、Open WebUIの環境を作成するためのテンプレートファイルを作成します。 cat << 'EOF' >| open-webui.template.yaml apiVersion: serving.knative.dev/v1 kind: Service metadata: name: open-webui annotations: run.googleapis.com/ingress: all run.googleapis.com/ingress-status: all spec: template: metadata: annotations: autoscaling.knative.dev/minScale: '0' autoscaling.knative.dev/maxScale: '1' run.googleapis.com/cloudsql-instances: ${PROJECT_ID}:${LOCATION}:open-webui spec: containerConcurrency: 40 timeoutSeconds: 600 serviceAccountName: open-webui@${PROJECT_ID}.iam.gserviceaccount.com containers: - name: open-webui image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/ghcr/open-webui/open-webui@sha256:9b7fb388f0828b597e67c263667214c93592cbc5cac3047be89f5e92bc1085ba ports: - name: http1 containerPort: 8081 env: - name: DEFAULT_USER_ROLE value: user - name: ENABLE_LOGIN_FORM value: 'True' - name: STORAGE_PROVIDER value: gcs - name: GCS_BUCKET_NAME value: ${OPENWEBUI_BUCKET_NAME} - name: ENABLE_OAUTH_SIGNUP value: 'True' - name: OPENID_PROVIDER_URL value: https://accounts.google.com/.well-known/openid-configuration - name: ENABLE_OAUTH_GOOGLE value: 'True' - name: GOOGLE_REDIRECT_URI value: https://${OPEN_WEBUI_DOMAIN}/oauth/google/callback - name: WEBUI_URL value: https://${OPEN_WEBUI_DOMAIN} - name: ENABLE_OLLAMA_API value: 'False' - name: ENABLE_EVALUATION_ARENA_MODELS value: 'False' - name: ENABLE_RAG_WEB_SEARCH value: 'True' - name: RAG_WEB_SEARCH_ENGINE value: "searxng" - name: RAG_WEB_SEARCH_RESULT_COUNT value: '3' - name: RAG_WEB_SEARCH_CONCURRENT_REQUESTS value: '10' - name: SEARXNG_QUERY_URL value: "http://localhost:8080/search?q=<query>" - name: DATABASE_URL valueFrom: secretKeyRef: key: latest name: open_webui_database_url - name: OPENAI_API_KEY valueFrom: secretKeyRef: key: latest name: open_webui_openai_api_key - name: GOOGLE_CLIENT_ID valueFrom: secretKeyRef: key: latest name: open_webui_oauth_client_id - name: GOOGLE_CLIENT_SECRET valueFrom: secretKeyRef: key: latest name: open_webui_oauth_client_secret resources: limits: cpu: 2000m memory: 2.0Gi startupProbe: httpGet: path: / port: 8081 initialDelaySeconds: 10 periodSeconds: 3 failureThreshold: 30 - name: searxng image: searxng/searxng:latest env: - name: SEARXNG_HOSTNAME value: 'localhost:8080' - name: SEARXNG_PORT value: '8080' - name: SEARXNG_BIND_ADDRESS value: '0.0.0.0' - name: SEARXNG_STATIC_USE_HASH value: 'true' - name: SEARXNG_LIMITER value: 'false' - name: SEARXNG_IMAGE_PROXY value: 'true' resources: limits: cpu: 1000m memory: 1Gi volumeMounts: - name: searxng-config mountPath: /etc/searxng volumes: - name: searxng-config csi: driver: gcsfuse.run.googleapis.com readOnly: false volumeAttributes: bucketName: ${SEARXNG_BUCKET_NAME} EOF 続けて以下のコマンドを実行し、yamlファイルを作成します。 envsubst < open-webui.template.yaml > open-webui.yaml Cloud Runサービスの作成 作成したyamlファイルを用いてCloud Runサービスを作成します。 gcloud run services replace open-webui.yaml --project=${PROJECT_ID} --region=${REGION} --platform=managed Cloud Runサービスの削除 上記で作成したサービスを削除したい場合は、以下のコマンドを実行します。 gcloud run services delete open-webui --project=${PROJECT_ID} --region=${REGION} Cloud RunサービスのIAMポリシーの設定 Cloud RunサービスのIAMポリシーを設定します。 この設定は非常に重要で、たとえばOpen WebUIのCloud Runを削除して作り直した場合などには常に再実行する必要があります。 今回はこの設定で、誰でもアクセスできるようにしています。逆を言えば、この設定を行わないと、誰もアクセスできないようになります。 gcloud run services add-iam-policy-binding open-webui --member="allUsers" --role="roles/run.invoker" --region=${REGION} OAuth認証設定 OAuthを使うための設定を行っていきます。 この設定の中で、Open ID Connectを使うための設定も間接的に行っています。 ブランディング Google Cloud Console → APIとサービス → OAuth 同意画面 → ブランディング の認証済みドメインへ echo ${OPEN_WEBUI_DOMAIN} で表示されるドメイン名を追加します。 OAuth2.0クライアント Google Cloud Console → APIとサービス → OAuth同意画面 → クライアント → 前工程で作成したOAuth2.0クライアントを選択 承認済みの JavaScript 生成元を追加 Cloud Run作成時に表示されたURLまたは gcloud run services describe open-webui --region=${REGION} --format="value(status.url)" で表示されるURLを「承認済みの JavaScript 生成元」に追加します。 「+URIを追加」をクリックして、URLを追加します。 承認済みのリダイレクトURIを追加 「承認済みのリダイレクト URI」には、Cloud Run作成時に表示されたURLまたはbash gcloud run services describe open-webui --region=${REGION} --format="value(status.url)" で表示されるURLに、 /oauth/google/callback を追加した値を追加します。 「+URIを追加」をクリックして、URLを追加します。 追加するURLは、 https://${デプロイ後に表示されるURL}/oauth/google/callback のようになるはずです。 データアクセス Google Cloud Console → APIとサービス → OAuth同意画面 → データアクセス ここからScopeの設定を行います。 「スコープを追加または削除」を押して、上から3つを選択します。 …/auth/userinfo.email Google アカウントのメインのメールアドレスの参照 …/auth/userinfo.profile ユーザーの個人情報の表示(ユーザーが一般公開しているすべての個人情報を含む) openid Google で公開されているお客様の個人情報とお客様を関連付ける これらを選択した後、「更新」を押します。 Open WebUIを利用してみる 以上で、Cloud Runサービスの作成は完了です。 Cloud Run作成完了後に表示されるURLへアクセスしてみましょう。 Open WebUIのログイン画面が表示されます。 URLがわからないという場合、以下のコマンドでURLを確認できます。 gcloud run services describe open-webui --region=${REGION} --format="value(status.url)" アクセスした際に Error: Forbidden Your client does not have permission to get URL / from this server. というエラーが表示される場合は、Cloud RunサービスのIAMポリシーを適用していない可能性が高いです。またIAMポリシー適用には時間がかかるため、動かないからと言ってすぐに設定を変えてみたりせず、しばらく待ってから再度確認してください。 今回のセットアップではGoogle Workspaceユーザーを使用したOAuthによるログインを有効にしているので、トップ画面より「Continue with Google」ボタンでログインし、そのまま使用することが可能です。 独自ドメインでの運用 ここまでの設定でもOpen WebUIを使うことは可能です。 ただ実際に使っていくとなると、独自ドメインを使用したくなると思います。 今回はGoogle Cloudで独自ドメインのゾーンを作成し、そのゾーンに独自ドメインをマッピングして運用してみます。 そのため、その使用予定の独自ドメインを管理することができるだけの状況下にあることを前提とします。 独自ドメインを使うための前準備 まずは独自ドメインとDNSのゾーン名称を環境変数に設定します。 YOUR_OPEN_WEBUI_DOMAIN / YOUR_ZONE_NAMEには、使用予定の独自ドメインとDNSのゾーン名称を設定します。 export OPEN_WEBUI_DOMAIN=YOUR_OPEN_WEBUI_DOMAIN export ZONE_NAME=YOUR_ZONE_NAME open-webui.example.comなら、 export OPEN_WEBUI_DOMAIN=open-webui.example.com とします。 example.comなら、 export ZONE_NAME=example-com とします。 指定した独自ドメインを使用して再度yamlファイルを生成します。 envsubst < open-webui.template.yaml >| open-webui.yaml 作成したyamlファイルを用いてCloud Runサービスを作成します。 gcloud run services replace open-webui.yaml --project=${PROJECT_ID} --region=${REGION} --platform=managed 独自ドメインのマッピング ドメインマッピングを作成します。 gcloud beta run domain-mappings create --service open-webui --domain ${OPEN_WEBUI_DOMAIN} --region ${REGION} (Cloud DNSでゾーン管理している人向け)独自ドメインのDNSレコードの作成 独自ドメインのDNSレコードを作成します。 レコードを追加するゾーンについては、すでに作成済みであり、ゾーンの所有確認が完了しているとします。 gcloud dns record-sets create ${OPEN_WEBUI_DOMAIN} \ --rrdatas="ghs.googlehosted.com." \ --ttl=300 \ --type=CNAME \ --zone=${ZONE_NAME} DNSレコードが正しく設定されたかを確認するには以下のコマンドを実行し、CNAMEレコードが存在することを確認します。 gcloud dns record-sets list --zone=${ZONE_NAME} または、nslookupやdigコマンドを使用して確認することもできます。 nslookup ${OPEN_WEBUI_DOMAIN} (Cloud DNSでゾーン管理していない人向け)独自ドメインのDNSレコードの作成 ご自身が利用されているDNSサービスで、CNAMEレコードを作成してください。 証明書のプロビジョニング DNSレコードが正しく設定されると、Google Cloudは自動的にSSL証明書のプロビジョニングを開始します。証明書のステータスは以下のコマンドで確認できます。 gcloud beta run domain-mappings describe --domain ${OPEN_WEBUI_DOMAIN} --region ${REGION} 証明書のプロビジョニングには時間がかかる場合があります。 いくつかのステータスがtrueになれば証明書のプロビジョニングが完了しています。 完了できていることが確認できたら、今回設定した独自ドメインへブラウザでアクセスしてみましょう。 画面が表示されれば設定は完了です。 ロードバランサー下での運用 より一層細かい制御を行いたいという場合、ロードバランサー下での運用を行うことも可能です。 ロードバランサー下での運用の前準備 前工程での独自ドメイン運用設定を行っている場合、まずはその設定を削除します。 ドメインマッピングの削除 ドメインマッピングを削除します。 gcloud beta run domain-mappings delete --domain ${OPEN_WEBUI_DOMAIN} --region ${REGION} ドメイン名のDNSレコードの削除 CNAMEレコードを削除します。 ゾーン名称は適切な値に変更してください。 gcloud dns record-sets delete ${OPEN_WEBUI_DOMAIN} --type=CNAME --zone=${ZONE_NAME} グローバルIPアドレスの予約 ロードバランサー下での運用にはグローバルIPアドレスが必要です。 前もってグローバルIPアドレスを予約しておきます。 gcloud compute addresses create open-webui-ip \ --global 予約したIPアドレスの確認 gcloud compute addresses describe open-webui-ip --global --format="get(address)" Cloud Run NEGの作成 gcloud compute network-endpoint-groups create open-webui-neg \ --region=${REGION} \ --network-endpoint-type=SERVERLESS \ --cloud-run-service=open-webui バックエンドサービスの作成 gcloud compute backend-services create open-webui-backend \ --global \ --load-balancing-scheme=EXTERNAL_MANAGED NEGをバックエンドサービスに追加 gcloud compute backend-services add-backend open-webui-backend \ --global \ --network-endpoint-group=open-webui-neg \ --network-endpoint-group-region=${REGION} URLマップの作成 gcloud compute url-maps create open-webui-url-map \ --default-service=open-webui-backend Cloud DNSへAレコードの作成 グローバルIPアドレスの予約時に取得したIPアドレスを使用します。 ゾーンは適切な値に変更してください。 gcloud dns record-sets create ${OPEN_WEBUI_DOMAIN} \ --type=A \ --ttl=300 \ --rrdatas=$(gcloud compute addresses describe open-webui-ip --global --format="get(address)") \ --zone=${ZONE_NAME} マネージドSSL証明書の作成 gcloud compute ssl-certificates create open-webui-cert \ --domains=${OPEN_WEBUI_DOMAIN} \ --global HTTPSプロキシの作成 gcloud compute target-https-proxies create open-webui-https-proxy \ --ssl-certificates=open-webui-cert \ --url-map=open-webui-url-map 転送ルールの作成 gcloud compute forwarding-rules create open-webui-https-rule \ --load-balancing-scheme=EXTERNAL_MANAGED \ --network-tier=PREMIUM \ --address=open-webui-ip \ --target-https-proxy=open-webui-https-proxy \ --global \ --ports=443 Cloud Runに対する外部からの直接アクセスを遮断 まず最新の情報でopen-webui.yamlファイルを更新します。 envsubst < open-webui.template.yaml >| open-webui.yaml open-webui.yamlファイルの以下の部分を変更します。 この設定の変更を行いデプロイすることで、Cloud Runに対する外部からの直接アクセスを遮断できます。 sed -i 's/run.googleapis.com\/ingress: all/run.googleapis.com\/ingress: internal-and-cloud-load-balancing/g' open-webui.yaml sed -i 's/run.googleapis.com\/ingress-status: all/run.googleapis.com\/ingress-status: internal-and-cloud-load-balancing/g' open-webui.yaml その後、デプロイします。 gcloud run services replace open-webui.yaml --project=${PROJECT_ID} --region=${REGION} --platform=managed この時点で、Cloud Runデプロイ後に表示されるURLや、 gcloud run services describe open-webui --region=${REGION} --format="value(status.url)" で表示されるURLにアクセスしても、Cloud Runに対する外部からの直接アクセスを遮断されているため、アクセスできなくなっているはずです。 代わりに設定した独自ドメインにアクセスすると、Open WebUIの画面が表示されるはずです。 今回の行程においては証明書のプロビジョニングを行っています。この処理は通常20分ほどかかるため、証明書のプロビジョニングが完了するまでは、設定した独自ドメインにアクセスしてもアクセスできない可能性が高いです。 証明書のプロビジョニングが完了しているかを確認したい場合は、以下のコマンドを実行してください。 gcloud compute ssl-certificates describe open-webui-cert --global status: PROVISIONING の場合は、証明書のプロビジョニングが完了するまで待ってください。 status: ACTIVE の場合は、証明書のプロビジョニングが完了しています。 Open WebUIに対するアクセス制御 ロードバランサー配下においたことにより、ロードバランサーの背後にあるCloud Runサービスに対するアクセス制御を行うことができます。 今回はセキュリティポリシーの適用による日本からのアクセスに限定する方法と、Identity-Aware ProxyによるGoogle Workspaceユーザーのみがアクセスできるようになる方法を紹介します。 なお この2つの方法は同時に適用することはできません。 Identity-Aware Proxyによるアクセス制御の一部が日本以外からのアクセスとなり、セキュリティポリシーの適用による日本からのアクセスに限定する方法とは矛盾するからです。 セキュリティポリシー(Cloud Armor)で制御したい場合 日本からのアクセスのみ許可するように設定してみます。 セキュリティポリシーの作成 まずはポリシーを作成します。 gcloud compute security-policies create open-webui-security-policy \ --description "open-webuiに対するセキュリティポリシー" 作成したポリシーに対して、日本からのアクセスを許可するルールを作成します。 gcloud compute security-policies rules create 1000 \ --security-policy open-webui-security-policy \ --description "日本からのアクセスを許可" \ --expression "origin.region_code == 'JP'" \ --action "allow" 作成したポリシーにおけるデフォルトルール(明示したルールにマッチしない場合のルール)を拒否に設定します。 2147483647はデフォルトルールのIDです。 gcloud compute security-policies rules update 2147483647 \ --security-policy open-webui-security-policy \ --description "デフォルトでアクセスを拒否" \ --action "deny-403" セキュリティポリシーをバックエンドサービスに適用 gcloud compute backend-services update open-webui-backend \ --security-policy=open-webui-security-policy \ --global 以上の設定で、日本からのアクセスのみ許可するようになります。 海外のProxyなどを利用して、アクセスできなくなっていることを確認してみてください。 セキュリティポリシーの適用を解除したい場合、 gcloud compute backend-services update open-webui-backend \ --security-policy= \ --global で、セキュリティポリシーの適用を解除できます。 Identity-Aware Proxy(IAP)で制御したい場合 Identity-Aware Proxyで、Google Workspaceユーザーのみがアクセスできるようにしてみます。 Identity-Aware Proxy(IAP)とは Identity-Aware Proxy(IAP)は、Google Cloudが提供するセキュリティサービスで、アプリケーションやリソースへのアクセスを細かく制御することができます。従来のVPNやファイアウォールとは異なり、ユーザーの身元(アイデンティティ)に基づいてアクセス制御を行います。 IAPの主な特徴 ユーザーベースのアクセス制御 Google WorkspaceやCloud Identityのユーザーアカウントを使用して認証を行います 特定のユーザー、グループ、ドメイン単位でアクセス権を付与できます IPアドレスではなく「誰であるか」に基づいてアクセスを制御します セキュリティの向上 VPNを使わずともセキュアなアクセスが可能になります 多要素認証(MFA)と組み合わせることで、さらにセキュリティを強化できます すべてのアクセスはログに記録され、監査が可能です 簡単な導入 アプリケーションコードの変更なしに導入できます Google Cloud Consoleから簡単に設定可能です 既存のCloud RunやApp Engineなどのサービスにシームレスに統合できます Identity-Aware Proxy(IAP)の仕組み Identity-Aware Proxy(IAP)は、ユーザーがアプリケーションにアクセスする際に「門番」のような役割を果たします: ユーザーがアプリケーションのURLにアクセスします Identity-Aware Proxy(IAP)がリクエストを受け取り、ユーザーに認証を要求します ユーザーがGoogle認証情報でログインします Identity-Aware Proxy(IAP)はユーザーの身元を確認し、アクセス権があるか確認します アクセス権がある場合のみ、リクエストをアプリケーションに転送します これにより、認証されていないユーザーはアプリケーションにアクセスできなくなり、セキュリティが大幅に向上します。 Identity-Aware Proxy(IAP)の利用シナリオ 社内ツールへのアクセスを特定の従業員のみに制限したい場合 顧客向けアプリケーションを特定の顧客のみに公開したい場合 開発環境や管理コンソールへのアクセスを開発者のみに制限したい場合 VPNを使わずに社内リソースへのセキュアなアクセスを提供したい場合 Identity-Aware Proxy(IAP)を使用することで、「誰が」「どのリソースに」アクセスできるかを細かく制御でき、セキュリティを強化しながらも利便性を損なわないアクセス管理が可能になります。 backend-servicesにIAPを有効化 先ほど作成したbackend-servicesに対し、Identity-Aware Proxy(IAP)を有効化します。 Google Cloud ConsoleのIdentity-Aware Proxy(IAP)のページで、確認できるようになります。 gcloud compute backend-services update open-webui-backend \ --global \ --iap backend-servicesのIAPを削除 backend-servicesを削除する場合は、以下のコマンドを実行します。 ただこのコマンド単体では削除に失敗する可能性が高いです。 gcloud compute backend-services delete open-webui-backend --global 実際削除しようと思うと、関係するリソースを先に削除する必要があります。 # 1. 転送ルールの削除 gcloud compute forwarding-rules delete open-webui-https-rule --global # 2. HTTPS プロキシの削除 gcloud compute target-https-proxies delete open-webui-https-proxy # 3. URL マップの削除 gcloud compute url-maps delete open-webui-url-map # 4. バックエンドサービスの削除(これで成功するはず) gcloud compute backend-services delete open-webui-backend --global 指定したドメインのみ許可 指定したドメインのみ許可する場合は、以下のコマンドを実行します。 たとえば、example.comのメールアドレスのみを許可する場合は、以下のコマンドを実行します。 gcloud iap web add-iam-policy-binding \ --member=domain:example.com \ --role=roles/iap.httpsResourceAccessor \ --resource-type=backend-services \ --service=open-webui-backend 指定したドメインの削除 指定したドメインを削除する場合は、以下のコマンドを実行します。 以下の例は、example.comを削除したい場合のコマンドです。 gcloud iap web remove-iam-policy-binding \ --member=domain:example.com \ --role=roles/iap.httpsResourceAccessor \ --resource-type=backend-services \ --service=open-webui-backend 独自ドメインをOAuth設定に追加 OAuth認証設定 と同じ手順で、独自ドメインをOAuth設定に追加します。 Identity-Aware Proxy(IAP)越しにアクセス 以上で、Identity-Aware Proxy(IAP)の設定は完了です。 トップページのアドレスにアクセスすると、「Googleでログイン」画面が表示されます。 ここでGoogle Workspaceのユーザーでログインすると、Open WebUIにアクセスできるようになります。 ここまでの内容で、ロードバランサー下での運用は完了です。 スケール対応 現在のopen-webui.yamlの設定では、1つのインスタンスしか起動しないようになっています。 これは、現在の設定のままだと、セッション情報の保存場所がローカル(インスタンス内)になっていて、インスタンスを複数起動しても、インスタンス間セッション情報が共有されず、正しいセッション管理ができないためです。 想定している同時アクセス数がそれほど多くない場合は1インスタンスで運用しても問題ないでしょう。 しかし、同時アクセス数が多い場合は、インスタンスを複数起動して水平スケールを行う必要があります。 VPC セッション情報の共有ためにRedisを使います。その際、Cloud RunからRedisにアクセスするためには、VPCを使う必要があります。 VPCとは? VPC(Virtual Private Cloud)は、Google Cloud Platform上に作成できる仮想ネットワークです。VPCを使用することで、クラウド内のリソース間で安全に通信できる独立したネットワーク環境を構築できます。 VPCの主な特徴と利点は以下の通りです: 分離されたネットワーク環境 : 他のプロジェクトやユーザーのリソースから論理的に分離された環境を提供します。 カスタムIPアドレス範囲 : 自分で定義したIPアドレス範囲を使用できます。 ファイアウォールルール : ネットワークトラフィックを制御するためのルールを設定できます。 プライベート接続 : インターネットを経由せずにGoogleのサービスに接続できます。 VPNやCloud Interconnectとの連携 : オンプレミス環境との安全な接続が可能です。 今回のケースでは、Cloud RunからRedisへの接続をインターネットを経由せずに安全に行うためにVPCを使用します。これにより、セッション情報を複数のCloud Runインスタンス間で共有し、水平スケーリングを実現します。 VPCの作成 今回はVPCをカスタムモードで作成します。 作成されるVPC名は、PROJECT_IDと同じになります。 gcloud compute networks create ${PROJECT_ID} \ --subnet-mode=custom VPCの削除 サブネットが作成されているとエラーになります。 gcloud compute networks delete ${PROJECT_ID} サブネットの作成 VPCにサブネットを作成します。 Cloud RunとVPCの間をDirect VPC Egressで接続するため、少し広め(24ではなく16)のサブネットを作成します。 gcloud compute networks subnets create ${PROJECT_ID}-open-webui \ --network=${PROJECT_ID} \ --region=${REGION} \ --range=10.0.0.0/16 \ --enable-private-ip-google-access サブネットの削除 gcloud compute networks subnets delete ${PROJECT_ID}-open-webui \ --region=${REGION} Redis Redisとは? Redisは、高性能なインメモリデータストア・キャッシュシステムです。主な特徴と利点は以下の通りです。 高速なパフォーマンス : データをメモリ上に保持するため、非常に高速なレスポンスが可能です。 多様なデータ構造 : 文字列、ハッシュ、リスト、セット、ソート済みセットなど、様々なデータ構造をサポートしています。 永続化機能 : データをディスクに保存することで、再起動時にもデータを復元できます。 パブリッシュ/サブスクライブ : メッセージングシステムとしても利用可能です。 分散システムのサポート : 複数のインスタンスでデータを共有できます。 今回のOpen WebUI環境では、Redisを以下の目的で使用します。 セッション管理 : ユーザーセッション情報を保存し、複数のCloud Runインスタンス間で共有します。 WebSocketサポート : リアルタイム通信のためのWebSocket接続を管理します。 SearXNG検索エンジン : 検索結果のキャッシュやレート制限の管理に使用します。 これにより、Open WebUIを水平スケーリング可能な構成で運用することができます。 Redisインスタンスの作成 Redisインスタンスを作成します。 その際、Redisと先ほど作成したVPCを接続します。 Redisのスペックは利用環境に合わせて適宜変更してください。 Redisの作成は他のリソース作成より時間がかかります。 gcloud redis instances create open-webui \ --region=${REGION} \ --tier=basic \ --size=1 \ --redis-version=redis_7_0 \ --connect-mode=DIRECT_PEERING \ --network=${PROJECT_ID} Redisインスタンスの削除 gcloud redis instances delete open-webui \ --region=${REGION} Redisの接続先設定確認 Redisの接続先設定を確認します。 gcloud redis instances describe open-webui \ --region=${REGION} \ --format="value(host)" firwall Cloud RunからMemorystore for RedisにアクセスするためのFirewallルールを作成します。Open WebUIのサービスにはredisというタグがついているため、このタグを使ってFirewallルールを作成します。 gcloud compute firewall-rules create allow-redis-traffic \ --direction=INGRESS \ --priority=1000 \ --network=${PROJECT_ID} \ --action=ALLOW \ --rules=tcp:6379 \ --source-tags=redis 作成したFirewallルールの確認 gcloud compute firewall-rules list --filter="network=${PROJECT_ID}" スケール用open-webui.template.yamlの作成 以下のコマンドで、open-webui-redis.template.yamlを作成します。 cat << 'EOF' >| open-webui-redis.template.yaml apiVersion: serving.knative.dev/v1 kind: Service metadata: name: open-webui annotations: run.googleapis.com/ingress: internal-and-cloud-load-balancing run.googleapis.com/ingress-status: internal-and-cloud-load-balancing spec: template: metadata: annotations: autoscaling.knative.dev/minScale: '0' autoscaling.knative.dev/maxScale: '2' run.googleapis.com/vpc-access-egress: private-ranges-only run.googleapis.com/network-interfaces: '[{"network":"${PROJECT_ID}","subnetwork":"${PROJECT_ID}-open-webui","tags":["redis"]}]' run.googleapis.com/cloudsql-instances: ${PROJECT_ID}:${LOCATION}:open-webui spec: containerConcurrency: 40 timeoutSeconds: 600 serviceAccountName: open-webui@${PROJECT_ID}.iam.gserviceaccount.com containers: - name: open-webui image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/ghcr/open-webui/open-webui@sha256:9b7fb388f0828b597e67c263667214c93592cbc5cac3047be89f5e92bc1085ba ports: - name: http1 containerPort: 8081 env: - name: DEFAULT_USER_ROLE value: user - name: ENABLE_LOGIN_FORM value: 'True' - name: STORAGE_PROVIDER value: gcs - name: GCS_BUCKET_NAME value: ${OPENWEBUI_BUCKET_NAME} - name: ENABLE_OAUTH_SIGNUP value: 'True' - name: OPENID_PROVIDER_URL value: https://accounts.google.com/.well-known/openid-configuration - name: ENABLE_OAUTH_GOOGLE value: 'True' - name: GOOGLE_REDIRECT_URI value: https://${OPEN_WEBUI_DOMAIN}/oauth/google/callback - name: WEBUI_URL value: https://${OPEN_WEBUI_DOMAIN} - name: ENABLE_OLLAMA_API value: 'False' - name: ENABLE_EVALUATION_ARENA_MODELS value: 'False' - name: ENABLE_RAG_WEB_SEARCH value: 'True' - name: RAG_WEB_SEARCH_ENGINE value: "searxng" - name: RAG_WEB_SEARCH_RESULT_COUNT value: '3' - name: RAG_WEB_SEARCH_CONCURRENT_REQUESTS value: '10' - name: SEARXNG_QUERY_URL value: "http://localhost:8080/search?q=<query>" - name: ENABLE_WEBSOCKET_SUPPORT value: 'True' - name: WEBSOCKET_MANAGER value: redis - name: WEBSOCKET_REDIS_URL value: redis://${REDIS_HOST}:6379/0 - name: REDIS_URL value: redis://${REDIS_HOST}:6379/0 # - name: ENABLE_GOOGLE_DRIVE_INTEGRATION # value: 'True' - name: DATABASE_URL valueFrom: secretKeyRef: key: latest name: open_webui_database_url - name: OPENAI_API_KEY valueFrom: secretKeyRef: key: latest name: open_webui_openai_api_key - name: GOOGLE_CLIENT_ID valueFrom: secretKeyRef: key: latest name: open_webui_oauth_client_id - name: GOOGLE_CLIENT_SECRET valueFrom: secretKeyRef: key: latest name: open_webui_oauth_client_secret # - name: GOOGLE_DRIVE_CLIENT_ID # valueFrom: # secretKeyRef: # key: latest # name: open_webui_google_drive_client_id # - name: GOOGLE_DRIVE_API_KEY # valueFrom: # secretKeyRef: # key: latest # name: open_webui_google_drive_api_key # - name: ANTHROPIC_API_KEY # valueFrom: # secretKeyRef: # key: latest # name: open_webui_anthropic_api_key resources: limits: cpu: 2000m memory: 2.0Gi startupProbe: httpGet: path: / port: 8081 initialDelaySeconds: 10 periodSeconds: 3 failureThreshold: 30 - name: searxng image: searxng/searxng@sha256:662971a55feacea2eacd2a8a2f51b3e26b56a73080dd131d079d15d7b991faed env: - name: SEARXNG_HOSTNAME value: 'localhost:8080' - name: SEARXNG_PORT value: '8080' - name: SEARXNG_BIND_ADDRESS value: '0.0.0.0' - name: SEARXNG_STATIC_USE_HASH value: 'true' - name: SEARXNG_LIMITER value: 'false' - name: SEARXNG_IMAGE_PROXY value: 'true' - name: SEARXNG_REDIS_URL value: redis://${REDIS_HOST}:6379/0 resources: limits: cpu: 1000m memory: 1Gi volumeMounts: - name: searxng-config mountPath: /etc/searxng volumes: - name: searxng-config csi: driver: gcsfuse.run.googleapis.com readOnly: false volumeAttributes: bucketName: ${SEARXNG_BUCKET_NAME} EOF スケール用open-webui.yamlの作成 テンプレートファイルから新しいopen-webui.yamlを作成します。 新しいテンプレートファイルではRedisに関する情報が必要なため、環境変数にセットします。 export REDIS_HOST=$(gcloud redis instances describe open-webui --region=${REGION} --format="value(host)") 続けて新しいopen-webui.yamlを作成します。 envsubst < open-webui-redis.template.yaml >| open-webui.yaml スケール対応版Open WebUIのデプロイ 作成したopen-webui.yamlを使用してデプロイします。 gcloud run services replace open-webui.yaml --project=${PROJECT_ID} --region=${REGION} --platform=managed 以上で、スケール対応版Open WebUIのデプロイが完了です。 今回の設定では最大2インスタンスで運用するようになっています。 Open WebUIの設定 ここでは、Open WebUIの設定のうち、比較的複雑な設定を必要とする項目についてその設定方法を詳しく説明します。 Google Driveの設定 Open WebUIにはGoogle Driveからファイルをアップロードする機能があります。 APIを有効化 Google Drive APIとGoogle Picker APIを有効化します。 gcloud services enable \ drive.googleapis.com \ picker.googleapis.com Google Drive用OAuthクライアントの作成 Google Cloud ConsoleでOAuthクライアントを作成します。 基本的な手順は以前説明した OAuthクライアントの作成」 と同様です。 Google Drive用OAuth Client IDをシークレットマネージャーへ登録 OAuth Client画面から、Client IDとClient Secretを取得し、その値でシークレットを作成します。YOUR_OPEN_WEBUI_GOOGLE_DRIVE_CLIENT_ID部分を実際に利用するキーに書き換えます。 echo -n "YOUR_OPEN_WEBUI_GOOGLE_DRIVE_CLIENT_ID" | gcloud secrets create open_webui_google_drive_client_id \ --replication-policy="automatic" \ --data-file=- Google Drive用APIキーを作成 「+認証情報を作成」をクリックしてキーを作成します。 APIの制限で、「Google Picker API」と「Google Drive API」を選択しましょう。 「鍵を表示します」をクリックすることで、Google Drive用APIキーを取得できます。 Google Drive用APIキーをシークレットマネージャーへ登録 取得したAPIキーをシークレットマネージャーへ登録します。 YOUR_OPEN_WEBUI_GOOGLE_DRIVE_API_KEY部分を実際に利用するキーに書き換えます。 echo -n "YOUR_OPEN_WEBUI_GOOGLE_DRIVE_API_KEY" | gcloud secrets create open_webui_google_drive_api_key \ --replication-policy="automatic" \ --data-file=- Google Drive用データアクセス Google Drive用データアクセスを設定します。 データアクセス を参照して設定してください。 今回追加するのは drive.file drive.readonly の2つです。 open-webui.yamlの設定 open-webui.yamlの設定を変更します。 open-webui.yamlにはGoogle Driveに関する設定がコメントアウトされた状態で含まれています。コメントアウトを解除して設定します。 以下の部分のコメントを解除してください。 (略) # - name: ENABLE_GOOGLE_DRIVE_INTEGRATION # value: 'True' (略) # - name: GOOGLE_DRIVE_CLIENT_ID # valueFrom: # secretKeyRef: # key: latest # name: open_webui_google_drive_client_id # - name: GOOGLE_DRIVE_API_KEY # valueFrom: # secretKeyRef: # key: latest # name: open_webui_google_drive_api_key (略) Google Drive対応版Open WebUIのデプロイ 作成したopen-webui.yamlを使用してデプロイします。 gcloud run services replace open-webui.yaml --project=${PROJECT_ID} --region=${REGION} --platform=managed アップロード機能を使ってみる チャット入力欄の「+」からGoogle Driveを選択すると、OAuthの認可画面が表示されます。 許可を認めることで、Google Driveのファイルをアップロードすることができます。 まとめ 長文になりましたが、Open WebUIの実装について様々なパターンを紹介できたのではないでしょうか。 Cloud ArmorやIdentity-Aware Proxy(IAP)によるセキュリティ設定、VPCを活用したスケーリング対応など、Google Cloudの機能を活用することで、Open WebUIをより安全かつ安定的に運用できます。 本記事で解説したCloud ArmorやIdentity-Aware Proxy(IAP)は導入が比較的容易で、高い効果を発揮します。これらの知識は他のシステムにも応用可能です。 また、今回は詳しく触れませんでしたが、Cloud RunにはGPUコンテナオプション(一部リージョンのみのベータ機能)があります。このGPUを活用することで、ollamaをCloud Run内で実行し、Open WebUI上でセキュアなLLM実行環境を構築することも可能です。 Cloud Runは様々なアプリケーションの実行基盤として活用できます。ぜひ本記事を参考に、独自のユースケースでも試してみてください。 The post 【完全ガイド】Google CloudでプライベートなChatGPT「Open WebUI」をセキュアに構築する first appeared on Sqripts .
この連載では、ソフトウェア開発のQAエンジニアとして働き始めた皆様に向けて、私の実体験をもとに「こんなことを知っておけばよかった」という、ちょっとした気づきを共有します。 一緒にソフトウェア開発のQAエンジニアとしての充実したエンジニアライフを築くためのヒントを探っていきましょう。 <QAエンジニアのスタートガイド 記事一覧> ※クリックで開きます 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう 【第7回】良い働き方を継続するためのマインドセット ソフトウェアテストを背景としたQAエンジニアはその専門性として、批判的思考を持っています。 これらのスキルがテストにおいて重要であることはいうまでもありません。 一方で、アジャイル開発の現場をはじめとするソフトウェア開発の現場では、チームワークが不可欠です。 そういった状況の中で、批判的思考の一辺倒ではうまくいかなくなることがあります。 また、テストを担うQAエンジニアは、納期や品質に対するプレッシャーから、様々な精神的な問題に直面してしまうことがあります。 これらの課題を乗り越えるには「マインドセット」が重要です。 本稿では、こういった状況を乗り越えるために、私が大切にしている「マインドセット」について解説いたします。 他者ではなく、自分を変えるという気持ち 誰かを変えたいという欲求にかられるQA QAエンジニアは品質保証のために欠陥や改善点を見つけることが求められる職種であり、常に批判的思考・視点を持つことが重要です。 こういった批判的な思考を続けるうちに、QAエンジニアは「周りの人を変えたい」「チームを変えたい」という考えにいたることがあります。 しかし、これらの欲求はほとんどの場合満たされません。 なぜなら、他者を変えるということは自分自身ではコントロールできないからです。 その結果、様々なフラストレーションを抱えてしまったり、時には対立を生む可能性があります。 こうした「誰かを変えたいという」考え方を持って苦しんでいるQAエンジニアによく出会いますし、私自身もその苦しみに悩まされることがあります。 自分ごとで捉える そこで考えていただきたいのは「自分が変わる」あるいは「自分ごとで捉える」ということです。 仮に「相手の問題がある」と思ってしまっても、一度自分自身の考え方・捉え方・思い込みによって「問題」だと捉えていないかを自問自答してみることをおすすめします。 悪感情を抱くことは、もしかしたら自分の捉え方やバイアスが原因かもしれません。 重要なことは、「自分がコントロールできる問題に変換する」ということです。 相手がどのような人であろうが、どのような行動であろうが、他者を変えることよりも自分が変わることの方がはるかに簡単なのです。 チームやプロジェクト全体の課題を考える際にも、「誰かのせいでこうなった」と捉えるのもおすすめしません。 むしろ自分自身の責任として捉えて、自分のコントロールできる範囲で、小さく対処していくことも必要になります。 こういった視点で行動することが、問題解決と自己成長につながると考えています。 これらのマインドセットのあり方について「自分の小さな「箱」から脱出する方法」という書籍が参考になります。 この本では、他者を変えようとするのではなく、自分自身の考え方や行動を変えることで、より良い人間関係を築く方法が解説されています。 自分の小さな「箱」から脱出する方法 (アービンジャー・インスティチュート 著/金森 重樹 監/冨永 星 訳/大和書房) また、NLPという考え方も自分のマインドセットを適切に保つことに役に立ちます。 NLPは独特の単語が出てきて難しい部分がありますので、「マンガでやさしくわかるNLP」といった初学者向けの書籍から入ることをおすすめします。 マンガでやさしくわかるNLP (山崎 啓支 著/サノ マリナ 作画/JMAM) チームに合わせて仕事をする 個人の仕事を充実させる 社会人、あるいはQAエンジニアとして働くなかで、効率的な働き方や個人のスキルを高めることはとても重要です。 そんな中で、例えば効率的なスケジュールの組み方を実践したくなることもあると思います。 「朝には重要な仕事をする」などです。 こういった形で自分の仕事術や仕事のやり方を確立することは生産性の向上や自己肯定感の向上に繋がります。 チームの仕事を優先する しかし、ソフトウェア開発はチームで行うということを忘れてはいけません。チームのミーティングが入ったり、作業が入ったり、様々な事情で自分の仕事術が妨げられてしまうこともあると思います。 ここで重要なのは、自分の生産性や自分のやり方だけにこだわるのでなく、チーム全体のことやチームのやり方を尊重するということです。 私自身、自分のやり方やタイムスケジュールにこだわって仕事をしていた時期もありました。 しかしながら、周りの意見に耳を傾け、建設的な議論を行い、合意形成を図ることは自分のタスクをこなすことよりもチームの利益につながることに気がつきました。 時には自分の意見ではなく チーム全体の利益を優先したり、自分の都合を変えて全体のイベントを優先することが必要です。 自分の仕事へのこだわりから脱してチームの利益のことを考えて仕事をすることは、自分自身の達成感に繋がったり、チームでしか解決できないような難しい課題を解決することができるのではないかと考えています。 尊敬と感謝を能動的に持つ 尊敬の気持ちを持つ QAエンジニアとして、様々な人と関わるのではないかと思います。 職場の同僚・上司・部下・顧客・様々なステークホルダーです。 そして、その関係するすべての人に対して、尊敬の念を持つということはとてもいいことです。 「自分はこんなに尊敬している人たちと働いてるんだ」と思いながら働くことは精神衛生上もいい効果があると実感しています。 周囲の人たちのいいところをできるだけたくさん感じ・探して・言語化し、それに対して尊敬してください。これは、エンジニアのマインドにいい影響を及ぼすと考えています。 能動的に感謝する 周りに感謝の気持ちを持つことは、自分自身のマインドにいい影響を与えると考えています。 感謝して、それを伝えることにデメリットは何もありません。 私がおすすめするプラクティスは、感謝にかかわる日記やメモを毎日書くということです。 自分が受動的に感じた「ありがとう」の気持ちを書くのもいいですが、むしろ能動的に感謝の気持ちや「ありがとう」と思った気持ちを探すということが大切です。 そしてそれを書き起こすことも重要です。 これらのプラクティスによって、毎日接する人への気持ちや心持ちが好転し、よりよいマインドセットで働けると考えています。 さいごに この記事では、QAエンジニアが直面する課題を乗り越えるためのマインドセットについて解説しました。他者を変えようとするのではなく、自分自身の考え方や行動を変えること、チーム全体の利益を優先すること、そして周囲への尊敬と感謝の気持ちを持つことが重要です。 これらのマインドセットを実践することで、QAエンジニアはより良い人間関係を築き、チームでの協働を円滑に進め、難しい課題を克服し、自己成長を達成できるでしょう。 皆様が、この記事で紹介したマインドセットを日々の業務に活かし、より充実したキャリアを築かれることを願っています。 【連載】QAエンジニアのスタートガイド 記事一覧 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう 【第7回】良い働き方を継続するためのマインドセット The post 【第7回】良い働き方を継続するためのマインドセット|QAエンジニアのスタートガイド first appeared on Sqripts .
こんにちは。まーくー&くまねこです。 ゆるっとシリーズ第8話です。 前回 から引き続き、まーくーの学び直し回です! 書籍「基本から学ぶソフトウェアテスト」 を読んで、現在でも活かせる内容があるのか?、まーくー&くまねこの会話形式でお話させていただきます。 最後まで楽しんで読んでいただければ幸いです! ゆるっと♪Blogシリーズの記事一覧はこちら(クリックで開きます) 第1話 ゆるっと♪ファームウェアテストよもやま話 第2話 ゆるっと♪学び直し!アジャイルソフトウェア開発技術者検定試験 第3話 ゆるっと♪どうやってる?探索的テストの世界! 第4話 ゆるっと♪学び直し![書籍]基本から学ぶソフトウェアテスト! 第5話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!② ~あきらめてしまわないでね 難しさ感じても~ 第6話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!➂ ~きっとそこに信じていた、バグ管理の姿があるはずさ♪~ 第7話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!④ ~君がおしえてくれたテストの名前は~ 第8話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!⑤ ~つかまえて デバイスたちの歌を~ 自己紹介 まーくー QA業界経験2x年のエンジニア。 年齢からくる(?)気力、体力の衰え、体重の増加を感じつつ、お気に入りアーティストのMCを完コピすることで奮い立たせる今日この頃。自宅から徒歩3分のところにあるチョ○○ップ入会すら躊躇ってしまう、一歩踏み出せない自分がいます・・・ くまねこ QA業界経験1x年のエンジニア。 最近のマイブームはペットボトルをどこまで縦にまっすぐ立てて飲めるかトライすること。 ノドに勢いよく流れ込む液体に身を任せ、テストの日々を泳いでいます。 イラストby くまねこ 今日も二人のやりとりをお楽しみください! 2025年も!学び直しの旅は続く… (ズッタンズズタン♪ズズタタズッタン♪)Wow! (あっ、まーくーさんだ。何やらリズムに乗ってゴキゲンだ…! どうしよう。話しかけてみようかな…) まーくーさん! おつねこです~! おつねこ! 私は最近こんな風に思っている。 ダイエットっていうのは数字にしばっ、しばられないことなんだ。そして、自分に与えられた全ての食物の中で、一体何が食べたくて、何が食べたくないのか、見分ける力を持つことが大事なんだって。 Oh…とにかく好きなものを食べようってことですか! どんな体重でもそれがベスト! 今がベスト! (まーくーさん、ちょっと嚙んでたけど…かっこいい! しびれるぅ~!) そう! ベストが毎日続けばいつでもベスト! Yeah~! \ / オゥーライ! では、今日も学びなおしていこうかぁ~ ? Yeah~! \ /(今日は書籍に関する前振りなしでいきなり始まった~!) 第8章 プリンタ(およびその他デバイス)のテスト を読んで① 前回 は7章まで進み、今回は8章ですね…。「プリンタ(およびその他デバイス)のテスト」ですって。プリンタって聞くとまーくーさんと同じ現場だった時のことを思い出します。 あっのっころっは~♪ Wow!…で、どんなことが書いてあるんだい? (今日はテンション高い&展開が早い~!)そうですね…ふむふむふむふむ。 大きく分類すると以下のような記載になっていますね。 ・デバイス構成テスト ・プリンタのテスト ・プリンタの内部処理 ・プリンタのテスト戦略 ・プリンタのテスト項目 ・テスト自動化のヒント なので、この中からプリンタにしばっ、しばられない項目から汎用的に学べそうな部分をピックアップしていくと良いと思います。(意図的に噛んでみたけど…気づくかなぁ?) そうだね。構成テストというくくりで言えば、私たちも行っている他端末検証とかにも応用できる知見が得られそうだね。「プリンタの内部処理」は分野が限定されすぎるから、今回は無しにしても良いかもね。ひとまず前半の2つをピックアップしてみよう。 「デバイス構成テスト」 と 「プリンタのテスト」 についてですね。Yeah~ッサー! \ /(気づかなかった~!) まずは「デバイス構成テスト」について。 ここではテスト対象を動作させる環境面のことが書かれています。テスト対象と互換性のあるプリンタの用意をするかどうか、PCのハードウェアやOSのバージョンなども記載がありますね。 なるほど。テストの大前提ではあるけど、テストを行うための環境の洗い出しやバージョン情報などは最初にしっかりと確認し、ステークホルダーと合意して進めていけるようにしたいね。 本文にもあるけど構成の組み合わせは「ブラックホール」のように多様なデバイスを飲み込んでしまって複雑になりすぎたり、せっかくテストが順調に進んでいたのに、実はテスト対象プログラムのバージョンが違ってました…とかだと目も当てられないしね。 ですよね…そこまで大きなロスをしたことはないですが、プロジェクト終盤で判明してしまった時のことを考えるといろいろな意味で背筋が凍りますね。((( ))) 続きまして、「プリンタのテスト」について。本書発行当時はプリンタは1000種類以上あり、その中からプリンタと連携するPC(OS)のシェア、プリンタのシェアなどを考慮して動作保証範囲を検討する必要がある旨が書かれています。 当時はそれぐらいの種類だったんだね。現在はプリンタの種類もそうだけど機能も高度化しているから、その辺も考慮に入れてデバイス構成を検討すると良いと思う。もっとも当時よりデバイス間の互換性が保たれていることも多いだろうから、思ったよりうまく整理できるかもしれないね。 第8章 プリンタ(およびその他デバイス)のテスト を読んで② では8章の後半も進めていこう。「プリンタのテスト戦略」について。ここは私が… 「テスト戦略」として大切なことは一般的なところから特殊なところへ進めていく、というところが参考になると思う。色々な種類のプリンタがある中で、ひとつ目の機種ではプリンタに依存しない不具合を見つけ、次のプリンタではプリンタとして共通の不具合を見つけていく…というところ。これを行うことで同じテストをプリンタ種類毎に全て実施しなくても良くなるから良いよね。 そうですね。この考え方はプリンタやデバイスのテストだけでなく、アプリのテストでも活用できそうです。まーくーさんはテストを進めていく上でのアイデアって他にどのようなものがあると思いますか? 戦略と言うほど大がかりなことではないけど…(目を細めながら遠くを見つめる)、 派生開発とかならテスト実行の順番を考えるとき、過去の傾向から不具合が多かった機能や、プログラムの修正に時間がかかった不具合を検出した機能から先にテストを進められるようにスケジュールするかな。そうすれば不具合が発生しても早めに対処することが可能となって、終盤に重大不具合が発生してアップアップするなんて事態を回避できるよね。 なるほど。テストチームだけでなく、開発チームの作業負荷も考慮して進めることができれば、より効率よく安心してプロジェクト終了へ進めていくことができますね! 次は「テスト項目」についてだけど…現在では一般的になっている内容かと思うので今回は割愛させてもらおうかな。 了解しました ゞそしたら最後は「テスト自動化のヒント」ですね。自動化っていうと今でもテーマとしては重要かと思います。ふむふむふむふむ。やはり当時から以下のようなポイントで語られていますね。 (プリンタテストの自動化に関する四つのリスク※要約) ・すべてを自動化しようとしないこと ・合否判定が正しくできない項目は実施しないこと ・印刷に関連するバグを見逃さないように注意すること ・同じ自動テストだけを実施し続けないこと なるほど。ここでも自動化する前にどういった範囲を自動化していくのか、ツールの特性でできること/できないことも調査しながら適切に自動化ができるようにしていきたいところだよね。 はい。合否判定のところも、もし実際の印刷まで自動化するのであれば出力された紙の目視確認も必要になると思います。その際、どの自動化テストケースで印刷したのかわかるようなデータ作成をする必要もありますね。他にも紙出力ではなくファイル出力したデータと期待値ファイルと比較して合否判定するっていうのも良いですよね! うん。あと4つ目の同じ自動テストを続けないこと、のところはまさに殺虫剤のパラドックスと同じだね。既存の動作に問題ないことを確認するのは良いけれど、テスト対象の成熟度に応じて自動テストの量や内容も臨機応変に対応していかないといけないよね。 変化を恐れず常に前を向いて前進する、まーくーさんのようにですね! 最初はトライ&エラーの時間が少なからず発生すると思うけど、「テスト自動化のヒント」で学べることを活かせば自動化の成功率向上と安定した運用ができそうだね。 トライ! トライ! トライ! Yeah~! We can do it! \ / まとめ 第8章はこれぐらいかな。 次回のまーくー&くまねこは、 まーくー: JSTQB ALTM試験、うっかり受かっちった! 次はTA? (仮) くまねこ: JSTQB ALTM試験、ではないものを受け、あと1問で x 2 (苦) の2本でーす! 最後まで読んで頂き、ありがとうございました! よろしければ、過去のゆるっと♪シリーズもお楽しみください! 次回もまた見てねー ノシ 三 ノシ 三 ゆるっと♪シリーズ 第1話 ゆるっと♪ファームウェアテストよもやま話 第2話 ゆるっと♪学び直し!アジャイルソフトウェア開発技術者検定試験 第3話 ゆるっと♪どうやってる?探索的テストの世界! 第4話 ゆるっと♪学び直し! [書籍]基本から学ぶソフトウェアテスト! 第5話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!② ~あきらめてしまわないでね 難しさ感じても~ 第6話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!➂ ~きっとそこに信じていた、バグ管理の姿があるはずさ♪~ 第7話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!④ ~君がおしえてくれたテストの名前は~ 第8話 ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!⑤ ~つかまえて デバイスたちの歌を~ The post ゆるっと♪学び直し![書籍] 基本から学ぶソフトウェアテスト!⑤~つかまえて デバイスたちの歌を~ first appeared on Sqripts .
みなさんこんにちは。 「ソフトウェアレビューをエンジニアリングっぽく捉える会」の”きたのしろくま”です。 前回 に引き続き、「#5レビューの終わり方~レビュー評価・ふりかえり(2/2)」をお伝えします。 【第3回】[#5]レビューの終わり方~レビュー評価・ふりかえり(1/2)|ソフトウェアレビューをエンジ... みなさんこんにちは。「ソフトウェアレビューをエンジニアリングっぽく捉える会」の”きたのしろくま”です。次の話題は「#5レビューの終わり方~レビュー評価・ふりかえり」です。前回うれっしーさんが書いてくれた「#1レビューとは?」の次に#5・・・かなり飛んだテ... 続きを読む Sqripts <ソフトウェアレビューをエンジニアリングっぽく語ってみる 記事一覧> ※クリックで開きます 【第1回】[#0]イントロダクション 【第2回】[#1]レビューとは? 【第3回】[#5]レビューの終わり方~レビュー評価・ふりかえり(1/2) 打開策2:レビュー指摘事項の分類/評価の実施 打開策1と同様、レビュー終了直後に、レビューにより検出された指摘事項をいくつかの視点で分類し、評価します。 分類/評価の方法にはいろいろありますが、ここでは2つの事例(視点)を紹介します。 1つ目の視点は、このフェーズで作り込まれた欠陥・不備なのか、他のフェーズで作り込まれたものなのかの分類です。理想的なのは、このフェーズで作り込まれた欠陥・不備を同じフェーズのレビューで見つけ出すことです。(図2の上)これが実現できなければ、プロジェクトが混乱する原因となってしまいます。(図2の下) よって、他のフェーズで作り込まれた欠陥・不備があれば、作り込まれたフェーズのレビューを見直す必要があることに気づきます。 図2:フェーズで作りこんだ欠陥・不備をどこで見つけるか? 2つ目の視点は、レビュー目的の達成度と指摘事項の効果です。 レビューの“効果”を何で示すのかについてもいろいろ考えられますが、今回はその一例として「仮に今回のレビューでこの欠陥・不備を見逃した場合、あとでどの程度悪い影響が出るものかの度合い」をご紹介します。 あとになって発生する悪い影響を正確に把握することはできない場合も多いので、下記のように進めます。 少なくとも自分たちの開発の進め方から想定すると、この欠陥・不備はこの先どのフェーズで見つかる可能性が高いか、見つかった時の対処にどのくらい期間、工数を費やして対処することになるのかを(ザックリでもOK)見積もります。その際にプランニングポーカーを使うなどの工夫が可能です。 見積結果を活用して3つの枠:効果大、効果中、効果小に割り振ってマッピングします。 さらに、それぞれの指摘事項がどのような観点にあたるのか?を明らかにして、効果大中小の観点分布を把握します。(以上、図3) 図3:レビュー指摘事項の分類/評価の流れ(例) 以上の結果を見ながら、どの観点の指摘事項がどの程度見つかったのか?や、効果大・中・小の指摘数、観点の偏りはないか?、今回のレビュー目的は達成できたといえるのか?、レビューにおける費用対効果はいかほどか?、等を分析、評価します。(図4) 図4:レビュー指摘事項評価の観点例 最初は効果大、中、小をどのように分けたらよいのか、それぞれの指摘事項がどのような観点(意味がある)と言えるのか、などメンバーの認識が合わずに難航するかもしれませんが、議論を重ねて一度出来上がるとそれを再利用しながら短い時間で分類/評価を進められるようになります。 完成したレビュー指摘の効果分類図に表現された内容が、対象となるソフトウェアの品質に対するチームの価値観を表すことになります。これがマネジメント、開発メンバー、QAメンバーの共通の価値観になり、あらゆるタスクを進める上で注視して開発を進められるようになっていきます。それがさまざまな役割のメンバーが相互に協力して同じ目的達成を目指すうえで協調関係を築く土台になります。 ここで間違ってほしくないのは、完成した図が大事なだけではなく、それを創りあげる過程=チームメンバーによる対話や議論がなにより重要である点です。そして、一度完成したら終わりではなく、さまざまなレビューやテストの結果を同様に分類/評価しながら何度も見直し、更新していくことが本質である点です。 なお、この打開策2は 打開策1:「レビューふりかえり」 の前に実施し、その結果を踏まえてふりかえることをおススメします。 この組合せにすることで、レビューの実施過程+実施結果の両面を解像度高くふりかえることが可能になるため効果的です。 おわりに ~忙しくてそんなことしている時間はないよ、と言っていた当時の私に 以上の提案をすると「レビュー終了直後に指摘事項を分類/評価したり、ふりかえりを実施するなんて、、、忙しいからそんな時間はないよ。」という声をよく聞きます。 私も当時はそう思っていた一人なので、この先は当時の私に伝える/問いかける内容です。 当時のしろくまさんへ どうしてそんなに毎日忙しいのか、現状で自分が何にどのくらい時間を割かれているのかちゃんと把握しているかな?例えば、計画された作業を実施したものの、あとで仕損じていたことがわかり、作業をやり直したり、成果物を手直ししたりする工数って作業全体の中にどのくらいあるんだろう? それを把握することも大事なふりかえりの一種なんだけど、それも忙しいからできないって言うかもしれないね。 自分(たち)の作業や成果物をふりかえって、仕事の仕方をもっとより良く変えない、良くないところを直さないから、いつまで経っても仕損じて手戻り(再作業や非効率状態)が減らず、その結果忙しさが解消されない、さらに忙しいのを言い訳に本当に必要な作業を端折ったりしてまた手戻りを増やしている、なんてことはないかな? 実は、忙しいからふりかえりなんてできない、のではなく、ふりかえらないから忙しくなってしまう、ということなんじゃないのかな? 「忙しい」が結局は現状維持・現状肯定のための言い訳にならないように、そして意図せず自らの成長を阻害することにならないように、しろくまさんの今後の健闘を祈ります。疑問点などあれば遠慮なく教えてね。他者のせいにしていても解決しないからさ。一緒によりよい世界を自ら創り上げていこう! この記事を担当したメンバー きたのしろくま(安達 賢二/ @kitanosirokuma ) 自律・自己組織化を促進する価値共創プログラムSaPIDをベースに三方よしとなる新しい価値を一緒に考えて創る「共創ファシリテーター」として活動中。 https://www.softwarequasol.com/ 【連載】ソフトウェアレビューをエンジニアリングっぽく語ってみる|記事一覧 【第1回】[#0]イントロダクション 【第2回】[#1]レビューとは? 【第3回】[#5]レビューの終わり方~レビュー評価・ふりかえり(1/2) The post 【第4回】[#5]レビューの終わり方~レビュー評価・ふりかえり(2/2)|ソフトウェアレビューをエンジニアリングっぽく語ってみる first appeared on Sqripts .
こんにちは。執筆者のおすしです。 ChatGPTが世にリリースされてから、私には続けてきた趣味があります。 変わった料理のレシピをAIに提案してもらい、作って食べてみること です。 数あるおかしなレシピの中からおいしかった3つを紹介します。 ルール 次のような単語を入れてAIにレシピ作成を依頼する。 「奇抜な」「前衛的な」「いまだかつてない」「狂った」 無難なレシピを提案してきたら、「より奇抜なものをお願いします」のように指示してやり直してもらう。 提案したレシピ名や材料の組み合わせを検索して、同じレシピがヒットしなかったらOK。ヒットしたら手順2を繰り返す。 食べても安全かチェックしてから作成に入る。 AIは食品以外を材料にしたり、危険な食べ方を提案してしまうことがあります。必ず安全を確かめてください。 残さず食べる。 レシピ①「かんぴょうと餃子のカルパッチョ」 AIとのやり取り まずは普通に依頼した場合の結果です。しけてきたかんぴょうの残りを使い切りたかったので、必ず使ってほしいと依頼します。 無難なレシピを提案されました。「前衛的な」を指示に入れてみます。 「かんぴょう 餃子 カルパッチョ」で検索しましたが、似たような料理はヒットしませんでした。 ※2025年現在は「餃子のカルパッチョ」というレシピがヒットします。 レシピ 【かんぴょうと餃子のカルパッチョ】 【材料】 餃子 6個 白菜 4枚 かんぴょう 20g ベーコン 2枚 スプラウト 適量 レモン 1/2個 オリーブオイル 大さじ2 塩、胡椒 適量 【作り方】 餃子を沸騰した湯で1分程茹でます。 冷水で餃子を冷やし、食べやすい大きさに切ります。 白菜を塩茹でし、水に取っておきます。 かんぴょうを水で戻して、茹でます。 ベーコンをフライパンでカリカリに焼きます。 レモンの汁、オリーブオイル、塩、胡椒を混ぜ合わせ、ドレッシングを作ります。 盛り付け皿に3と2を乗せ、5と4を添えます。 ドレッシングをかけ、スプラウトを散らして完成です。 和のかんぴょうと洋のカルパッチョが融合した、前衛的な一品となります。おしゃれなパーティーやディナーにもぴったりです。 作成 ゆでた餃子を冷水で冷やすのか…と驚きながら調理しました。 餃子は切らない方が見栄えが良いので作り方の手順2の後半は無視します。「おしゃれなパーティーやディナーにもぴったりです」とあるのでおしゃれに盛りつけます。しかし、白菜を下に敷くと餃子が転がって盛り付けが難しい。白菜はお浸しとして食べてしまいました。時にはレシピを無視するのも楽しく続けるコツです。 実食 とてもおしゃれな見た目です。確かにパーティにぴったりかもしれません。 おいしくいただきました。 冷やした餃子の皮のもちもち感、添えたかんぴょうの歯ごたえ、上に載ったベーコンのカリカリ感。面白い食感でした。上に散らかしたスプラウト(カイワレ大根)の辛味がアクセントになって、食べ続けても飽きません。レモンのおかげで後味もさわやかでした。お酒のつまみにぴったりだと思いました。 この料理がおいしかったとAIに伝えました。かんぴょうが好きだとインプットされたらしく、しばらく提案するレシピにかんぴょうが入るようになりました。 レシピ②「うどんティラミス」 AIとのやり取り 「うどん ティラミス」で検索するとうどんのティラミス風がヒットしました。しかしながら、作り方や材料を比較すると全く違う料理のようです。やや驚きに欠ける気もしますが、同じものはないのでOKとします。 レシピ 「うどんティラミス」 うどんをデザートに大胆にアレンジし、ティラミス風に仕上げた一品です。もちもちのうどんが、意外とマスカルポーネとコーヒー風味に合います! 【材料】 うどん(冷凍うどんを推奨):1玉 マスカルポーネチーズ:100g 生クリーム:100ml 砂糖:大さじ2 インスタントコーヒー:小さじ1(湯大さじ2で溶かして冷ましておく) ココアパウダー:適量 【作り方】 冷凍うどんを茹でて冷水でしっかり締め、水気を切ります。1~2cmほどの長さに切り、ティラミスのスポンジ部分の代わりにします。 ボウルにマスカルポーネチーズと砂糖を入れて混ぜ、生クリームを加え、ふわっとするまで泡立ててクリームを作ります。 切ったうどんをコーヒー液にさっとくぐらせ、グラスや容器に敷き詰めます。 3の上にマスカルポーネクリームを重ね、再度コーヒーにくぐらせたうどんを敷き詰めて、もう一層クリームをのせます。 最後にココアパウダーをふりかけ、冷蔵庫で1時間ほど冷やして完成です。 うどんのもちもち食感がティラミスのクリーミーさと相まって、新しいスイーツの食感と風味が楽しめます。まさかうどんがデザートになるとは思わない驚きの一品です。ぜひ話のネタに試してみてください! 作成 うどんという中身の詰まったものをスポンジ部分の代わりにするのですね。「ティラミスのクリーミーさ」とあるけどスポンジ部分も含めてティラミスなのでは?ティラミスってどういう意味なんでしょう。ちょうど開いていたGoogleのAI(Gemini)に聞いてみます。 【語源】Tira(引っ張る、mi(私、 su(上に。 「私を上に引っ張り上げて」が転じて「私を元気づけて」という意味になりました。 また、「私を天国に連れて行って」という意味もあります。 強烈な味で天に召されるのかもしれない。材料からそこまでおかしな味にならないとは思いますが…。 実食 上から見ると完全にティラミスです。 横から見るとうどんが…。クリームにうどん。複雑な気持ちになりますが、目を閉じて食べてみます。 意外にもおいしくいただきました。 うどんの弾力が大福などのモチ系のお菓子と似ています。食べ始めはうどんが甘いことに違和感がありましたが、慣れたらおいしく感じます。うどんって甘い味も合うんですね。 レシピ③「鹿胸肉のカーボン化ロースト ブラックダイヤモンド仕立て」 AIとのやり取り 鹿肉の塊が手に入りました。私の大好きな食材です。早速レシピを提案してもらいます。 鹿肉とチョコレート、ベリーソースを使ったものはすでにある料理でした。私も食べたことがあります。奇抜さが足りないのでやり直してもらいます。 いまだかつてなく危険なにおいのする料理名とサブタイトルです。念のため「鹿肉 ロースト 炭」「鹿肉 カーボン」「鹿肉 ブラックダイヤモンド」で検索しましたが同じ料理はヒットしませんでした。 プロンプトは胸肉と書いてしまいましたが、手元にあるのは鹿の肩肉でした。気にせず調理に入ります。 レシピ 「鹿胸肉のカーボン化ロースト 〜ブラックダイヤモンド仕立て〜」 (見た目は真っ黒、食べるとジューシー!炭と科学を駆使した革新的な一皿) コンセプト 鹿肉を「完全に黒焦げ」に見せつつ、中は驚くほどジューシーで旨味たっぷり。 活性炭や黒ニンニクを使い、炭化したような見た目ながら、旨味を凝縮させる新感覚の料理。 【材料】 (2人分) 鹿胸肉(ブロック):300g 食用活性炭パウダー:大さじ1(※食品用を使用) 黒ニンニク(ペースト状にする):3片 バルサミコ酢:大さじ2 黒蜜:大さじ1 カカオパウダー(無糖):小さじ1 オリーブオイル:大さじ1 塩・黒胡椒:適量 【作り方】 漬け込み(ブラックマリネード) 黒ニンニク、バルサミコ酢、黒蜜、カカオパウダーを混ぜてペーストを作る。 鹿胸肉に塩・黒胡椒をふり、ペーストをたっぷり塗り込む。 1時間以上漬け込み、冷蔵庫で休ませる。 カーボンコーティング(完全黒化) 活性炭パウダーをふるい、マリネした鹿肉全体をまぶす。(しっかり真っ黒に!) 表面が乾燥しすぎないよう、オリーブオイルを軽く塗る。 低温調理(ジューシーに仕上げる) 120℃のオーブンでじっくり40分焼く。(中はピンクをキープ) 焼き上がったらホイルに包み、10分ほど休ませる。 仕上げ(カーボンローストの完成) 表面が完全に黒くなっているはず!だが、中はレアでジューシー。 薄くスライスし、岩塩を添えて提供。 驚きのポイント 見た目は「真っ黒の炭」、でも食べると柔らかくて旨い! 活性炭の効果で胃腸に優しく、デトックス効果もあるヘルシー料理! 黒ニンニク&バルサミコの甘酸っぱさが鹿肉の旨味を爆発させる! 作成 AIのモデルが変わったのでしょうか。以前よりも絵文字と「!」が多く「驚きのポイント」も炎で挟むというハイテンションぶりです。やや不安になりましたが、「食用活性炭パウダー:大さじ1(※食品用を使用)」と注意書きがあります。安全性を考える冷静さは残っているようです。 鹿肉の生食は危険な場合があります。温度計で中心温度を確認してしっかり低温調理をします。味はともかく、安全性には必ず配慮しましょう。危険なものは残さず食べることができません。 食べ物と思えない黒い塊ができました。期待と不安で胸が高鳴ります。 実食 切ってみました。程よく火が通った美しいお肉が見えます。 とてもおいしくいただきました。 しっとり柔らかいお肉に、黒ニンニクとバルサミコ酢の風味がしっかり染み込んでいます。赤ワインに合いそうな味です。 炭の味がするのかな、と心配でしたが外側の炭は特に味がしません。切る前の見た目と味のギャップがおもしろい料理でした。 まとめ 今まで複数のレシピを提案してもらいましたが、プロンプトに入れる形容詞や副詞によって傾向があるようです。 「驚くような」「奇抜な」:既存のレシピで、ちょっと変わっているなと感じるものが多いです。(例:お肉にチョコレートソースなど) 「前衛的な」:既存のレシピを食材の変更でアレンジする傾向があります。また、比較的おしゃれなレシピが多いです。 「いまだかつてない」:調理法から変わったものが多いです。 「激しい」「狂った」:調理法は普通ですが、量、色、味で狂気を表現するものが多いです。(例:大量の食材を積み上げる、真っ赤にする、大量の唐辛子で激辛にするなど。)また、レシピの説明で中二病のような表現を使うようになります。 毎日の献立に悩んだり、同じご飯が続いて飽きることがあると思います。上記のような言葉を入れて、ちょっと変わったレシピをAIに提案してもらうのはいかがでしょうか。 作成の際はレシピの安全確認を忘れないように気を付けてください! The post AIに前衛的な料理のレシピを提案してもらった(写真と実食あり!) first appeared on Sqripts .
みなさんこんにちは。 「ソフトウェアレビューをエンジニアリングっぽく捉える会」 の”きたのしろくま”です。 次の話題は「#5レビューの終わり方~レビュー評価・ふりかえり」です。 前回うれっしーさんが書いてくれた「 #1レビューとは? 」の次に#5・・・かなり飛んだテーマではありますが、 準備できた順に投稿していくと宣言 して始めた連載ですのでご容赦ください。 (すべてのテーマ投稿が出揃った際にこの連載の価値がわかるはず・・・です) 今回のテーマは少し長くなりますので2回に分けてお伝えします。 今回は「#5レビューの終わり方~レビュー評価・ふりかえり(1/2)」です。 レビューのよりよい終わり方を一緒に考える機会になるとうれしいです。ではスタートです! <ソフトウェアレビューをエンジニアリングっぽく語ってみる 記事一覧> ※クリックで開きます 【第1回】[#0]イントロダクション 【第2回】[#1]レビューとは? レビューってどうしたら終わる? みなさんのレビューはどうなれば終了しますか? 例えば、 ・予定していた時間が来たら終了~まだ途中だけど、残りの内容でこれまでの指摘と同様の箇所があれば同じように直しておいてね(ハート) ・レビューアから指摘事項が出揃ったら/それを作成者に伝えたら終了 ・声の大きな人が「終わり」と言ったら終了 ・正式なレビュー記録が承認されたら終了(QMS的) など、いろいろありそうです。 これは「レビューの終了基準」の話題ですが、(「開始基準」と同様)特に決まりがないまま、いや「慣習になっている暗黙のやり方」に従って運営している、という状態が意外と多い気がしています。 ”やりっぱなしレビュー”の影響 先ほど示した4例ですが、どれをとっても「レビュー計画」や「レビューの実施方法」「レビュー結果」の良し悪しをふりかえらず、集まった人たちでレビュー指摘さえ出せば、あるいはそれを申し渡したら終わり、という状態になっている可能性があります。 この状態を「やりっぱなしレビュー」と呼ぶことにします。 やりっぱなしレビューがもたらす主な影響は以下の通りです。 ・レビューに費やす工数や時間が最小限で済むので、実務に早めに戻ることができる。(これは良い影響) ・レビューで新たな経験や気づきを獲得した特定の個人にのみ、その分の学習効果が得られる。 しかし、あくまでも個人の話であり、かつレビュー能力の向上は非常に小さく、組織としてのレビュー能力向上には長い年月が必要になる。 ※有識者がいないとレビュー結果が伴わない状態はこのように作られる ・(一度のレビューで各自が獲得するノウハウはそう多くはないため)次回以降のレビューでも同じような結果になることを繰り返す可能性が高い。 例1:検出すべき欠陥や不備を見逃しがちなレビューになっているチームは、以降も同様に見逃す結果になりやすい。 例2:集合レビュー時に話題が横道に逸れてもそのまま放置される(ムダな時間、工数が多くなる)運営になっているチームは、以降も同じ状態になりやすい。 以上のように、メリットよりもデメリットが目立つのが実態だと思います。 さらに、業務やプロジェクトのメンバーは、自分が割り当てられているタスクを遅延なく進めることでさえも簡単ではなく、多忙な中で依頼されたレビューを何とかして行っている場合も多いと推察します。 多忙な中、何とかやりくりしてレビューを実施しているのに、その効果が実感できないと、レビューに対するモチベーションが低下し、前向きにレビューが実施できなくなってしまいます。 このような「やりっぱなしレビューの悪影響や負の連鎖」はどのように打開すればよいでしょうか? 打開策1:レビュー実施直後のふりかえり実践 レビューを実施した直後に今回のレビュー全般をふりかえり、次(今後)のレビューでどのように進めるとより良い結果が出せるのかを明確にするのが打開策の一つ目です。 ふりかえりを実施するときの大事なポイントの一つは「ふりかえりの対象活動を小さくする」そして「終了直後に実施する」ことです。 小さい活動の終了直後にふりかえりを実施することで、対象活動(今回はレビュー)で発生した「継続すべきよい事項」や「見直すべき事項」が記憶のかなたに消えてしまうリスクを軽減し、何が起きたのか、その結果どうなったのかを思い出すための余計な時間を最小化します。(図1-【B】) よく、プロジェクト終了後にプロジェクトふりかえりを実施しているケースを目にしますが、数か月~数年の期間で運営してきた内容を一度に一気に思い出すことを暗に求めることになります。1日経過すると7割程度の記憶がなくなる、数日前の食事の内容ですら思い出すのに苦労するのが人間ですから、数か月前、半年前の記憶はほんのささやかな断片でしかありません。必要なことをしっかり思い出して共有するには余計な時間と手間をかける必要がありますが、それでも実際には思い出せずに終わることのほうが多くなります。 この方法だと、時間も工数も大きくなる割に効果的な結果が得られる可能性はとても低くなってしまいます。(図1-【A】) レビュー実施直後にふりかえりを行うことで、短い時間と工数で次(以降)のレビューで実践すべき事項を確実に導出することができるわけです。 さらに慣れてくると、ふりかえり時に各自がふりかえって結果を書き出す(そのために時間をかける)のではなく、レビュー計画立案や準備、各自のレビュー実施、集合レビュー時などの各段階で気づいたことや見直すべき事項(ふりかえり結果)を共有場所に書きだしながら進めることができるようになります。その結果、ふりかえり時にはすでに書き出された各自の結果を確認・共有するところからスタートするため、ふりかえりにかかる時間・工数が小さくできます。これを、リアルタイムふりかえり、と呼んでいます。(図1-【C】) 図1:ふりかえり実施形態と費用対効果 個人的な経験則ですが、この形式で運営できるようになると、ふりかえりにかかる時間は最短で5分程度、長くても15分程度で済み、次のレビューで実践する具体的な内容を確定することができます。 ふりかえりを実施するときのもう一つの大事なポイントは「関係者で観点を共有して実施する」ことです。 ソフトウェアレビューは一般的に“成果物”に対するレビューですが、ふりかえりは“活動”を対象としたレビューです。 突然「何かあれば指摘してください」と言われると、何となくぼんやり実施することになり、必要な結果が得られる可能性が低くなってしまいます。 関係者が今回のレビュー計画~終了までに体験したことの中には、磨けば光る財宝級の情報が含まれていることがあります。それをしっかり抽出・言語化するために「観点」を活用します。 下記はレビューふりかえりの観点例です。 [全体共通] ナイスプレー(自薦他薦問わず)、個人的に獲得した気づき、あとから準備不足や仕損じが判明したこと、など [レビュープランと準備] レビュー目的、確認すべき観点は適切であったか レビュー目的、観点等に必要なレビューアを割り当てていたか レビュー対象成果物の難易度や重要性・規模、作業者のスキル等からふさわしいレビュータイプを選択できたか ・レビュー実施に必要なインフラ(各種様式、結果格納場所の確保と周知、集合レビュー時の会議室やオンライン会議の準備など)は遅滞なく準備できていたか [集合レビュー] 集中して建設的に議論し結論が導けたか 全員参画できたか/全員から発言・意見・コメントが提示されたか 司会のファシリテーションは適切であったか [レビュー結果] 特定の観点による確認の欠落、不足が危惧されることはないか 指摘件数や指摘内容から想定されるリスクや問題点はないか ふりかえり時に各自が観点に沿ってふりかえり結果を1件1葉で書きだし、全員で共有してまとめていきます。とある一人の気づきや考えを関係者の気づきや考えに変えられる、共有されるのがふりかえりの大事な期待効果です。ふりかえりを通じて次のレビュー時にチームとして継続して実践すること、見直して実践方法を変えることを具体化します。 なお、ふりかえり観点は固定化するモノではありません。 個別のレビューの目的やチームや関係者の習熟度、実践レベル等に応じて内容を見直す必要があります。 このように「やりっぱなしレビュー」によるいつも同じような結果しか得られない状態から、レビューを実施するたびに個々人の体験やノウハウをチームのノウハウに変えてレビューのパフォーマンスを段階的に変えていく基盤にすることができます。 ・・・ちょっと長くなりました。 まだ途中ではありますが以上で「#5レビューの終わり方~レビュー評価・ふりかえり(1/2)」は終了です。 この続きは次回「#5レビューの終わり方~レビュー評価・ふりかえり(2/2)」でお伝えします。 お楽しみに。 この記事を担当したメンバー きたのしろくま(安達 賢二/ @kitanosirokuma ) 自律・自己組織化を促進する価値共創プログラムSaPIDをベースに三方よしとなる新しい価値を一緒に考えて創る「共創ファシリテーター」として活動中。 https://www.softwarequasol.com/ 【連載】ソフトウェアレビューをエンジニアリングっぽく語ってみる|記事一覧 【第1回】[#0]イントロダクション 【第2回】[#1]レビューとは? The post 【第3回】[#5]レビューの終わり方~レビュー評価・ふりかえり(1/2)|ソフトウェアレビューをエンジニアリングっぽく語ってみる first appeared on Sqripts .
はじめまして!クオリティマネージャーの”黒山羊さん”です。 どのような業種においても、複数のチームで仕事を進めることは常に発生します。 複数人で仕事を進めるにあたり、打ち合わせやミーティングを開催して認識合わせから始まり、情報の共有、方針・内容の決定、合意に至っているのではないでしょうか。 会議の参加者はお客様、他社様、上役、チームメンバーとそれぞれ異なりますが、いずれの場合でもどのようなことを決定したかを残すために議事録を作成します。 それとは別に、議事メモというものもあります。 社内の小さな会議体の時に議事録代わりに作るというところもあると思いますが、私は議事録とは別に、会議の振り返りに役立てるため、議事メモを作成しています。 今回は、議事メモ作成のポイントを共有させてください。 議事録と議事メモの違い 議事録は会議全体の概要や決定事項等を記録するものです。 議事メモは議論の内容や議題の要点が記載され、決定事項に行き着く流れがわかるものです。 チームメンバーとの会議であれば、会議中に議事メモを表示させ、加筆修正しながら議論を進めるといった使い方もします。 議事録の内容 概要 会議の議題や論点、アジェンダを記す 決定事項 議題に対して決定したことを記す 未決事項 議題に対して決まらなかったこと、次回持ち越したことを記す 確認事項・宿題事項 次回までにやるべきことTODOとして記す この時、対応する担当と期限も記載しておく 議事メモの内容 議事メモは定められたものではなく、それぞれの組織にあわせて記載すればよいと思います。 ただ、議事録と突き合わせて会議の振り返りに使用する場合、アジェンダ毎にどのような意見や議論、質疑応答があったかを記載し、どのタイミングで決定事項と確認事項・宿題事項が出たかわかるようにすると使用しやすいです。 今の議事録事情 昨今のテレワークの普及により、オンライン会議が増えました。 オンライン会議をする際に録画をしておくことで、その録画データをもとに、生成AIが議事録を作成してくれる世の中です。 音声から文字起こしを行い、それを要約することで完成するのですが出来上がったものは要点や決定事項がしっかりまとめられており、少し手直しして議事録のフォーマットに落とし込めばそのまま使えるものになります。 生成AIで作成しなくても、録画が残っていれば後から見直して議事録と突き合わせることもできます。 議事メモ作成のポイント 議事メモは自分やチーム内で会議を振り返ったり、議事録の内容を深堀りするために使います。 個人的に議事メモに残しているポイントを連携します。 確認事項、宿題事項の記録について 確認事項や宿題事項も話の流れで誰がやいつまでにが抜けることがあります。アクションが着実に進むよう、5W1Hがわかるように心掛けるとTODOが明確になります。 確認事項、宿題事項にマークを付けておく 議事録にもTODOとして記載される事項ではありますが、議事メモであれば前後の流れも含めて確認できるので、やることのズレを少なくすることが出来ます。 マークをつけておくことで、後でメモを確認する際に見つけやすくなります。 誰の発言か書いておく 質問やその回答、依頼事項や意見などが出た場合は誰の発言かわかるようにしておきましょう。それによって、発言の意図を確認することに役立ちます。 資料のページ数を書いておく 資料の説明中に質問が出た場合、ページ数も添えておきます。 振り返りの際、資料を突き合わせやすくするため、役立ちます。 時間をメモる これは録画データを確認するときに重宝します。基本議事メモは時系列に記載しているので、前から順に追っていけば該当箇所にたどり着けますが、意見が出たタイミングの時間を書いてあれば、直接アクセスすることが出来ます。 資料とは違う意見は残しておく 資料が間違っていて訂正しているのであれば、後で修正した資料を連携してもらえばいいのですが、報告最中に補足説明や懸念事項が挟まれた場合は残すようにしています。 やっかいなのが、例えば技術者から報告の最中に出てきた懸念事項。ちょっと気になっている・引っかかっている箇所がある。課題にはしたくないけど報告はしておきたい。そういった理由で会議の中の報告の最中に混ぜてくることはあります。(私自身も技術者だった頃、チーム内ミーティングでやりました) そういったものが会議でスルーされると議事録から外れてしまうこともあるので、議事メモには残しておきましょう。 おわりに テレワークや生成AIと我々を取り巻く環境は日々変化していっていますが、人と人が協力して仕事を進めることに変わりはありません。 お互いの意思疎通ができ、認識齟齬が発生しないよう、よりよい会議を開催し、スムーズな決定事項が出来るような資料作成を念頭に置いて頂ければと思います。 参考書籍 コンサル一年目が学ぶこと (大石哲之 著/Dicover) こちらの記事もおすすめです QAコンサルタントの私が、文章を書く時に気を付けている事(5W1H) こんにちは、そして初めまして、QAコンサルタントのsakkyです。 私達は日々、短いものから長いものまで、色々な文章を書いていますが、文章を書くのを苦手に感じたり、なんだかイマイチしゃっきりしないと感じたり、記載の過不足があるのではないかと思ったりする事... 続きを読む Sqripts 段取り八分/仕事二分のマネジメント こんにちは。クオリティマネージャーのおすぎです。「段取り八分、仕事二分」という言葉があります。仕事の事前準備の大切さを表すもので、仕事に取り掛かる前にきちんと段取りを済ましておくことで仕事の8割は完了している、という格言です。段取りはプロジェクトマ... 続きを読む Sqripts 環境構築ミスやヒューマンエラーをなくすためのノウハウ こんにちは、テスシです。私はソフトウェア開発で、システムテストに携わっています。この工程では、これまでに開発したプログラムを一つにまとめて、想定通りのものができているかどうかや本番環境でちゃんと動作するかどうかを確認しています。はじめに今回のお話... 続きを読む Sqripts The post 議事メモのすすめ first appeared on Sqripts .
帰納的な推論 と 発見的な推論(アブダクション) は、 私たちがソフトウェア開発の現場/実務で(知らず知らずにでも)駆使している思考の形です(それどころか日々の暮らしでも使っています)。 それほど“自然な”思考の形ですが、どんな考え方で、どんなところに注意すると質の高い思考ができるのか、基本知識を押さえておくと実務のレベルアップにつながります。 <実務三年目からの発見力と仮説力 記事一覧> ※クリックで開きます 【第1回】見つけるための論理【連載初回、全文公開中】 【第2回】 “共通項”を見つけ出す 【第3回】発見はよい観察とよい方法から 【第4回】帰納の仲間と落とし穴 -前編- 【第5回】帰納の仲間と落とし穴 -後編- 【第6回】 なぜ・どのようにを説明したい 今回からは、“非演繹的”なもうひとつの推論、 アブダクション の考え方を見ていきます。 今回は「仮説(説明仮説)って何?」「アブダクションって何!?」という話です。 ところで仮説って何だろう? “なぜ” “どのように”を解き明かしたい、説明したい・して欲しい 帰納的推論で一般的な傾向を見つけたり、原因と結果の関係を見つけるのに加えて、 「その条件(原因)から なぜ この事象が起こるか」「原因から結果まで、 どのようにして (どのような過程・機序で)起こるか」の説明ができれば、 推測の説得力は相当高まるでしょう。 アブダクションが考える仮説は、 このような「事象の原因を見つけたり、原因から結果に至る過程などを説明する」仮説( 説明仮説 )です。 よい仮説の性質 はじめに、当てずっぽうや思いつきの推測と一線を画す「よい仮説」が具えているべき性質を確認しておきましょう。 (参考:『論理学入門』) いくつか考えられますが、外せないのは次の4点です。 問題となっている事象や因果関係を説明できる。 直接的/間接的に 真偽を検証可能 (verifiable)である。 仮説自体でなくとも仮説がもたらす帰結などの真偽を、事実に照らして判断できる。 ( 反証可能性(偽であると検証できる) は、 誤った仮説を除外できるために重要な性質) 説明能力が同じなら、 より単純な仮説 が望ましい。 複数の仮説が考えられて、同じように不整合や破綻がなく、同じように説明できるなら、単純な仮説を採るのがよい。 少数の仮定から、整合的に説明できる仮説 が望ましい。 既に確立された知識・理解に基づいて、多くの仮定を足すことなく、系統的・体系的に説明できるのが理想的。 アブダクションとは 仮説を考える推論とその形式 19世紀から20世紀アメリカの哲学者・論理学者パースは、説明仮説の重要性と、よい仮説を考える推論( アブダクション )はどのようなものか(どうあるべきか)を研究しました。 パースによれば、アブダクションの典型的な形は次のように示されます。 (出典:『アブダクション 仮説と発見の論理』。太字は引用者による) ①驚くべき事実Cが観察される。 ②しかし もしHが真であれば、Cは当然の事柄 であろう。 ③よって、Hが真であると考えるべき理由がある。 「驚くべき事実C」とは、理由や原因を探りたくなるようなものごとや、解明が必要なものごとです。 (推理小説や推理ドラマの「不可解な事件」や、日常で「これは何だろう?」と不思議に思う出来事もそうです) このCに対して 「こう考えれば C は説明できる」と、“謎”の解消を図る のが仮説Hです(図6-1)。 図6-1 アブダクションの典型的な形・例 アブダクションの形式面での特徴 図6-1の推論の形を図式化すると図6-2のようになります。 図6-2 アブダクションの論理 図6-2の前提1と前提2の順序を入れ替えると、混合仮言三段論法の形をしています(図6-3)。 つまり、アブダクションによる推論は、見かけ上演繹的な推論っぽい形をまとっています。 図6-3 アブダクションの論理・変形 ただし、それは 後件肯定 という、演繹的な推論では誤りになる形です(図6-4。実践編「 “ならば”を使って推論する 」参照)。 図6-4 混合仮言三段論法・後件肯定の誤謬 このように、 (後件肯定という 演繹的には誤った形ではあるが )後件(事実や結果)から、その後件を導く前件(前提や原因など)を“逆向きに”考え、 「 そう考えるのが理にかなっている、もっともらしい 」という説明仮説を発案する のが、アブダクションという推論形式の特徴です。 図6-5 アブダクションの論理の特徴 ポリアの「発見的三段論法」 仮説を考える推論の、もうひとつの見方 パースとは別に、20世紀アメリカの数学者ポリアが「発見的推論」というテーマの論考を著しました。 「発見的推論」とは「帰納や類推(類比的推論)から新たな知見を引き出す推論」に与えた名称で、 パースのアブダクションに言及したものではありませんが、内容はアブダクションに通じるものがあると思われるので、 アブダクションを“側面支援”するひとつの考えとしてその一部を紹介します。 発見的三段論法 ポリアはこの種類の推論の形と意味を考察し、 演繹的な三段論法に対応づけて「発見的三段論法」と呼びました。 発見的三段論法の典型は次の例で示されます。 (参考:『いかにして問題をとくか』、『数学における発見はいかになされるか』) ①Pが正しいならば、Qも正しい。 (例:外洋の航海から陸に近づくと鳥を見かける) ②Qが正しいことが判った。 (例:今、鳥の姿が見えた) ③Pが正しいということは確からしい。 (例:多分陸が近いだろう) 「①PならばQ。②Q。③従って、Pであろう」 という形で、Pがアブダクションでいう仮説Hに相当すると見ることができます。 やはり後件肯定の形(図6-4)ですが、発見的三段論法でもこれを誤りとせず、次のように考えます。 前提Pを裏づける帰結Qが正しい事例が増えると、Pに対する信頼が増す(図6-6 上)。 (「陸が近づくと鳥を見た」事例が増えれば、「鳥が見えた」から「陸が近い」確からしさは増す) 前提Pが正しくない事例が増えると、帰結Qに対する信頼は減る(図6-6 下)。 (「陸は近くないのに鳥を見かけた」“反例”が増えれば、この推測は怪しくなる) 図6-6 発見的な推論の形と意味 なお、この「信頼が増す/減る」は、PとQとの関係性の強弱に応じて“グラデーション”(度合の違い)があります。 PでないのにQである可能性が低い場合は、Qが真の時、Pの信頼はかなり増しますが、 PでなくてもQである可能性が高い場合は、Qが真の時、Pの信頼はわずかに増すにとどまります(図6-7)。 図6-7 発見的な推論の形と意味・グラデーション版 “犯人でないのに手の込んだトリックを仕組むだろうか?” 図6-1上の「V氏殺人事件」で具体化してみましょう(図6-8)。 (なお、図6-1から捜査が進んで、②で「V氏が犯行時刻に間に合うように戻ってきたことが判明している」時点であるとします) 図6-8 発見的な推論・例 レッツアブダクション アブダクションとは、形式や意味の面から見ると、どのようなものなのか? 今回はその概要を見ました。 アブダクションもまた蓋然的な推論であり、“間違い”の可能性をはらみますが、“間違えるリスク”以上の価値をもたらし得る推論です。 説明仮説の質を高めて、原因究明の効果と効率を高めましょう。 次回は、「仮説を考える」にはどう取り組むとよいのか、どんな進め方があるかを見ていきたいと思います。 参考文献 近藤洋逸, 好並英司 『論理学入門』 岩波書店 1979 米盛裕二 『アブダクション 仮説と発見の論理』 勁草書房 2007 パース(著), 伊藤邦武(訳) 『連続性の哲学』 岩波書店 2001 ポリア(著), 柿内賢信(訳) 『いかにして問題をとくか』 丸善 1954 (1997(日本語第11版30刷)) ポリア(著), 柴垣和三雄(訳) 『数学における発見はいかになされるか 2 (発見的推論 そのパターン)』 丸善 1959 図版に使用した画像の出典 Loose Drawing 人物画をお借りしています。 品質探偵コニャン:Produced by Sqripts . No Unauthorized Reproduction. 【連載】ソフトウェアエンジニアのための論理スキル[実務三年目からの発見力と仮説力] 記事一覧 【第1回】見つけるための論理 【連載初回、全文公開中】 【第2回】 “共通項”を見つけ出す 【第3回】発見はよい観察とよい方法から 【第4回】帰納の仲間と落とし穴 -前編- 【第5回】帰納の仲間と落とし穴 -後編- 【第6回】 なぜ・どのようにを説明したい The post 【第6回】 なぜ・どのようにを説明したい|実務三年目からの発見力と仮説力 first appeared on Sqripts .
こんにちは、テストエンジニアの ナカノ です。私は以前、とあるプロジェクトで「お金に関するシステム」に関するテスト設計・実施を行う機会がありました。 「課金 = お金」 というわたしたちの日常生活に密接に関わるモノのシステムにおいて不具合が発生してしまった場合、ユーザーに対する損失は多大なる影響を与えることになります。そのため、一般的なシステムに加えて様々な状況やリスク等を考慮しながらテスト設計を行う必要があると感じました。そういった経験を基に、今回は「お金に関するシステム」においてテストで使用できるような観点を考えてみました。 ※今回ご紹介するケースはあくまで1つの事例・観点であり、全てのカバレッジを網羅するわけではありませんが、少しでも参考にしていただけたらと思います。 お金に関するシステムとは? はじめに、今回のメインテーマである 「お金に関するシステム」 についてどのようなものがあるか、一例をご紹介したいと思います。 オンライン決済システム:Eコマースや店舗での支払い等、Webシステムやアプリで決済を行うシステム 金融機関システム :金融機関(銀行・証券・保険)が利用する業務システム 資産運用システム :AI等を利用して資産運用を取り扱うシステム 仮想通貨取引システム :金融機関を介さずに仮想通貨の取引を行うためのシステム 上記で挙げたものの中では特に「オンライン決済システム」がもっとも身近に感じられるシステムなのではないでしょうか。最近はお店でのタッチ決済やネットショッピングなど、モノやサービスの購入をオンライン上で済ませることが当たり前の時代となり、またシステムの需要も増えてきました。本記事では、そういったオンライン決済システムの中でも「課金システム」や「決済」についてピックアップして、テストの観点をご紹介していきたいと思います。 汎用的なテスト観点について まずはじめに大前提として、他のシステムテストなどでも共通と言える汎用的なテスト観点を挙げてみます。 汎用的なテスト観点例) 表示 :仕様通りの文言やアイテム等が適切に表示されているかを確認する レイアウト :レイアウト崩れ等が発生せず適切に描画されているかを確認する 入力 :テキストボックスやテキストエリア等に文字列が入力できることを確認する 画面遷移 :仕様通りに各ページ等に画面遷移できるかを確認する 挙げればキリがないので他は割愛しますが、このような汎用的なテスト観点はどのようなシステムにおいても重要な確認項目となります。 数値のバリデーション観点について 次に数値のバリデーションについてご紹介します。課金システムや決済システムでは、「お金=数値」を入出力する機能が想定されるため、「バリデーション(入力値が正しい形式や範囲に合致しているか)」もとても重要な観点となります。 「数字」に関するバリデーション観点例) 小数点あり :100.1、0.1234 など 記号あり :+100、-1234 など 指数表記 :1e2 (=100)、1e12 (=1,000,000,000,000) など また、半角数字以外を入力したときの挙動を確認する観点も考慮する必要があります。 「文字」に関するバリデーション観点例) 全角数値 :12345 など 数値以外の文字種 :ひらがな・カタカナ・漢字・アルファベット・記号 など 数値の入力が可能なシステムの場合、「境界値」に不具合が潜んでいる可能性が高いため、値の有効・無効の範囲を確かめる観点も重要なポイントとなります。 「境界値」に関するバリデーション観点例) 最小値の境界値 :最小有効値の境界値、最小無効値の境界値 など 最大値の境界値 :最大有効値の境界値、最大無効値の境界値 など 境界値分析については、こちらの『 「境界値分析」をテスト設計に取り入れる 』でも紹介しているので、ご興味がある方は是非読んでみてください! 「境界値分析」をテスト設計に取り入れる こんにちは、はまたくです。前回の「同値分割法」を使ってみたに続いて、今回は「境界値分析」についてのお話をします。JSTQB FLを勉強したけど実際にテスト技法を使用したことが無い方や、現在JSTQBの勉強を進めている方々の参考になれば幸いです。境界値分析の定義... 続きを読む Sqripts 以上が数値に関する観点の一例のご紹介となります。他にもシステムの仕様や条件によって様々な要素や観点の考慮が必要なため、実際の作業では仕様やテスト条件を見逃さないように、十分注意してテスト設計を行う必要があります。 課金システム特有のテスト観点について 続いて、「課金システム」特有のテスト観点について考えてみます。課金システムでは、テスト対象となるシステムの仕様によって課金に関する各機能の実装が異なるため、本記事ではいくつかの代表的な機能をピックアップしてテスト観点をご紹介します。 クレジットカード決済 Eコマースサイト等の課金システムの場合、ほとんどの機能仕様としてクレジットカード払い、コンビニ払い、口座振替といった「決済方法」が選択できるようになっているかと思います。本記事ではその中でも決済代行システムを利用した 「クレジットカード」 について、観点を検討してみました。 対象の課金システムが決済代行システム(ECサイト等の運営と決済機関との間で第三者が決済を仲介するシステム)を利用している場合、「テスト専用のカード」を使用して架空のデータで決済処理を行ってテストすることができる場合があります(実際に決済は行われません)。通常、テスト専用のカードのデータとしては、 ①正常に決済できるカード と ②決済処理を作為的に失敗させるカード の2種類あります。さらに、①正常に決済できるカードには、「カードブランド」の種別(基本的には国際的な5ブランドなど)や「カード属性」として「デビッドカード」や「プリペイドカード」などの種類があります。一方、②決済処理を作為的に失敗させるカードには、エラーの種別として「残高不足」や「限度額オーバー」といったデータが用意されていることがあります。 クレジットカードの因子例) 決済に成功するケース : カード種別 :国際的な5ブランド、デビットカード、プリペイドカード、海外発行カード など セキュリティコード :4桁、3桁 名前の文字列長 :有効桁数最小、有効桁数中間、有効桁数最大 など 有効期限 :最短期限、中間期限、最長期限 など 決済に失敗するケース : エラー種別 :残高不足、限度額オーバー、取扱不可 など クレジットカードの条件の注記 例えば、上記記載の「決済に成功するケース」のようなパターンについては、システムの特徴やテストの規模感等を考慮したうえで、「全網羅」とするのか「水準網羅」とするのかといった、どのような条件でテストを行うのかをテスト設計段階でステークホルダーや開発側と協議して合意を形成したうえで決定する必要があります。 クレジットカードの因子例を基にした因子・水準リスト 因子・水準リストを基にした全網羅のパターン例 すべてのパターンをテストケース化する「全網羅」でテストしようとした場合、8 × 2 × 3 × 3 = 144パターンとなるため、テストケース数は大きく増加します。全パターンの組み合わせで確認できるため、ケースの抜け漏れなどは防ぐことができますが、その分テストに必要な工数が膨らむ傾向があります。 因子と水準を基にした水準網羅のパターン例 1つの水準に対して最低限1回は確認を行う「水準網羅」の場合は、「全網羅」ほどの複雑な組み合わせは確認できませんが、例えばシステムの特性として任意の組み合わせで確認できればよいといった条件の粒度感が提示されているのであれば、比較的有効となる確認方法となります。 課金方法種別と残高 課金方法種別について 課金システムにおける課金方法では、主に 「都度課金」 と 「継続課金」 が挙げられます。「都度課金」では商品やサービスの決済ごとにその都度課金する方法に対して、「継続課金」ではサブスクリプションシステムの月額使用料などに代表される設定された金額が毎月決められた日に課金される課金方法となります。各課金方法に関するテストについては、対象システムの仕様に即した各機能が動作するか(都度課金であれば決済時に毎回課金する方式となっているか、継続課金では決済時は課金せず決済日に引き落とされるか など)といった単体的な機能の確認に関するテストが有効となるでしょう。 残高について 課金システムでは、事前にチャージされているお金やポイントを 「残高」 として取り扱い、そこから決済を行う機能仕様が備わっている場合があります。残高は決済前後の状態が重要なポイントとなるため、以下のような観点を抽出すると有効な確認となるでしょう。 都度課金時の決済金額と残高の関係に着目したバリデーション例) 決済金額 < 残高(決済できるか/決済後の残高情報が適切か) 決済金額 = 残高(決済できるか/決済後の残高情報が適切か) 決済金額 > 残高 決済可能な額を追加で課金(決済できないか/決済後の残高情報が適切か) 決済のキャンセル(決済できるか/決済後の残高情報が適切か) 継続課金であっても同様に、設定された決済日に対して自動で課金額が引き落とされるシステムとなるため、決済日当日に上記観点を応用することができます。 年齢による課金額制限 システムによっては、使用するアカウントの年齢に対して課金できる金額の上限が定められている場合があるため、年齢や金額の境界値等の仕様を十分に確認し、テスト設計を行う必要があります。仕様を整理するためには、以下のようなデシジョンテーブルが有効となるでしょう。 課金額制限の仕様例) 15歳までは月額で課金できる上限金額を 5,000円 までとする 16歳から19歳までは月額で課金できる上限金額を 20,000円 までとする 20歳以上は上限金額なし とする 上記仕様を基にしたデシジョンテーブル例 デシジョンテーブルについては、『 いまさらデシジョンテーブルというものを考えてみた 』でも解説されています。こちらもご興味がある方は是非読んでいただければと思います! いまさらデシジョンテーブルというものを考えてみた こんにちは、ゆーすけです。 「V&V」「シフトレフト」に続く、いまさらシリーズの第3回です。今回は、ブラックボックステスト技法の一つである「デシジョンテーブルテスト」について考えてみたいと思います。デシジョンテーブルとは一旦、JSTQB FLシラバスでどの... 続きを読む Sqripts 決済タイミングとステータス 近年、市場はクレジットカードやスマホから決済を利用するようなシステムにおいて、 二重決済 (システム上の欠陥等により同じ金額が2回決済されてしまう現象)などのトラブルが発生する事例が増えてきました。原因としては、システム側で請求したはずの履歴がないために再請求が行われるケース(システム間の連携不備)や、注文時と商品発送時などで送信されるデータがそれぞれ2回分決済されてしまうといったケースがあるようです。そのため、課金システムにおいても決済を行うときのタイミングやそのときの各ステータスの変化に着目するような観点は重要なポイントとなります。例えば、決済時のアイテムやコンポーネント間での確認であれば「機能テスト」が、決済処理とそのステータスといった各処理の連携に関する確認であれば「状態遷移テスト(または画面遷移表や状態遷移図を用いたテスト設計)」がそれぞれ有効なテストとなるでしょう。 機能テストの観点例) 正常系: 決済処理を行ったとき、関連するステータスが適切に変化するか 決済処理を行ったとき、関連する履歴が適切に反映されるか フロントシステムから決済処理を行ったとき、バックエンドシステムや基幹システムなどに決済した情報が適切に受け渡されるか 異常・特殊操作系: 同時処理(複数ブラウザ等から同タイミングで決済したとき二重決済されないか) 割込処理(決済処理中などで別の決済情報が割り込みしたとき各決済が適切に処理されるか) 連続操作(決済を確定するボタンを連打したとき二重決済されないか) ※上記で記載している当該処理・操作時の期待結果はあくまで想定で記載しているため、実際のテスト設計時は対象システムの仕様を考慮する必要があります。 状態遷移テスト例) 決済に関する各ステータスの仕様例 仮売上: 決済が完了して注文が入った状態 処理中: 売上処理・キャンセル処理を行っている状態 決済完了: 実売上処理が正常に完了した状態 決済失敗: エラーが発生して決済処理が失敗した状態 キャンセル: ユーザーが注文のキャンセルを行った状態 上記仕様を基にした状態遷移図例 状態遷移図については、『 幅広いソフトウェアとテストレベルで適用可能な状態遷移テスト 』にて解説されているため、詳しい内容はこちらでご確認いただけます! 幅広いソフトウェアとテストレベルで適用可能な状態遷移テスト 初めまして。テストエンジニアリング部のこまです。今回はテスト技法の1つ、「状態遷移」についてのお話です。実際の業務でお世話になることも多い技法であることに加えて、JSTQBの学習を進めている方で苦手意識がある方もいらっしゃるかと思い(私がそうでした)、... 続きを読む Sqripts その他の機能 その他に、例えば 「ポイント」 を付与・利用できるような機能や、 「クーポン」 に対応しているような機能があれば、課金額への影響に関するテスト観点や今回ご紹介した「残高について」周りのテスト観点をかけ合わせてテスト設計を行うと有効となる場合があります。その他にもテスト対象となる課金システムによって様々な機能やサービスがあるため、各機能仕様やテスト条件、テスト環境やテストの規模感などに応じて、適切なテスト設計を行う必要があることを忘れてはいけません。 おわりに 冒頭の「お金に関するシステムとは?」でも述べた通り、近年ではオンライン決済等、お金を扱うシステムが増えてきました。一方で、そのようなお金に関するソフトウェアが正しく動作しないと、経済的な損失、時間の浪費、信用の失墜など企業やユーザーにとって生活レベルで重篤な問題が発生する可能性があります。そのため、テスト設計者は仕様通りに動作することはもちろんのこと、仕様通りの動きが妥当か、ユーザーの様々な利用シーンを考慮できているかなど、開発視点とユーザー視点の両方からテストを考えることが品質保証にとって重要なポイントとなります。仕様やリスクを深く理解し、様々な状況を想定してテストを設計していきたいと改めて感じました。今回の記事が少しでも参考になれば幸いです。 The post 課金システムのテスト設計に必要な観点を考えてみた first appeared on Sqripts .
この連載では、ソフトウェア開発のQAエンジニアとして働き始めた皆様に向けて、私の実体験をもとに「こんなことを知っておけばよかった」という、ちょっとした気づきを共有します。 一緒にソフトウェア開発のQAエンジニアとしての充実したエンジニアライフを築くためのヒントを探っていきましょう。 <QAエンジニアのスタートガイド 記事一覧> ※クリックで開きます 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう 本記事ではエンジニアとして重要な課題である「学ぶこと」について解説します。 学ぶことは大切です。ITという分野は技術やトレンドの移り変わりが激しく、常に最新の知識をアップデートしていく姿勢が求められます。 また、ITエンジニアは、学ぶことでさらにキャリアを飛躍できる可能性が高いです。 私が過去に経験していた営業職では、「勉強してもなかなか結果につながらない」ということがありました。もしかしたら他の職種でも同じような状況があるかもしれません。 一方で、ITエンジニアは学んだ知識をすぐに試せる特徴があると実感しています。また、世の中で広く知られている知識の多くは、現実のプロダクト開発の貢献につながるような、実践的なものがたくさんあるとも思います。 なので、前向きに学び、それを普段の業務で実践することは充実したエンジニアライフに繋がると考えています。 学び方は、学校教育や受験勉強など、これまでの人生でたくさん経験してきたのではないでしょうか。 しかし、実際に働いていく中では、学生時代と同じように学べないことがあると思います。 本記事では、社会人として、学びを継続することの考え方やコツを伝えていきます。 さまざまな方法で学習する 学習の仕方を学ぶ 社会人になると、1日のほとんどを学びに使っていた学生時代と状況が異なります。 もしかしたら、仕事や家庭の事情で、以前と同じようには学習できないかもしれません。 これらは時間的な要因だけでなく、脳の成長や、経済的な環境の変化にも影響を受けているのだと考えています。 そのため、社会人、そしてエンジニアとしての学び方を身につける必要があります。 具体的な学習の方法は、様々な書籍で言及されていますので、ここでは個別の学習方法について言及しないでおきます。 学習の仕方を学ぶには、以下の本をおすすめします。 エンジニアの知的生産術 (西尾泰和 著/技術評論社) 一生頭がよくなり続ける すごい脳の使い方 (加藤俊徳 著/サンマーク出版) 独学大全 (読書猿 著/ダイヤモンド社) 学習方法には様々なものがあり、具体的にどうやって学ぶかは、自身で考える必要があります。 重要なのは、一人一人に合った学習方法があり、「これが最高」というベストプラクティスは存在しないということです。 アウトプットを通じて学ぶ 個人的にいい学習方法だと思っているのは、アウトプットを通して学ぶことです。 ご自身が使用するナレッジマネジメントツールへの記録、SNSやブログへの発信、イベントへの登壇、普段の仕事での実践などです。 しかし、SNSやブログを通してパブリックな場にアウトプットすると、批判を受けてしまう可能性もあります。外部に向けてのアウトプットはいい面もあれば悪い面もあります。 それでもアウトプットをおすすめする理由は、自分の記憶に頼らなくても、ネット上から自分で検索して思い出すことができるというメリットがあることです。 アウトプットを通じて、自分の力を自分の外に蓄えておくことが可能になるのです。 「テスト」を通じて学ぶ QAエンジニアとして、様々なソフトウェア開発の言語やフレームワークを学ぶことがあると思います。 そういった場合に私は「どうやったらテストできるかを考える」ことを通して学んでいます。 テストとは試験ではなく、ソフトウェアテストです。 ソフトウェアテストは、そのプログラムの呼び出し、処理、アウトプットなど、ソフトウェアの概観を理解するのに重要な要素が詰まっています。 プログラミングを苦手だと感じているQAエンジニアは少なくありません。 そんな人は一度、「この言語やフレームワークはどのようにすればテストできるのだろうか」から考えてみることをおすすめします。 習慣を味方につける 社会人になると、様々な年齢や経験を持った人と比較されます。 そのため、学生時代のような、「同じ世代が同じスタートを切って比べる」ような経験からマインドをチェンジする必要があります。 早く到達することより、むしろ長い時間をかけてでも高い能力に到達することで、メリットを享受できることを理解することです。 だからこそ、長期的な視点で学習に取り組むことは大切だと思います。 「習慣にできるかどうかはその人の性格による」と考えている人もいるかもしれません。実際に私もそう考えていました。 しかしながら、習慣化にもまた技術があり、習熟することが可能なのです。 小さな習慣から始める 私のおすすめは、小さな習慣を作ることです。 学習の具体的な習慣だと、「1行だけ本を読む」や「1問だけ解いてみる」といったことです。 こういった小さな習慣は、数秒から数分程度で実行できるので、習慣化しやすいです。 これらの習慣をアプリやカレンダーなどで簡単に記録します。 小さな習慣の実行と記録を一定期間、例えば1ヶ月続けたとき、これは成功体験となり、次の習慣化のモチベーションに繋げることができるのです。 小さな習慣は育つ 小さな習慣は小さな歩みですが、時間を味方につけることで、長期的には大きな飛躍につながります。 そして、ここで強調したいことは、「小さな習慣は進化する」ということです。 例えば、1日1行の読書を続けているうちに、「1行から1ページにしよう」といった、小さな習慣が大きな習慣に育っていくことがあります。 私のおすすめはこういった前向きなモチベーションには正直に従い、大きな習慣にしてしまうことです。 続けるのが難しくなればまた小さな習慣に戻せばいいのです。 習慣化に失敗しても、習慣化をする技術は失敗を通じて向上させることができると考えます。 習慣化の技術については以下の本が参考になります。 200万人の「挫折」と「成功」のデータからわかった 継続する技術 (戸田大介 著/ディスカバー) 仕事から学ぶ エンジニアとして、様々な学び方があります。 机に向かって勉強するだけでなく、普段の仕事から学ぶことも大切です。 ふりかえりから学ぶ 普段の仕事をしていて、学習よりもむしろ、業務に追われてしまうことは少なくないと思います。 そういった中で、「ふりかえり」や「内省」を通じて学ぶことも有効です。 失敗を繰り返さないことも大切ですが、「よかったことを習慣化する」という点でも、自分の普段の業務をふりかえり、自分自身の学びに繋げることができます。 たとえばKPTというフレームワークがあります。 これは自分が行ったことや感じたことなどを、 Keep/Problem/Try という3つの視点で分類して、次のアクションを考えるという手法です。 KPTの中ではProblemに気を取られる人は少なくないですが、むしろ私はKeepを習慣化することが大切だと考えています。 ふりかえりについては下記の書籍をおすすめします。 アジャイルなチームをつくる ふりかえりガイドブック 始め方・ふりかえりの型・手法・マインドセット (森 一樹 著/翔泳社) 失敗から学ぶ 失敗から学ぶことも大切です。 失敗には学びにつながる「良い失敗」と学びに繋がらない「悪い失敗」があります。 たとえば「失敗学」という分野では失敗の原因を分析し、レベルの低い判断ミスを防止しつつ、高度な判断ミスを形式知にして改善していくという考え方があります。 失敗学のすすめ (畑村洋太郎 著/講談社) 最後に 最後に、1つだけアドバイスしたいことがあります。 「さあ学んでみよう」と学んでみても、うまく記憶が定着しなかったり、アウトプットに繋がらないことがあります。 それによって「また、これを学ばなければいけない」とか「また、こんなこと忘れていて恥ずかしい」と思うことがあると思います。 私はよくあります。 そういった時に私が自分に言い聞かせていることがあります。 「繰り返しの中から、また学べばいい」と考えることです。 何かを学び、忘れてしまって、同じことを学んでしまうこともあります。 しかし、それを悔やむ必要はありません。 そうして悔やむのではなく、「また学ぶことができる」「同じことでも学べばいい」と前向きに考えて、好奇心を持ち続けることが大切だと考えています。 「どれだけ学べたか」は他者から見れば、大事かもしれません。 一方で、「学ぶ姿勢を持ち続けよう」は、自分自身が充実したエンジニアであると感じて過ごすために、重要だと思っています。 【連載】QAエンジニアのスタートガイド 記事一覧 【第1回】充実したQAエンジニアとしてスタートするためのガイドライン 【第2回】「誰のためか」を意識しよう 【第3回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -前編- 【第4回】QAエンジニアの第一歩、「ソフトウェアテスト」を知ろう -後編- 【第5回】コミュニケーションが鍵を握る 【第6回】学ぶ姿勢を持ち続けよう The post 【第6回】学ぶ姿勢を持ち続けよう|QAエンジニアのスタートガイド first appeared on Sqripts .
こんにちは、K.Oです。 現代のソフトウェア開発では、新しい技術やプロセスの導入機会が増えています。特に、スピードと柔軟性が求められるスタートアップのアジャイル開発では、技術導入による生産性向上が大きな魅力です。しかし、現場の抵抗感やスキルギャップにより、導入が思うように進まないことも少なくありません。 そこで鍵となるのがチェンジマネジメントです。これを活用することで、組織や個人が変革に柔軟に適応し、スムーズに定着させるためのプロセスを可視化・管理できます。 本記事では、まずチェンジマネジメントの全体像を押さえ、以下の2つの事例をもとに、ADKARとKotterの2つのモデルを用いてチェンジマネジメントの実践方法を解説します。 スタートアップのアジャイル環境に品質管理の仕組みを導入 第三者検証企業のテスト工程にAIベースのテスト支援を導入 チェンジマネジメント とは?変革を定着させる基本原則 チェンジマネジメントとは、新しい技術やプロセスをスムーズに導入し、定着させるための手法です。単にツールを導入するだけでなく、組織や個人の行動変化を支援し、変革を持続させることが目的となります。 代表的なフレームワークとして、以下の2つがよく知られています。 ADKARモデル ジェフ・ハイアット(Jeff Hiatt)が提唱した、個人に焦点を当てた変革モデルです。 変革を受け入れる個人の心理プロセスを次の5つの要素で定義しています。 Awareness(認識) – 変革の必要性を理解していること Desire(欲求) – 変革に参加し支えたいという意欲があること Knowledge(知識) – 変革の方法に関する知識を持っていること Ability(能力) – 新しいやり方を実行するスキルが備わっていること Reinforcement(強化) – 定着させ変化を持続するための強化策があること ADKARモデルでは、個々人が「なぜ変わる必要があるのか」「変化が自分にどう影響するのか」を明確に理解し、自発的に変化を受け入れる状態を作ることを重視します。 個人レベルでこの5要素を順に満たす支援を行うことで、組織全体の変革成功率を高めることができます。 Kotterの8段階プロセス ジョン・コッター(John Kotter)が、多くの企業の変革事例を分析してまとめたフレームワークです。変革を成功させるために踏むべき8つのステップを提示しており、特に大規模な組織変革における人の動きに焦点を当てています。 8段階の概要は次の通りです。 危機意識を高める – 変革の必要性を周知し、現状のままでは問題であるという認識を共有する 強力な連帯を築く – 変革推進チームを結成し、信頼できるメンバーで連帯して取り組む 戦略的ビジョンを策定する – 目指す方向性(ビジョン)と実現する戦略を示す 全員の支持を得る – ビジョンを社内に浸透させ、できるだけ多くの支持と参画を得る 障壁を取り除いて行動を可能にする – 新しい取り組みを妨げる抵抗や障害を排除し、現場が行動しやすい環境を作る 短期的な成功を生み出す – 早い段階で小さな成功事例を作り出し、成果を実感させる 加速を持続する – 得られた成果を踏み台にさらなる変革を進め、勢いを維持する 変化を定着させる – 変革で導入した施策を組織文化や日常業務に組み込み、元の状態に戻らないよう定着させる このモデルのポイントは、抵抗感のある人々も巻き込みながら信頼関係と透明性を持って進めることで、受動的で抵抗感のある人を主体的な変革の担い手へと変えていく点です。 コッターのモデルはトップダウン視点の色合いが強いため、ADKARモデルで個人の理解と納得を促しつつ、コッターのステップで組織の環境を整えるという使い分けが効果的です。 以降の事例では、ADKARモデルとコッターの8段階プロセスを効果的に組み合わせながら、品質管理の導入やAIベースのテスト支援の導入を例に成功させるポイントを解説していきます。 ケース1:スタートアップのアジャイル環境に品質管理を導入 スタートアップのアジャイル開発に起こりがちな品質管理の課題 アジャイル開発を採用するスタートアップでは、以下のような課題が起こりやすい傾向があります。 スピード重視文化の弊害 「動くものを早く届ける」を優先し、テストや品質基準を軽視しやすい 属人的な判断・経験頼み KPIや品質基準がなければ、リリース前のチェックも各エンジニアの裁量に依存 リリース後のバグ増大と修正コストの上昇 初期不良が重なり、結果的に作業負荷や開発スピードが落ちる アジャイル開発はスピードと柔軟性が強みですが、品質面が甘いと長期的な成長を妨げる可能性があります。こうした状況を改善するためには、品質管理の仕組みを「無理なく」アジャイル開発に取り込むアプローチが効果的です。 ADKARモデルを活用した導入ステップの一例 A(Awareness) :認識 まずは、品質管理の重要性を全員に認識してもらうことが出発点です。 過去の不具合件数や修正コストを可視化。チームが「長期的な開発速度低下」を実感するようなデータを共有 D(Desire) :欲求 次に、品質管理導入がチームのメリットにつながることを共有します。 バグ修正頻度が下がれば、エンジニアはより新機能開発に専念できる 品質管理の導入は、開発者のストレス削減につながることを強調 K(Knowledge) :知識 品質基準やKPI測定の方法など、具体的な知識を浸透させます。 軽量な品質基準の策定し、テストカバレッジ、コードレビュー実施率など、導入ハードルの低い指標からスタート プロジェクト管理ツールに「バグ起票ルール」や「優先度付け方法」をまとめ、誰でも確認できる状態を整える A(Ability) :能力 実際の開発現場で運用できるよう、チームに必要な技術を身につけてもらいます。 デプロイ時に自動テストが実行されるようにするなど、開発フローを大幅に変えずに品質管理を自然に取り込める仕組みを整える コードレビューの基準化を進め、チェックリスト形式で「レビューすべきポイント」を定義するなど、担当者の迷いを軽減、レビュー工数が増えすぎるリスクを抑える R(Reinforcement) :定着 最後に、成果を振り返り、チーム文化として定着させます。 バグ発生率の変化やテストカバレッジの推移を週次やスプリント末に確認し、チームで議論 良い変化があれば称賛し、継続的な振り返りと改善を重ねて開発文化として定着させる 成功のポイント 大きな変革は小さく始める いきなり品質基準を厳しくするのではなく、テストカバレッジやコードレビューの導入など、小さいステップから取り入れる 品質管理の形骸化を防ぐ 「テストカバレッジ100%」を目指すことが目的ではなく、「実際の品質向上」を重視するという意識づけを行う 成功事例をチーム全体で共有 不具合の減少や長期的な工数削減のデータを共有し、品質管理のメリットを実感してもらう ケース2:第三者検証のテスト工程にAIベースのテスト支援を導入 第三者検証へのAI導入も考えてみます。 AI導入時の典型的な課題 第三者検証企業におけるテスト工程にAIベースのテスト支援を導入する際は、技術的ハードルに加えて、顧客や現場の理解を得る必要があります。具体的には、以下のような点が課題となりがちです。 AIによるテストケース生成の妥当性 顧客が「本当に十分な品質が担保できるのか?」と懐疑的 不具合起票の一貫性 AIが自動で発見した不具合と、テストエンジニアが手動で発見した不具合の整合性をどう確保するか 現場エンジニアの抵抗感 「AIに仕事を奪われるのでは?」という誤解や、新ツール学習への負荷 ADKAR+ Kotter で見る導入プロセスの一例 AI導入時は、個人の変革を促すADKARモデルに加え、組織全体の変革を推進するコッターの視点が役立ちます。 危機感を高める :Kotter Stage 1 人手不足や工期短縮要請など、従来のやり方では対応が難しい現状を明示 Awareness(認識) :ADKAR AI導入の必要性をデータで裏付ける(例えば、テストケース自動生成やテストの自動実行で〇%の工数削減見込み) 強力な連帯を築く :Kotter Stage 2 開発チームに加え、営業やカスタマーサポートも含めた横断的なチームを編成し、導入をリードする Desire(欲求) :ADKAR 「AIがルーティン作業を担うことで、テストエンジニアはより高度なテスト設計に集中できる」というメリットを明確に示す Knowledge(知識) :ADKAR AIによるテストケース生成の仕組みや、誤評価・評価漏れリスクの対処方法を従来のテストと比較し、社内勉強会で共有 短期的な成功を生み出す :Kotter Stage 6 一部プロジェクトでPoC(概念実証)を実施し、バグ検知率の向上や工数削減といった成功データを取得する Ability(能力) :ADKAR PoCで得たノウハウを手順化し、マニュアルや動画チュートリアルを整備 Reinforcement(定着) :ADKAR 成果を関係者全体で評価し、顧客への提案資料に活用する 組織全体でAIベースのテスト支援に対する理解を深め、現場での定着を図る 変化を定着させる :Kotter Stage 8 組織として「AI活用」を当たり前の体制にし、人事評価やプロジェクト計画書にAI活用を織り込む リスク管理と成功のポイント 顧客とのコミュニケーションを強化 AIがどの範囲まで自動化し、どこから人が判断するのかを、契約時やテスト計画の段階で明確にし、関係者間で合意形成しておく PoC→段階的導入→水平展開 まずは限定的なプロジェクトで導入し、成功を確認。その後、他のプロジェクトへ段階的に展開する 透明性と説明責任 AIが生成したテストケースや不具合起票の根拠を説明できる仕組みがあると、顧客が安心しやすい まとめ 変革=ツール導入だけではない 技術導入の成否は「ツールそのものの優秀さ」だけでなく、人や組織がどう変わるかにかかっている 小さな成功体験の積み重ねがカギ まずは限定的な範囲で導入し、成功体験を積み上げることで、チーム全体のモチベーションを高めながら定着を促す “なぜ今この変革が必要なのか”を共有する 関係者全員が納得できる理由を明確にし、データや事例を活用して効果を示すことで、チェンジマネジメントをスムーズに進められる チェンジマネジメントの本質は、「人の意識と行動をいかに変えるか」にあります。スタートアップの品質管理導入からAIベースのテスト支援の活用まで、ADKARモデルやKotterの8段階プロセスといった理論を適切に応用することで、変革の成功率を大きく高めることができます。 本記事が、チェンジマネジメントを進める際のヒントとなり、少しでもお役に立てれば幸いです。 #チェンジマネジメント #ADKAR #Kotter #アジャイル #品質管理 #AIテスト The post チェンジマネジメントで変革を加速!ADKAR×Kotterで実現するアジャイル品質管理とAIテスト導入 first appeared on Sqripts .