この連載は、登場して20年が過ぎ、成熟期を迎えつつある「アジャイル開発」を解説します。アジャイル開発については、世の中にたくさんの書籍や情報があふれていますが、アジャイルコーチとして10年以上の現場経験をもとに、あらためて学び直したい情報を中心にまとめていきます。 第5回目のテーマは、「アジャイル開発の誤解」です。 この内容はUdemyで公開しているオンラインコース「 現役アジャイルコーチが教える!半日で理解できるアジャイル開発とスクラム 入門編 」の内容を元にしています。 よくある誤解: アジャイル開発はドキュメントを作らない 有名な誤解ですが、これは間違っています。 アジャイルマニフェストにも書かれているように、「ドキュメントよりも、動くソフトウェアを価値としよう」なので、ドキュメントを不要としているわけではありません。 よって、必要なドキュメントがあれば作ります。また、プロダクトの規模が大きくなればなるほど、必然的にコミュニケーションコストがかさむため、ドキュメントが重要になってくるでしょう。 それでは、アジャイル開発におけるドキュメントのイメージを持っていただくため、現場でよく見かけるドキュメントをいくつか紹介します。 インセプションデッキ: アジャイル開発版のプロジェクト憲章のようなもので、プロダクトやプロジェクトにおいて、自分たちのチームは同開発を進めていくか? チームの共通認識を生み出すための文書です。 システム全体図: アジャイル開発は小さく開発していきますが、開発が進めば進むほどプロダクトは大きくなっていきます。ちょっとずつ組み立てていく過程を経験していれば、大きくなってもある程度理解できますが、途中から入ってきたメンバーにとっては、なかなか全体像が見えないものです。そういった場合、システム全体図のような高い視点のドキュメントが役に立ちます。 複雑な部分の仕様書: 仕様は全部整理しておきたいものですが、「仕様をドキュメントにまとめる」と決めた場合、それ自身が新しい仕事になります。そしてその仕事は、開発が続く限りずっと続いていきます。そのコストを払い続けても、それに見合ったリターンがあるなら良いと思います。もしそうといえないのであれば、まずは重要な部分の仕様書だけ整理しておくといいと思います。 振り返りのログ: アジャイル開発では、定期的にふりかえりを行います。そのときの学びをWikiやホワイトボードツールなどに残しておけば、過去の経緯や過去の学びが情報として溜まっていきます。 よくある誤解: アジャイル開発なら要件をいつでも変更できる? これもよく見かける誤解です。 アジャイルソフトウェアの12の原則 にも書かれているように、要求の変更はたとえ開発の後期であっても歓迎します。しかし、何でもかんでも変更していては、どんな開発でも進んでいかないでしょう。 変更するということは、その時点で再計画が発生するという意味でもあります。再計画無しの変更は無謀です。これも12の原則にもあるとおり、アジャイル開発であれば、無理や無茶がない、持続可能な開発を促進しなければなりません。 変化の多い現場であれば、開発サイクルを短くしたり、やることを小さくするといいでしょう。大きなものを大きなまま開発しているのであれば、アジャイル開発よりも従来型の方がやりやすいかもしません。 よくある誤解: アジャイル開発は優秀な人にしかできない? 筆者の回答は「誰にでもできる」です。 12の原則にあるように、アジャイル開発に必要なのは、意欲に満ちた人々です。意欲がないとはじまりません。 また、「試しにやってみよう」ぐらいの意欲だと失敗する可能性が高いです。きっかけとして悪くはないのですが、「必ず成功させよう」という意欲を持ったチームのほうが、成功率が高くなります。 優秀な人たちがチームにそろうといいことがありそうですが、個々の能力が高くても、チームの生産性が上がるわけでないという有名な研究結果が グーグルからも出ています 。チームでの開発が主流のアジャイル開発では、個人の能力だけではだめで、チームという集団での知性が問われるのです。 よくある誤解: アジャイル開発は計画を立てない? アジャイル開発でも計画を立てます。ただ、計画の立て方が従来型とは異なります。 アジャイル開発は短い期間で開発を繰り返します。小さいものを積み上げていく方法なので、全体像が見えにくいという欠点があります。よって、3ヶ月毎、半年ごと、1年毎、というように、中長期的なリリース計画やロードマップが必要になります。 計画ごとの解像度のイメージ。濃い色になるほど解像度が高くなる。 注意したいのは、計画の解像度です。アジャイル開発は変化に対応していきたいので、従来型のようにかっちり計画をきめてしまうと、解像度は高まりますが、変化に弱くなります。変更があったときに、また解像度の高い計画を立てていては、スピードも出せません。 よって、アジャイル開発では、遠いものは見えにくいので低い解像度。近いものははっきりみえるので高い解像度・・・と、計画の解像度を変えて対応していきます。 つまり、遠くのものはざっくりと計画を管理し、現在に近づけば近づくほど解像度を高めていくのです。 よくある誤解: アジャイル開発は開発生産性を高める? 従来型でもアジャイル開発でも、開発生産性を高められます。よって、従来型よりアジャイル開発のほうが開発生産性が高いということはないと思います。 アジャイル開発は、従来型の開発生産性の考え方をあまり適用しません。考え方が異なる方法同士なので、導入が難しいためです。 そのかわりといってはなんですが、アジャイル開発では、ベロシティ(チームのアウトプット量)やリードタイム(アイデアがリリースされるまでの時間)といった別の指標を計測して、チームの状態を確認していきます。 よくある誤解: アジャイル開発にはプロジェクトマネージャは必要ない? アジャイル開発でもプロジェクト型の開発を行っているチームは多いです。期限があるプロジェクトをやるというよりは、プロジェクトを繰り返しながら開発するイメージです。 アジャイル開発であろうと、チームの開発を運営は必要なので、プロジェクトマネジメントの考え方は大切だと思います。ただ、アジャイル開発は自律したチームですので、計画もチームで作り、進捗もチームで見ていくので、チームが自律してしまえば、プロジェクトマネージャーは必要なくなるかもしれません。 もし、現在が、プロマネという役割によってチームが管理されている状況だとすれば、アジャイルチームの目指す自律性を阻害している可能性があります。 よくある誤解: アジャイル開発では設計しない? ソフトウェア開発において設計は重要な活動ですから、設計はします。 ただ、アジャイル開発は短い開発サイクルをまわしていくものなので、従来型のような明確な設計フェーズはないことが多いでしょう。 短い開発サイクルの中で、設計>開発>テスト・・・と繰り返していくイメージになりますが、これだと小さなウォーターフォールになってしまい、期間の最後にまとめてテストすることになり、期間分の手戻りリスクが発生してしまいます。 これを回避するために、機能 > 機能 > 機能 と、期間の中で小さな開発を繰り返していく方法をとっているチームが多いです。 よくある誤解: アジャイル開発にQAは必要? 従来型の開発の場合、作るべきものが明確なケースが多いので、品質を保証(Quality Assurance: QA)しやすいと思います。ここでいう品質は、仕様通り作られているかが中心になります。 アジャイル開発の場合、小さくリリースしたものに対するフィードバックを元に軌道修正していくので、「これは価値が大きい!」とリリース前に保証するのは至難の業です。ここでいう品質は、リリースしたものの価値の大きさが大きいほど品質が高いと言えます。 よって、アジャイル開発に従来型のQAという考え方を適用するのは難しいと思います。おそらく、網羅性の高いテストをリリースごとに繰り返していく形になるので、QAがフェーズになり、QAフェーズがボトルネックになる可能性が高いでしょう。 アジャイル開発には、アジャイル開発に適したテストや品質の考え方が必要です。まちがっても、速く作るからテストをすっとばそう!とはなりません。 よくある誤解: ユーザの価値、プロダクトの価値が重要? 最後の誤解は、「ユーザの価値、プロダクトの価値が重要」です。もちろん重要なのですが、注意したい点があるので、あえて最後に解説します。 たとえば、プロダクトを優先させるために、チームが犠牲になり、連日連夜デスマーチを続け、チームが疲弊して離脱者が増える・・・といったケースもたまに見かけます。 アジャイル開発では、持続可能な開発を大切にします。プロダクトを優先させすぎて、それ以外の価値や原則が歪んでしまっていないかを意識するようにしたいものです。何かを犠牲にして何かを達成するのは、決して持続可能な開発ではありません。 また、アジャイル開発はチーム開発が中心になりますが、チームだけでなく個人も大切です。こちらもチームのために、個人が犠牲になるようなことがないようにチーム運営していく必要があります。 よくある誤解: アジャイル開発を導入すればうまくいく? 世の中には「これを導入して売上UP」のような方法論やフレームワークがたくさんあります。たしかに、そういうベストプラクティスを駆使すれば、現状はよくなるかもしれません。 しかし、アジャイル開発は、成功を約束する方法論ではありません。あくまで成功率を高める手段です。 「アジャイル開発を導入したが良くならなかった」というケースがなくならないのは、この部分を誤解している可能性があります。 第1回:アジャイル開発の過去、現在、未来を知ろう! 第2回:声に出して読みたいアジャイルマニフェスト 第3回: 従来型開発とアジャイル開発の違い その1 第4回: 従来型開発とアジャイル開発の違い その2 The post 第5回 アジャイル開発のよくある誤解を解いていこう! first appeared on Sqripts .
こんにちは、エリアマネージメント部の 蟹乃中 味噌太郎 です。 FacebookやTwitter、AmazonなどのWebサイトからExcel、Skypeといったソフトウェアなど様々な国で利用されているサービスがたくさん展開されています。皆さんも一度は利用経験があるのではないでしょうか。 そのような複数の国・言語に対応したソフトウェアをテストする機会もあるかと思います。ブラウザ、Webアプリケーション、スマートフォンアプリなど、システムによって観点が大きく異なることもありますが、今回はブラウザに焦点を当てて、私なりに注意したいポイントなどをご紹介させていただきます。説明には私の所属会社(AGESTとDIGITAL HERATS HOLDING)のホームページを使用します。 表示言語 複数の国で展開されるWebサイトをテストする場合、まず初めに初期表示となるデフォルト言語について確認する必要があります。 言語設定が未設定の場合はデフォルト言語となりますが、どのようにデフォルト言語が設定されているかを確認する必要があります。 単純にシステムのデフォルト言語で表示されるパターンもあれば、上記のようにアカウント毎の設定された地域や国を参照してデフォルト言語が変化するパターンもありますので注意が必要です。 言語設定が行われている場合は、デフォルト言語に影響することなく設定した言語で表示されることをテストする必要があります。 また、表示される言語が異なれば当然ながら単語や文章の長さが変化します。言語が変化することによってレイアウトが崩れてしまうことがありますので、各言語でレイアウトなどを確認するテストが必要となってきます。 リンク設定 リンクの場合、同じページに遷移するので、表示言語に合わせた言語で表示されるのでは?と思われるかもしれません。ですがリンクも表示言語に合わせて設定されている必要がありますので注意が必要です。 日本語に設定しているはずなのにリンク先に遷移すると英語で表示されたり、PDFの書類をダウンロードすると表示言語と異なる書類となっていたりする場合もあります。なので、リンクについても各言語毎にテストするように注意したいです。 実際にAGESTのホームページで確認してみます。 日本語のページだとURLが” https://agest.co.jp ”となっていますが、英語に切り替えると URLが” https://agest.co.jp/en/ ” となっていて、URLが少し変化していますね。次にヘッダにある「会社情報(Corporate)」を日本語と英語の場合で比較してみたいと思います。 まず日本語のリンク設定は、 ” /corporate/ “となっていますね。次に英語では、 ” /en/corporate/ “となっていますので、”/en/ ”がつくことにより英語の会社情報へ遷移するように設定されています。このように言語に合わせてリンクが設定されているため、遷移によって言語が戻ってしまう様なこともなく快適に利用できるというわけです。逆に言語に合わせてリンクが設定されていないと煩わしく使いづらいものとなってしまいます。 エラーメッセージ表示 バリデーションで入力必須のエラーメッセージが表示されるシステムの場合、特定の画面のみ設定言語とは異なる言語で表示されてしまったり、特定のエラーメッセージが設定言語と異なる言語で表示されたりといった不具合が潜んでいることがあります。 ※上図はページ内のテキストは英語表示なのに、エラーメッセージが日本語となっているイメージ画像です。この場合、エラーメッセージも英語で表示されるのが望ましいでしょう。 ここではエラーメッセージを例にしましたが、エラーメッセージに限らず特定の操作によって追加で表示されるようなメッセージやダイアログについては、設定言語に合わせて正しい言語で表示されるかをテストする必要があります。 日時表示がある場合 日時表示がある場合、どのような基準で表示されているかに注意を払う必要があります。例えば、国毎のタイムゾーンに合わせて日時表示が行われていて、「協定世界時(UTC)を基準としてそれぞれのタイムゾーンに変換して表示」している機能があったとします。 “10:00:00(UTC) “をアメリカの日時に変換する場合 (ここでは「CST(米国中部標準時)」に変換されると仮定)、CSTはUTC(協定世界時)から”-6:00:00”となるので、4:00:00(CST)が正しい変換となりますが、 日時が協定世界時(UTC)のままのパターン 【10:00:00(UTC) ⇒ 10:00:00(UTC)】 日時が別のタイムゾーンに変換されているパターン 【10:00:00(UTC) ⇒ 19:00:00(JST)】 ※JST(日本標準時はUTCから ”+9:00:00”なので19:00:00となります。) 日時は合っているがタイムゾーン表示が異なるパターン 【10:00:00(UTC) ⇒ 4:00:00(JST)】 上記のような不具合が潜んでいる可能性が考えられます。 さらに、日本ではあまりなじみがありませんがサマータイムというものが国によっては設定されています。サマータイムは特定の期間に適用され、「協定世界時(UTC)基準で1時間進められる」といったものになり、タイムゾーンもサマータイム用のものに変化します。 「CST(米国中部標準時)」を例に挙げると、タイムゾーンは「CDT(米国中部標準時の夏時間)」となります。時間は「10:00:00(UTC)」を基準とすると、CDTの場合はUTCから”-5:00:00”となるので、「05:00:00(CDT)」となります。 そんなサマータイムですが、現在アメリカやヨーロッパで廃止する動きがあります。廃止となれば、サマータイムを採用しているシステムからも機能が廃止されることが考えられますので、それらの取り扱いについてもしっかりと確認しておきたいですね。 ちなみにアメリカでは、夏時間が恒久化される可能性があるようです。 価格の表示について 通貨が国によって異なることは言うまでもありませんが、国によって価格表示の桁数の表現も異なります。日本の場合、小数点に対応していませんが、アメリカでは小数点にあたるセントの単位があります。また、日本では数字の区切りが ”カンマ” で区切られておりますが、国によっては ”ピリオド” や ”スペース”で区切られていることがあります。 価格表示については、小数点の対応・非対応であったり、数字の区切りなどが国によって変化することを考慮してテストする必要があります。さらに、これらはシステムの制御や環境によっても変化するので、テスト対象毎にどのような振る舞いとなるのかを開発者やマネージャに確認するなど、テストする際は事前確認を怠らないように注意が必要です。 少し実践 ではAGESTのホームページを使用して簡単なテストを行いたいと思います。ここでは、英語のTop Pageを使用して、ヘッダーの各リンクからの遷移を中心にテストします。確認する観点は以下の4つで実行したいと思います。 英語の該当ページに遷移すること 特定の位置が指定されている場合は指定の位置に遷移すること 日本語で表示されている箇所がないこと レイアウトなどの表示が崩れていないこと それでは始めます。 Top Pageにあるヘッダーの確認箇所は下図の赤枠で囲った部分となります。 確認するアイテムは以下の4つです。 ・AGESTのロゴ ・Japanese ・DIGITAL HEARTS HOLDINGS ・Inquires では、それぞれクリックしていきます。 【AGESTのロゴをクリック】※ ” https://agest.co.jp/en/ ”に遷移 【Japaneseをクリック】※ ” https://agest.co.jp/ ”に遷移 【DIGITAL HEARTS HOLDINGSをクリック】※ ” https://www.digitalhearts-hd.com/ir/ ”に遷移 【Inquiresをクリック】※ ” https://agest.co.jp/en/inquiry/ ”に遷移 それぞれ確認したところ、” Japanese ”と” DIGITAL HEARTS HOLDINGS ”は日本語のページ、他は英語のページに遷移しておりました。まず” Japanese ”については日本語ページに切り替えるメニューなので、日本語表示となるのが正しい挙動となります。次に” DIGITAL HEARTS HOLDINGS ”については、外部サイトへのリンクとなるので遷移先のデフォルト言語で表示されるのが正しい仕様となります。たとえば” AGESTのロゴ ”や” Inquires ”など本来は英語表示のページに遷移するはずのリンクで、日本語表示のページに遷移してしまう場合は今回の観点では不具合となります。今回はそのような事はありませんでした。 まとめ いかがでしたでしょうか? こちらで挙げたポイントが全てではなく、システムによっても気を付けないといけないポイントは当然変わるかと思いますので、臨機応変に対応していきたいですね。一番は国や地域に寄り添って考えていくことが大事ではないかなと思います。 The post 多言語対応したWebサイトをテストする時に気をつけたい5つのポイント first appeared on Sqripts .
はじめに 近年、AgileやScrumの普及に伴って、振る舞い駆動開発(Behavior Driven Development、以下BDD)や受け入れテスト駆動開発(Acceptance test–driven development、以下ATDD)にも注目が集まってきました。 そこで本連載では、BDDやATDDとは何か、どのように活用すれば良いのか考えていきたいと思います。 本連載の構成は以下の通りです。 本連載のメインであるBDDやATDDは、テスト駆動開発(Test-driven development、以下TDD)から派生した考えです。つまり「TDDとは何か」という理解がないとBDDやATDDを理解することが難しくなります。そこで今回は、TDDとは何か、TDDの目的は何かについて改めて考えてみましょう。 本連載を読み始める前に確認してほしいこと 対象読者について 本連載では、以下のような読者を対象として考えています。 ・TDDのやり方を知っている、もしくはTDDを実践している ・BDDという単語は聞いたことある ・BDDのやり方は知らない 本記事でTDDのやり方については語りません 本記事では、具体的なTDDのやり方については割愛します。 理由としては、既に素晴らしい教材がネット上にあるからです。特に、 TDD Bootcamp 2020 Onlineの和田卓人さんによる基調講演(動画) は是非ご覧ください。文字上でTDDを語るよりも多くの有益な考え方が示されています。 本記事では、TDDのやり方を知っている前提で、なぜTDDを行なうべきか、何を目的としているのかについて話します。 TDDはテスト手法ではなく開発手法である 「TDDとは開発手法もしくは設計手法の1つである」という理解が必要です。特に、TDDという名前から「テスト手法の1つである」という勘違いが非常に多いです。 TDDとは、「テストの方法」ではなく、あくまでも 「手段としてテスト(テストコード)を用いた開発方法」 です。 TDDは以下の3つを満たしながら作成していきます。 ・Red…設計の指針や直近のゴールを明確にする(そのためにテストコードを記述する) ・Green…ゴールを達成する(つまりテストコードがPassする)コードを愚直に実装する ・Refactor…ゴールを達成させたまま(つまりテストコードがPassしたまま)、実装したコードを改善していく ゴールを示す具体的な手段としてテストコードを用います。 BDDを考案したDan Northも自身の記事「 We need to talk about testing (邦訳: テストについて話し合わなくてはならない) 」の中で、以下のように述べています。 TDD、BDD、ATDD、および関連するメソッドは、その名前が示すように、テストに取って代わるものではありません。これらは主に設計および開発手法です。 (中略) プログラマーは自分が単体テストを書いていると思っています。そうではありません。彼らは、設計の指針となる簡単な具体例をテストコード形式で書いているに過ぎません。 TDDを行う主目的は素早くフィードバックを得るためである。 TDDとは、「手段としてテストを用いる開発手法」という説明をしました。 それでは、なぜTDDを行うのでしょうか? TDDを行う主目的は、「素早くフィードバックを得ること」です。 開発をして、顧客からフィードバックをもらうには、通常1週間以上、長いと半年以上かかります。これは、リリースサイクルや顧客との関係性によって期間が変わります。この状態だと、フィードバックを貰った時に、開発が終わってからかなりの時間が経っているため、そもそもどのように開発したのか思い出したりするところから始めることになります。(以降の画像および説明は「 私が経験したソフトウェアテストの変遷(JaSST’18 Tokyo招待講演) 」を参考に作成) それでは、顧客からのフィードバックが来るまで待ち続ける必要があるのでしょうか?そうではなく、もっとフィードバックを短くする方法があります。 例えば、「受け入れテスト」などと名付けて、リリース前の評価環境で実際にテストしてフィードバックをするかもしれません。 これならば、顧客に提供するよりは短い期間でフィードバックを行うことができます。しかし、まだまだフィードバックまでの期間が長くなります。 そこで、システムテスト、統合テスト、単体テストなど様々な手段によって、もっと短いフィードバックを検討することができます。 ここまで書いた「単体テスト」「統合テスト」「システムテスト」「受け入れテスト」は、品質保証手段として行われるテストです。([注釈]JSTQBシラバスのテストレベルの記載を参考に単語を選定しました。実際の現場では、「APIテスト」「UIテスト」など、違う単語を用いているかもしれません) 一方、品質保証を目的としないで作成するテストとして、開発者自身が作成するxUnitテストがあります。 テストを作る目的は違いますが、フィードバックまでの長さという軸で見ると、xUnitテストは他のテストよりも短いことが分かります。 それでは、xUnitテストの実施が一番短いフィードバックなのでしょうか?いえ、さらにフィードバックを短くすることができます。 実装とUnitテストの作成の順番を逆にすれば良いのです。 これがテストファーストな開発です。この考え方を用いているのがTDDです。 TDDは、上に書いたテストファーストな開発の考え方に加えて、「失敗するUnitテストを1つ作成したら、そのテストがPassするように実装を行う」「テスト実行を終えたら、次のUnitテストの作成を行う前に、リファクタリングによるコードおよび設計の改善を行う」という考え方も必要となります。 TDDもテストファースト開発の1つとして考えると、TDDを行う主目的は「素早くフィードバックを得ること」と考えて良いでしょう。 つまり、如何に素早いフィードバックを得て開発に活かすのかという、開発手法および設計手法としてTDDがあると考えることができます。 TDDによってどの程度素早くフィードバックを得ているのかについては、 TDD Bootcamp 2020 Onlineの和田卓人さんによる基調講演(動画) をご覧ください。 また同様の主張については、やっとむ/安井 力(やすい つとむ)さん作の記事「 テスト駆動開発(TDD)への招待 」もご覧ください。 回帰テストへの流用という副次的な効果 TDDを行う主目的は「素早くフィードバックを得ること」ですが、実際にTDDを行なって得られる副次的な効果として、回帰テストへの流用があります。 TDDで作成したテストは自動化されているため、そのまま回帰テストの材料として利用することができます。 つまり、別機能を開発する際のデグレードの防止に役立つのです。しかし、これはあくまでも副次的な効果です。TDDの主目的ではありません。 品質保証の考え方を注入する ここまでで、TDDを行う主目的は「素早くフィードバックを得ることである」という説明をしました。それに加えて、品質保証を入れることも目的の1つとして、TDDに取り組むことはできないのでしょうか?私は可能だと思っています。 その具体的なやり方については、秋山 浩一さん作の記事「 Fizz Buzz問題とTDDとテストと 」をご覧ください。 次回予告 今回はTDDとは何か、TDDの目的とは何かについて話しました。 次回は、BDDがどのような考えで誕生したかについて話します。 The post TDDとBDD/ATDD(1) TDDはテスト手法ではない first appeared on Sqripts .
こんにちは、バックエンドエンジニアのまるです。 この記事では、Elasticsearchの検索において、matchとmatch_phraseの違いについて解説します。 Elasticsearchとは Elasticsearchは、オープンソースの分散型検索エンジンです。大量のデータを高速かつ効率的に検索、分析するために利用されます。テキストデータ、数値、地理情報、日付など、あらゆる種類のデータを扱える汎用的な検索エンジンです。 本記事では日本語の全文検索に絞った解説をします。 matchとmatch_phrase Elasticsearchの検索には、matchとmatch_phraseという2つのクエリがあります。どちらも「フィールド内に指定された単語が含まれること」を条件としたクエリですが、以下のような違いがあります。 matchクエリは、指定した単語がフィールド内のどこにあっても検索することができます。検索ワードは形態素解析され、デフォルトでは単語のOR検索となります。 match_phraseクエリは、指定した単語がフィールド内で 連続して 出現している場合にのみ、検索することができます。matchと同じように検索ワードは形態素解析されますが、単語が連続している必要があります。 説明だけでは理解しづらいと思うので、サンプルデータを使った例を見てみましょう。 matchクエリ 初めに、日本語の全文検索をしたいので、kuromojiでindexを登録します。 PUT test_index { "mappings": { "properties": { "title": { "type": "text", "analyzer": "kuromoji" } } } } サンプルデータとして以下の3つの例文を登録します。 POST /test_index/_bulk { "index": {}} { "title": "ログイン機能のテスト仕様書" } { "index": {}} { "title": "探索的テストの仕様書" } { "index": {}} { "title": "書を捨てよ町へ出よう" } 登録が終わったら、さっそく「テスト仕様書」というワードでmatch検索してみましょう。 GET /test_index/_search { "query": { "match": { "title": "テスト仕様書" } } } Responseは以下のようになります。 (Responseは見やすいように一部省略、整形しています。以降同様) "hits": [ { "title": "ログイン機能のテスト仕様書" }, { "title": "探索的テストの仕様書" }, { "title": "書を捨てよ町へ出よう" } ] 3つ全てヒットしました。上2つはともかく、「書を捨てよ町へ出よう」という文がヒットするのはおかしいように感じられます。これは、検索ワードが形態素解析されてトークンという単位に分割され、トークンのOR検索として処理されているためです。 検索ワードがどのように分割されているのかは_analyzeで見ることができます。 GET /test_index/_analyze { "field": "title", "text": "テスト仕様書" } { "tokens": [ { "token": "テスト", }, { "token": "仕様", }, { "token": "書", } ] } 「テスト仕様書」というワードは、「テスト」と「仕様」と「書」に分割されて検索に使われます。デフォルトではトークンのOR検索となるため、「書」を含む「書を捨てよ町へ出よう」がヒットした、ということです。 分割された単語すべてが含まれてほしい場合は、operatorオプションにANDを指定すればよいです。 GET /test_index/_search { "query": { "match": { "title": { "query": "テスト仕様書", "operator": "AND" } } } } "hits": [ { "title": "ログイン機能のテスト仕様書" }, { "title": "探索的テストの仕様書" } ] 「テスト」「仕様」「書」が全て含まれる文だけがヒットしました。 match_phraseクエリ match_phraseは、指定した単語がフィールド内で連続して出現している場合のみヒットします。 同じサンプルデータを使ってmatch_phrase検索してみましょう。 GET /test_index/_search { "query": { "match_phrase": { "title": "テスト仕様書" } } } "hits": [ { "title": "ログイン機能のテスト仕様書" } ] 「ログイン機能のテスト仕様書」という文だけがヒットしました。これは、match_phraseの場合「テスト」「仕様」「書」が この順序で連続して 出現する文のみがヒットするためです。従って完全一致検索のように使うことができます。 完全一致検索では厳しすぎるのでもう少し柔軟な検索をしたいという場合には、slopというオプションを使うとよいです。slopオプションには「各単語の間にいくつの余計な単語を含んでよいか」を指定することができます。 GET /test_index/_search { "query": { "match_phrase": { "title": { "query": "テスト仕様書", "slop": 1 } } } } "hits": [ { "title": "ログイン機能のテスト仕様書" }, { "title": "探索的テストの仕様書" } ] 「テスト」と「仕様」の間に1つ余計な単語が含まれていてもヒットすることが確認できます。 終わりに この記事ではElasticsearchのmatchとmatch_phraseの違いについて解説しました。Elasticsearchは非常に汎用的な検索エンジンですので、他のクエリと組み合わせてもっと詳細で柔軟な検索を実現することもできます。 この記事がみなさんのお役に立てば幸いです。 The post Elasticsearchで押さえるべき!matchとmatch_phraseの違いを徹底解説 first appeared on Sqripts .
こんにちは。まーくー&くまねこです。 懲りずにまた二人で出てきました! 今回はソフトウェアテストの学び直しとして、まーくーがアジャイルソフトウェア開発技術者検定試験を受けてきました!まーくーがやった学習内容の紹介や感じたことを会話形式でお話させて頂ければと思います。 最後まで楽しんで読んで頂ければ幸いです! 自己紹介 まーくー QA業界経験2x年のベテラン(おじさん)エンジニア。 前回のブログ( ゆるっと♪ファームウェアテストよもやま話 )でJSTQB ALTM試験を受けると匂わせましたが、もう少し準備期間が必要そうです くまねこ QA業界経験1x年のエンジニア。 フェンスに腰掛けJSTQBの学習をしていたところ、またもまーくーさんに呼び出される(笑) イラストby くまねこ それでは、二人のやりとりをお楽しみください。 まーくー学び直しを決意する! まーくー :くまねこさんさぁ、アジャイル開発ってちゃんと理解している? くまねこ :どうしたんですか?唐突に・・・ まーくー :いやね。テスト業界に入って20年以上経つけど本格的なアジャイル開発プロジェクトって、まだがっつり参画した経験が無いんだよね。。。 くまねこ :まぁ、前回話していたファームウェアテストの現場は基本ウォーターフォール型開発でしたからね。 まーくー :そうなんだよね。アジャイルライクなプロジェクトには少し関わったことはあるし、書籍「 アジャイルサムライ 」とかは読んだことはあるけど、実際「アジャイル開発」をちゃんと理解しているかって不安なのよ・・・ くまねこ :渡る世間はアジャイルばかり?増えてますもんね。 まーくー :JSTQBのFL Extensionとしてアジャイルテスト担当者というのがあるけど、日本ではまだテストが実施されてないからなぁ。。。 くまねこ :海外で受験するとか(笑)あっ、まーくーさん。アジャイルソフトウェア開発技術者検定試験というのがありますよ! まーくー :なんですと!じゃ、学び直しも兼ねてアジャイルソフトウェア開発技術者検定試験受けるぞ!!! くまねこ :えー!急展開(笑) アジャイルソフトウェア開発技術者検定試験とは? まーくー :ところで・・・ちと聞きづらいんだけど、アジャイルソフトウェア開発技術者検定試験てなに? くまねこ :全然知らないんですか???アジャイルソフトウェア開発技術者検定試験コンソーシアムさんが運営している、アジャイル開発のスキルを客観的な尺度で分析・判定する試験のことですよ!(くまねこ調べ) アジャイルソフトウエア開発技術者検定試験 アジャイル開発のスキルを客観的な尺度で分析・判定するのが、アジャイルソフトウエア開発技術者検定試験です。 試験システムとして、CBT(Computer Based Testing)を採用しています。いつでも、どこでも受験することができます。4肢択一スタイルの問題、平均で70%の正解率を得られるよう、難易度を調整しています。 合格基準は80%以上の正解率です。 ※ アジャイルソフトウェア開発技術者検定試験のご案内「アジャイル検定とは」 より 受験料 10,000円(税別) 受験料には受験受付、試験の実施、合格者への証明書等、一切が含まれています。 ※アジャイルソフトウェア開発技術者検定試験のご案内「受験するには」 ]より まーくー :おぉ、Lv1の認定内容として「アジャイル開発に参加するのに必須となる知識が出題されます。(中略)すべてのアジャイル開発に必要なスキルが認定されます。」って書いてある。まさに自分のアジャイル開発に対する知識レベルを確認するのにちょうど良い感じだね!まさにうってつけ♪ 学習方法のイメージを立ててみた まーくー :でも、せっかくだから合格したいよねー。合格した人はどんな学習方法だったのだろうか?Webで調べてみよう! くまねこ :情報提供している人で5時間程度の学習時間で合格している人もいるみたいですよ!!! まーくー :なにぃぃぃ!あら?でもその人はかなりのアジャイル経験者みたいだね。びっくりしたぁ。私のアジャイル開発経験はちょびっと齧った程度なので アジャイル検定公式テキスト (以下テキスト)中心の学習をしっかりやらなくては!そして知識に厚みを持たせるため「アジャイルサムライ」を読み直す! くまねこ :気合入ってますね!(学習方法のイメージという割には気合に偏ってる気が・・・) まーくー :テキストは120ページほどだし、文章も読みやすそうだから繰り返し読むことができそうだよ。 くまねこ :じゃ、さっさと気合で試験申し込んじゃいましょう! まーくー :えぇぇ!(展開が早い・・・)まだ学習始めてないし・・・ くまねこ :この日が良いんじゃないですか? まーくー :(他人事だと思って・・・ええぃ、背水の陣じゃ!)その日(10日後)のテスト申し込んだよ!最寄り駅の隣の駅前がちょうど空いてたし。 くまねこ :もうやるしかないですねー!( ̄ー ̄)ニヤリ 申込みの詳しいやり方、CBTの様子などは、下記記事をご参照下さい♪ アジャイルソフトウェア開発技術者検定Lv1 受験レポート アジャイル検定公式テキストを読んで 数日後・・・ くまねこ :まーくーさんアジャイル検定の学習は進んでいますか? まーくー :ぼちぼちでんなー(笑) くまねこ :(なぜエセ関西人?) まーくー :予定通りテキストを1回読み終えたよ!このテキストって、下記の構成で簡潔に且つアジャイル開発の基礎知識が学習できるんだ。演習問題もついてるし♪問題は基本的な内容なんだけど、しっかりテキストに書いてあること理解してないと間違えてしまう問題もあったり、学んだ内容のチェックにはちょうど良い感じなんだ! アジャイル検定公式テキスト目次(抜粋) 第1章 アジャイル開発の概要 第2章 アジャイル開発に対する基礎知識 理解度確認! 演習問題 第3章 アジャイル開発におけるプロジェクト管理 理解度確認! 演習問題 第4章 開発チームの運営 理解度確認! 演習問題 第5章 アジャイル開発の各種手法 理解度確認! 演習問題 ( 書籍の詳細 アジャイル検定公式テキスト より) くまねこ :それは良かったですね! まーくー :うーむ・・・ くまねこ :どうしたんですか? まーくー :でもテキストを読むと・・・アジャイル開発に携われるエンジニアってかなり開発者よりじゃなきゃダメなんじゃないか?って印象を受けたんだよね。特に多能工のところなんてコーディング出来ない私にはちと「ハードル高っ!」って感じたのよね。。。 多能工 「アジャイル開発は、設計、実装、テストを同時に行うと説明しました。アジャイル開発を行う開発者には、これらを全てできるスキルが必要です。」 ※アジャイル検定公式テキストP8より くまねこ :僕もアジャイル開発では開発者とかテスターとか分かれてないって聞いたことあります。あっ、でもJSTQBに「アジャイルテスト担当者」ってシラバスあるくらいだから、テスターの知見を活かせるところも多々あるんじゃないですかね? まーくー :そっか、JSTQBの「アジャイルテスト担当者」のシラバスも読んでみれば、テスターのアジャイル開発への関わり方が分かるかもしれないな!そして自信を失わなくても済むかもね(笑)よしっ!アジャイルサムライは今回はスキップして、JSTQBの「アジャイルテスト担当者」のシラバスを読んでみよう! 「テスト技術者資格制度 Foundation Level Extensionシラバスアジャイルテスト担当者」を読んで 試験前日・・・ くまねこ :まーくーさん、また会いましたね。どうですか調子は? まーくー :さっとだけど、 テスト技術者資格制度 Foundation Level Extensionシラバスアジャイルテスト担当者 Version 2014.J02 )(以下JSTQBシラバス)読んだよー。 テスト技術者資格制度 Foundation Level Extensionシラバス アジャイルテスト担当者 目次(抜粋) 0. 本シラバスの紹介 0.1 本書の目的 0.2 概要 0.3 試験のための学習の目的 1 .アジャイルソフトウェア開発 1.1 アジャイルソフトウェア開発の基本 1.2 アジャイルアプローチの特徴 2.アジャイルテストの基本的な原則、プラクティスおよびプロセス 2.1 テストにおける従来型アプローチとアジャイルアプローチの違い 2.2 アジャイルプロジェクトでのテストステータス 2.3 アジャイルチームにおけるテスト担当者の役割とスキル 3.アジャイルテストの方法、技法、およびツール 3.1 アジャイルテストの方法 3.2 品質リスクの評価とテスト工数の見積り 3.3 アジャイルプロジェクトの技法 3.4 アジャイルプロジェクトにおけるツール くまねこ :じゃ、随分理解が深まったんじゃないですか? まーくー :うーん。おじさんの頭脳だと、テキストとJSTQBシラバスを絡めて理解を深めるにはもっと読み込まないとこまないとダメっぽい(笑) くまねこ :どういうことですか? まーくー :考えてみれば当然のことなんだけど、JSTQBシラバスの方はアジャイル開発の概要とともにテスト担当者に必要なことを書いているんだ。でもテキストの方は開発者目線(開発担当者、テスト担当者を分けずに)で書かれている。アジャイル開発の概要や、プロジェクト管理方法、XPやテスト駆動開発などアジャイル開発の進め方なんてところはテキストと共通なんだけど、違う目線の文章を読んだことで逆に混乱したというか・・・ くまねこ :えー!!! まーくー :読み込みが浅いせいなのか、目線の違いを整理しきれなかった。例えばJSTQBシラバスにある「チーム全体アプローチ」と同じ意味を持つ言葉をテキストで探しちゃったりして、結局見つけられなかったりとか・・・テキストの第3章なんかで言及しているのかな?って気はしたんだけど。。。 くまねこ :完全に混乱しちゃってますね。。。試験は明日ですよね?どうするんですか??? まーくー :「アジャイルソフトウェア開発技術者検定試験」なんだから、もう一回基本に戻ってテキストを復習しようと思ってる 試験が終わって・・・ くまねこ :まーくーさん、試験はどうでしたか? まーくー :前日の夜はポイントだと思うところに貼った付箋箇所を中心に再度テキストを読み直して、当日朝も喫茶店で付箋箇所の復習をして臨んだよ。 くまねこ :試験問題自体はどんな感じだったんですか? まーくー :CBTで試験問題を持ち帰れないから説明は難しいけど、問題のレベルとしてはテキストと変わらない感じで、しっかりとテキストを読み込めば、比較的答えを導き出すのは難しくなかったかも・・・ くまねこ :かも??? まーくー :やっぱり、学習方法で迷子になったりしたから十分な理解が進んでなかったみたい。4択問題で2択までには絞れるのだけど、決め切れない問題が多々あったよ。試験時間60分で60問と時間が限られているので、自信の無いところはマークを付けておいて、とりあえず最後まで問題を回答して残り時間30分。1/3くらいが悩んだ問題(多すぎ?)だったから、それを回答して残り10分。最後の最後の見直しでギリギリ1分前に回答完了って感じだった・・・ くまねこ :試験の結果ってすぐ出るんですよね?どうだったんですか???(興味本位ニャニャ) まーくー :あんまり言いたくないけど・・・ギリギリで合格!試験終了後のアンケート答えると、その次の画面で結果が表示されるから、ドキドキしたよ! くまねこ :不合格だったらこのブログ書けなかったですしね(笑) まーくー :(うっ、図星 )こんにゃろ! ※氏名とプロメトリックID、点数を加工してます。点数は恥ずかしくて出せませんでした 受験を振り返って くまねこ :いやはや、急な展開でしたが、受かっちゃうなんてさすがです!今回、試験を受けてみていかがでしたか? まーくー :そうだね、期間が短かったからこそ、自分なりには集中して学習できたかな(迷子にもなったけど)。ギリギリだったけど最低限の成果を上げられてホッとしたよ。さらに理解を深めるには、テキストの読み込みがもっと必要だと感じている。設問の中で正解はわかるけど、理解が浅いと間違えている箇所を判別するのが難しいって印象だった。 それに「アジャイルソフトウェア 開発技術者 検定」っていうぐらいだから、開発者の視点に絞って学習した方が試験的には近道だったかもしれない。テストの視点は、応用編かなぁ…実際の現場ではテスターがいることもあるみたいだけど、アジャイル開発では原則として役割がテスターのみって人はいないとされているしね… 今後の業務の中で、今回学習したことを取り入れて、テスト以外の領域にも目を向けて動いていけたらなって思ってるよ!(目指せ多能工?) 今の気分は「まだまだ知識が足りないなら、本屋に出て参考書を買えばいい!誰も「どうして?」なんて聞かないから♪Come on 」って感じかな? くまねこ :Yeeeeeeeeeeaaaaaaaaaah! \ / おわりに まーくー :いやー、結構勢いで受験を決めて動き出したけど、今回の「アジャイル検定公式テキスト」はアジャイルの原則を理解するのに良い教材だと思う(公式だしね!)。それに自分のようなおじさんでも頑張れば新しい資格も取得できる!って分かったのは良かったかな?これをきっかけに多能工を目指して、プログラミングも学習してみようかな?って思ったり思わなかったり(笑) くまねこ :まーくーさんがプログラム…!そしたら僕がテストしますね! まーくー :くまねこさんは愉快犯だからなぁ…突拍子もない観点でテストされそう(笑) 最後に妄想が膨らんでしまいましたが、ゆるっとまーくーの学び直しをご紹介させて頂きました。今回はここまでです! くまねこ :くまねこでございま~す。次回のまーくー&くまねこは、 まーくー、JSTQB ALTM試験、いったいいつ受けるの?まだでしょ!(仮) くまねこ、探索的テストを探索する?(仮) の2本でーす。 二人 :最後まで読んでいただき、ありがとうございました♪次回もまた見てねー ノシ ノシ The post ゆるっと♪学び直し!アジャイルソフトウェア開発技術者検定試験 first appeared on Sqripts .
前回は テスト自動化ツールの選定【前編】~ツールの比較表をどう活用するか | Sqripts にて、テスト自動化ツールを選ぶ際のツール比較表の活用方法について説明しました。 今回はテスト自動化ツールの中でも、とくにAI自動テストツールを選ぶ際のポイントについて考えてみたいと思います。 注意点として、本記事中では特定のツールをお勧めしたり、Yes/Noで答えていけば最適なツールが判別できるフローチャートを提示したり、といったことは行いません。ツール選定には、開発しているソフトウェアやサービス、開発スタイル、メンバーのスキル、会社のルールなどさまざまな条件が関係するためです。 誰にでもあてはまる「ツール選びの正解」は存在しませんが、本記事ではツールを選択する際のポイント・考え方を提示して、皆さんがなるべく後悔のないツール選定をするお手伝いができればと思います。 なお、本記事中の「テスト自動化」は前編と同様、E2Eテストなどテスト対象のUI、とくに画面を操作して行うようなテストのことをターゲットとします。 AI自動テストツールとは 最初に確認の意味もこめて、AI自動テストツールについて簡単に説明します。 まず、”AI自動テストツール”というと、 AIを自動でテストするツール AIで自動テストをするツール の2通りが考えられます。 厳密な定義はありませんが、本記事の執筆時点では一般的に後者の”AIで自動テストをするツール”、つまりAIの力を借りてテストの自動化や自動実行をするツールのことを指して”AI自動テストツール”と呼びます。 テストの自動化や自動実行においてAIを使うことができる場面は複数ありますが、現在の主流はテスト実行やテスト自動修復にAIを用いているものがほとんどです。テスト自動化における問題として「作成した自動テストが動かなくなる、メンテナンスが大変」などが挙げられますが、AIによるテスト自動修復機能があることによってメンテナンスの手間を減らすことができます。その結果、自動テストの運用を継続しやすい、というメリットがAI自動テストツールにはあります。 現在日本語で利用できる主なAI自動テストツールには以下があります。 mabl Autify MagicPod 他にもUIが英語のものも多数ありますし、20年以上の歴史を持つ自動化ツールにここ数年でAIが搭載されたりと、昨今のAIの盛り上がりと相まってさまざまな選択肢がある状態です。ツールを選ぶ側にとってはありがたい反面、テスト自動化にこれから取り組もうという組織においては逆にどれを選んだらよいかわからず、手が止まってしまう原因にもなっています。 何を基準に選ぶか AI自動テストツールを選ぶにあたっては、何を基準にしたらよいのでしょうか。 考慮すべきポイントはたくさんあり、本記事中でもすべては網羅しきれませんが、大きく分けて以下の2つ 機能面:ツール自体の持つ機能や特性 サポート・環境面:ツール会社のサポートや開発・コミュニティの活発度合いなど について考える必要があります。 それぞれ、詳しくみていきましょう。 機能面 機能面について最初に考えるべきポイントは、「テスト対象の操作と、期待結果との突き合わせができるか」です。 システムテストの自動化ツールは「PCアプリケーション」「Webアプリケーション」「モバイルアプリケーション」のうち1つ以上に対応しています。テスト対象に対応しているアプリケーションを候補として選ぶのが最初のステップです。どの形式のアプリケーションに対応しているかは、公式サイトやパンフレットに必ず記載があるため、調べることは簡単です。 PC、Web、モバイルアプリケーションのうち自分たちが操作したい対象に対応していることが確認できたら、次はテスト対象のバージョンやOS、フレームワークごとの対応状況を調べます。 とくに注意が必要なのは、 ブラウザの種類 Safari、IEなどのブラウザが操作できるか モバイルOS Android、iOSそれぞれ対応しているか モバイルアプリのフレームワーク Flutterなどのフレームワークに対応しているか です。意外と見落としがちな点なので、ツールの候補を絞る段階で確認をしましょう。 自動化したいテストケースのうち、これが出来なければ意味がないという重要なテストや、ハッピーパス等と呼ばれるもっとも基本的なテストをいくつかピックアップし、操作手順や結果確認の内容をテストツール会社に確認をしてもらうのもひとつの手です。万が一対応していない操作などがあっても、アップデートによる対応予定などがあれば教えてもらえる可能性もあります。 以上は選定にあたっての必須の事項、これが満たされていなければツールが使えない、という条件です。ツール選定にお困りの方でも、ここまではたどり着けた方が多いかもしれません。 問題はこの先です。必須事項を満たすツールに絞ってもまだいくつもの候補があり、明確な理由を持って選べない、選んだけれども後々使いこなせなかった、といった失敗が起こりがちです。 こうした失敗を避けるためには、 自動化する段階にだけ目をむけるのではなく、自動テストを使う段階のことを考えましょう 、というのがこれまでツール選定でつまづいた・失敗した事例から私なりに出した結論です。 よく「テスト自動化」や「システムテスト自動化」という言い方がされますが、実際には テストを自動化する 自動化したテストをメンテナンスしながら使い続ける の2つの段階があります。 自動テストツールを選択する際、「テストを自動化する」部分、つまりそのツールでテスト対象が動かせるかどうかや、「誰でも簡単に自動化できるか」などを基準に選ぶことが多いです。この点を考慮することはもちろん大切です。 しかし、実際にツールを使うにあたっては後者の「自動化したテストをメンテナンスしながら使い続ける」割合のほうが大きくなります。ここを考慮せずにツールを選ぶと、あとで失敗しやすくなってしまいます。 自分たちが自動化したテストをどのように使うのかを具体的にイメージし、それを自動化ツールが実現可能かどうかについても調べるようにしましょう。 どのように使うのか、とは、たとえば以下の要素を含みます。 自動テストをいつ、どのように実行するのか 例)週次、日次など決まったタイミングで実行 例)CI/CDパイプラインに組み込み、pushをトリガーに実行 どんな環境で、どんな用途で実行するのか 例)本番環境で死活監視的に実行 例)ステージング環境で、リリース前のリグレッションテストを実行 実行結果を誰が・どのように見るのか 例)テストエンジニアがツールのダッシュボードで確認する 例)開発者がチャットツールへの通知で確認する 例)レポートをPDF出力したものをPdMが確認する 自動テストが失敗したとき、検知・分析・テストの修正はそれぞれ誰がどんな流れで行うのか 例)テストエンジニアが自動テストの失敗を検知し、原因を分析。テストの問題であればテスト自動化エンジニアに報告し、不具合の可能性が高ければ開発者に報告 例)開発者が自動テストの失敗を検知・分析し、必要があればテストの修正まで行う 上記はあくまでも一例ですが、自組織でテスト自動化を行う際の「いつ、誰が、どう使うか」がイメージできたでしょうか?ここがハッキリしていない場合は、ツール選定の基準もあいまいになりがちです。 ツール選定の前に、まずは自分たちのやりたいことを明確にしましょう。 自動テストをCI/CDパイプラインに組み込むのであれば、既存のソースコード管理システムとの連携について調査が必要ですし、実行結果をテストエンジニアがツールのダッシュボードで見るのであれば、ダッシュボードの見やすさが検討ポイントになる。といったように、具体的な使い道を想定して、その実現可否をツール選定のポイントにするという順番で考えると、検討時の漏れを減らせます。 機能面のポイントについてまとめます。 まずはテスト対象に対して行いたい操作ができる、対応しているツールを絞り込む 個別の機能について考える際は、テストを自動化する段階だけでなく自動テストを使う場面を具体的にイメージし、必要な機能を考える サポート・環境面 前編 において、比較表に現れづらい選定ポイントの例として 使い勝手 サポートの質 開発・ユーザーコミュニティの活発さ を挙げました。 このうち、使い勝手の面はトライアルを通じて必ず確認することになるため、選定の過程で漏れる可能性は低いでしょう。 そこで、ここでは考慮から漏れがちな残りの2つ、サポートの質や開発・ユーザーコミュニティの活発さなど、ツール外部の環境面について見ていきます。 サポートの質は、AI自動テストツールに限らず、有償のツールを選定するうえでは大切なポイントです。 昨今ではツールを開発している各社にカスタマーサポートやカスタマーサクセス担当者がおり、手厚くフォローしてもらえるようになっています。 サポートについては、とくに以下の点について確認しておくとよいでしょう。 日本語サポートの有無 問い合わせの方法 メール、ツール上でのチャット、専用のSlack、など 問い合わせへの返答時間 サイト上の「*営業日以内」だけでなく、過去の実績値も オンボーディングの有無や時間、回数 ツールの導入をはじめて利用が軌道にのるまでは、ツールの効果的な使い方や既存のテストプロセスにどうツールを入れていくかなど、相談したい事項が多数発生します。 ここでサポートの協力を得てスムーズにテスト自動化を立ち上げられるかどうかも、その後の成否に関わってきます。 そのため、どのくらい手厚くサポートが受けられるのか、サポートとのやりとりはスムーズか、などは選定段階でよく見ておきましょう。 そして、サポートの対応だけでなく、開発・ユーザーコミュニティの活発さも大事になってきます。 昨今はどの自動化ツールも、開発している各社が自分たちでユーザーコミュニティを運営もしくは積極的に関わるなどで、そのツールを使っている人・会社同士のコミュニケーションを活発に行うようはたらきかけています。 ツールの操作方法を知るだけであれば、公式ドキュメントなどで十分です。しかし、実際にツールを導入・活用するには、操作方法を知っているだけではうまくいかないことも。 他社での活用事例や社内で普及・推進するための施策など、ユーザー同士で相互に情報交換を行うことができれば、テスト自動化の成功に近づきます。 こうした取り組みの背景には、AI自動テストツールの多くが買い切りではなくサブスクリプション型の料金体系になっていることがあると考えています。つまり、ツールを開発している各社にとっては、自分たちのツールを導入した企業がずっと使い続けてくれることで自社の売上が増えていきます。そのため、なるべくユーザーに解約せず使い続けてもらうために、ユーザーがうまく活用できるための取り組みを手厚く行ってくれるのです。 そこでユーザー側がツールを選ぶ際には、このコミュニティの活発さや開発の関わり度合いに関しても見ておくと役に立ちます。 具体的なポイントは以下です。 コミュニティの活発さ 参加人数(社数)、投稿の頻度、質問に対する回答がついているか 開発側の関与の度合い コミュニティ内でのQ&Aや、イベント開催などに積極的に関わっているか 雰囲気は合うか 自分たちも積極的に他ユーザーと関わっていこう、という気になるか サポート・環境面のポイントについてまとめます。 サポートのしやすさや返答のスピード感に加えて、とくにテスト自動化のスタート時に重要なオンボーディングの手厚さを確認する コミュニティにおけるユーザー間のやりとりも、ツールを活用するうえで必須の要素になっている。コミュニティの活発さや雰囲気を確認する ツール会社に対する見方を考え直す ここまで、機能面・サポートや環境面の2つの側面から、AI自動テストツールの選定ポイントを説明してきました。 機能面に関しては、ソフトウェア開発に関わる他のツールに通じるところが多かったのではないか、と思います。 一方で、サポートや環境面について意識していただきたい点があります。 それは、 テスト自動化ツールを開発・販売している会社は、ただツールを売っている「ツールベンダー」ではない ということです。 前項で説明したように、AI自動テストツールはサブスクリプション型の契約が多く、ツールを使い続けてほしい、と考えています。 そのため、ツールを開発している会社は導入した企業に対してさまざまなフォローを行い、テスト自動化をビジネスの成功につなげてほしいと思っています。 つまり、AI自動テストツールを開発している各社は顧客に対してツールを売っているのではなく、ツールを使って実現できる未来を一緒に目指すビジネスパートナーである、と捉えるべきです。AI自動テストツールを選ぶということは、ビジネスパートナーを選ぶことと同じです。 本記事のタイトルとは一見矛盾するように見えるかもしれませんが、AI自動テストツールを選ぶということは、テストを自動化して達成したい姿・目的があるはずです。達成に向けて「ツールを選ぶ」という視点とともに、ぜひ「パートナーを選ぶ」という視点でも考えてみてください。 まとめ 本記事ではAI自動テストツールを選ぶ際のポイントについて、機能面とサポート・環境面の2側面から説明をしました。 テスト自動化に限らず、ツールを選ぶ際は会社や開発チームの体制などさまざまな条件が複雑に関わってきます。そのため、読んでくださった方全員に共通するような「選び方」はなく、各々が考えなければなりません。 しかし、本記事中でも触れた以下の点、 テストを自動化する段階だけでなく、自動テストをメンテンナンスしながら運用している状態を具体的にイメージすること ツールを開発・販売している会社をツールベンダーではなくビジネスパートナーとして捉え、テストが自動化できた先の理想像を目指す手伝いをしてもらうこと これらを要として、関連する詳細な条件について検討していただければ、適切なツールを選択できるでしょう。 付録:ツールを選ぶ際のその他の確認点 記事中で触れたポイント以外で見落としがちな点についてリスト化します。 ツール選定時の参考にしてください。 自社のルール・規約への適合 ツール、SaaS利用時のルールを満たすか アカウント管理ルール(LDAP連携必須、など)を満たすか 最新環境への対応 モバイルOSの新バージョンに対して、OSリリースからテスト実行可能になるまでの期間はどのくらいか 今後の機能拡充予定・製品ロードマップ ソフトウェア開発や品質・テストに対する考え方 ツールの稼働率 直近での障害や定期メンテナンス等の状況 テスト自動化ツールの選定【前編】~ツールの比較表をどう活用するか The post テスト自動化ツールの選定【後編】~AI自動テストツールを選ぶ時に気をつけるべきポイント first appeared on Sqripts .
こんにちは、エリアマネージメント部のりきおです。 本記事では、テスト業務において検出された不具合に対して、「不具合ランク」を用いた品質分析のアプローチ方法とその活用事例についてご紹介していきます。不具合の分析作業やリスクアセスメントなどのマネジメント業務の際に少しでもご参考になれば幸いです。 準備作業 致命度・再現度の定義 まずは不具合ランクを算出するための準備として、「 致命度 (=不具合発生時のシステムやステークホルダに対する影響度合)」と「 再現度 (本記事ではユースケースとしての遭遇しやすさ)」の2軸を設定し、「Sランク」~「Dランク」をそれぞれ定義して振り分けることで、発生した不具合がどの位置づけにあるかを識別することができます。 ※今回は以下のように設定していますが、対象システムやプロジェクト規模等によってこれらの定義の基準や粒度感は異なります。 例えば、「特定の管理者アカウントが〇〇画面で✕✕操作をしたとき、アプリが落ちる」といった旨の不具合であれば、「特定の管理者アカウント(特定のユーザーかつ特定の機能)でアプリが落ちる(クラッシュ)」不具合となるため、致命度=A・再現度=B と判定することができます。 「優先度」との区別 インシデントレポート等で検出した不具合を報告する際の指標として「優先度」が挙げられることがあります。この優先度を「テスト項目での阻害影響(発生した不具合によってテストが実施できない影響度合い)」に設定し、致命度及び再現度と区別することによって、より明確な情報をステークホルダに提示することができます。 テストマネージャーや開発者はこれらを総合して判断して修正順位を割り当てることで、適切にテスト(リスク)をコントロールすることができる場合があります。 分析作業 致命度・再現度のランクの算出 続いて、上節で定義した致命度・再現度の各評点をもとに不具合ランクを算出します。以下の通り、Sランク~Dランクを評点 × ウェイトで振り分けて計算することで各ランクを量的に算出することができます。 ウェイト(重みづけ)について プロジェクトの方針やテスト対象によっては、致命度と再現度のウェイト(不具合としての重み)が異なる場合があります。例えば、「ある程度の検出数は許容するが致命度の高い不具合が発生することは問題」となるケースもありますし、反対に「内容に関わらずそもそも不具合が発生すること自体が問題」となるケースもあります。こうした基準の振り幅は、ウェイトで重み付けすることで対応することができます。 不具合ランクの算出 「致命度のランク * ウェイト (1.1)」+「再現度のランク * ウェイト (0.9)」 で求めた値を振り分けることで総合的な不具合ランクを算出します。今回は以下のように各ランクの評点範囲を設定しました。 一覧化すると以下のようになります。 準備作業で例に挙げた 致命度:A(=4.4点)・再現度:B(=2.7点) の不具合であれば、不具合ランクは「A(=7.1点)」という結果になります。 インシデントレポートでの運用 インシデントレポートといった不具合が一覧で記載されたドキュメントでも、不具合ランクを導入することができます。今回はスプレッドシートに「致命度」「再現度」「評点」「不具合ランク」の4列を導入して運用する例をご紹介します。 各不具合に対して、致命度・再現度をプルダウンリストから選択すると、評点・不具合が関数で自動出力される仕組みとなっています。 関数 参考までに評点・不具合ランク列の各関数をご紹介しておきます。 ・評点 =(IF(致命度のセル番号="S",5,IF(致命度のセル番号="A",4,IF(致命度のセル番号="B",3,IF(致命度のセル番号="C",2,IF(致命度のセル番号="D",1)))))*致命度のウェイトのセル番号)+(IF(再現度のセル番号="S",5,IF(再現度のセル番号="A",4,IF(再現度のセル番号="B",3,IF(再現度のセル番号="C",2,IF(再現度のセル番号="D",1)))))*再現度のウェイトのセル番号) ・不具合ランク =IF(評点結果のセル番号=0,"",IF(評点結果のセル番号>=9,"S",IF(AND(評点結果のセル番号>=7,評点結果のセル番号<9),"A",IF(AND(評点結果のセル番号>=5,評点結果のセル番号<7),"B",IF(AND(評点結果のセル番号>=3,評点結果のセル番号<5),"C",IF(評点結果のセル番号<3,"D")))))) 不具合ランクで品質を『見える化』する 上図のように集計した不具合をグラフ化することで、「 欠陥の偏在 」や各機能に対する影響度合いなどを『見える化(可視化)』して測定することができ、これらは不具合や品質を分析する際に有効な情報として提供できます。 欠陥の偏在とは? リリース前のテストで見つかる欠陥や運用時の故障の大部分は、特定の少数モジュールに集中する。 テストの労力を集中させるために欠陥の偏在を予測し、テストや運用での実際の観察結果に基づいてリ スク分析を行う。 JSTQB Foundation Level シラバス – 1.3 テストの 7 原則 より 活用事例 アドホックテストでの活用事例 機能テストで検出された各不具合を分析し、その結果をもとにアドホックテストを行うプロジェクトがあったとします。各機能ごとの不具合数が上図の場合、純粋な検出数だけを考慮して分析すると 「機能A > 機能B > 機能C」 の優先度でアドホックテストを行う方針となりそうですね。 しかし、不具合ランクを導入し、かつ各機能ごとの不具合ランクが以下の状態だった場合はどうでしょう。 一概に 「機能A > 機能B > 機能C」 の優先度は割り付けられないのではないでしょうか。 このように、不具合ランクを定義して不具合を分析すると、これまで定義前では見えてこなかった品質を可視化することができる場合があります。 ※不具合ランクは絶対的な指標ではありません。運用する際は、プロジェクトや不具合といったあらゆる状況を加味したうえで、適切な用途を心掛けましょう。 おわりに 品質分析は、対象のプロジェクトや検出された不具合の状態に応じて様々なアプローチ方法があります。今回ご紹介した不具合ランクの定義を含め、各方法や状況を適切に判断・運用し、商品やサービスに対してよりよい品質の分析・向上・担保に努めていきましょう! The post 不具合ランクを定義して品質を『見える化』する first appeared on Sqripts .
この連載は、登場して20年が過ぎ、成熟期を迎えつつある「アジャイル開発」を解説します。アジャイル開発については、世の中にたくさんの書籍や情報があふれていますが、アジャイルコーチとして10年以上の現場経験をもとに、あらためて学び直したい情報を中心にまとめていきます。 第4回目のテーマは、前回と同じく「従来型開発とアジャイル開発の違い」となり、前回とは異なる観点で比較を続けていきます。 この内容はUdemyで公開しているオンラインコース「 現役アジャイルコーチが教える!半日で理解できるアジャイル開発とスクラム 入門編 」の内容を元にしています。 見積もりと計画づくりの比較 見積もりと計画づくりを比較してみましょう。見積もりと計画づくりは、チーム運営でとても重要な要素だと思います。ただ、ここにも大きな違いがあるため、従来型のプロマネ経験者であれば、アジャイル開発のやりかたに少し困惑する部分があるかもしれません。 繰り返しになりますが、従来型は、作るものが決まっていて、計画を長く見通せるものが得意です。よって、リリースから逆算して計画を立てて行くのが基本になります。 やることが決まっているので、この方法が通用しますが、逆に言うと、プロジェクト初期にやることを洗い出せない場合は、うまくスケジュールを作れません。おそらく定番なのは、「経験上これぐらいかかる」とざっくり工数を見積もり、スケジュールを立てる方法でしょう。ただ、このやり方だと、早期に見積もりを正確にしなければ、やることが意外にも大きくなってしまった場合、大きなリスクになります。 アジャイル開発は、短いリリースを繰り返していきます。アジャイル開発は、小さな成果物をちょっとずつリリースしていくので、ゴールまで成果を積み上げていく形のスケジューリングになります。 短いリリースは、タイムボックスで管理を行います。タイムボックスとは、固定の時間、固定の人数という箱をイメージしてください。この箱の中にやること(ユーザーストーリー)を詰め込み、小さくリリースを繰り返していきます。何を入れるべきかを考えるために必要なのが優先順位です。 見積もりと計画づくりの比較図 プロジェクト期間の比較 プロジェクトの期間を比較します。アジャイル開発の場合は、プロジェクトじゃない場合もあるので、開発サイクルを比較します。 これまでになんども解説してきましたが、従来型は大きな開発を扱うのが得意なので、中長期的なプロジェクトが多くなります。従来型では、中途半端なプロダクトやシステムは顧客が望まないので、プロジェクトの中で完成を目指します。 アジャイル開発は、短くて1週間、長くて1ヶ月ぐらいの短期的な開発を繰り返していきます。小さく作って、大きく伸ばしていく方法です。この特性を生かした開発は、プロダクトを作りながら考え調整していくスタートアップでとても有効です。 品質の比較 品質について比較してみましょう。品質についても大きく考え方が変わってきます。 従来型の場合、テスト工程(フェーズ)が存在する場合が多いでしょう。つまり、それぞれの工程で品質を高める・維持するのも重要ですが、テスト工程の中で可能な限り品質を高めていきます。よって、テスト工程はとても重要です。 そして、基本的に、プロジェクトが終了するまでに品質を高めます。リリース後や納品後の品質向上は基本保証せず、別契約に移るケースが多いでしょう。 さて、ここまでに何度も出てきていますが、あらためて考えていただきたいことがあります。 ここで語られている品質とは何でしょうか? 従来型の場合、プロジェクトの内容や条件が契約で決まっているケースが多いので「契約通りのものが作られたか」が品質と言えます。 従来型では、作るものがだいたい決まっているので、ただしいプロセスで作れば、正しいものが出来上がるはず・・・という考え方が中心にあります。 この従来型の品質に対する考え方は、検証(Velificaiton)が中心になっていると言えます。あらかじめ作るものが決まっており、正解が存在するため、できあがった後に答え合わせできます。これがここでいう検証です。 アジャイル開発では小さな機能をどんどん開発し、リリースしていくので、小さい単位で品質を維持していきます。アジャイル開発では、リリースを繰り返すので、リリース後も品質を高められます。アジャイル開発では開発が続く限り、継続的にテストを行っていきます。 明確なテスト工程を定めると小さなウォーターフォールになるため、小さな機能をひとつひとつ作っていく形を取ります。手戻りを避けたいので、開発サイクルの後半にまとめてテスト工程を作るのを避けていこうとします。 アジャイル開発では、何が正解かわからないので、リリースごとに得られるフィードバックからヒントを学び、プロダクトをどんどん改善し、正解に近づけていこうとします。成果がでてやっと品質が高いと言えます。アジャイル開発における品質をまとめると、妥当性(Validation)が中心になっているのがわかります。 契約の比較 契約の比較をしてみましょう。 従来型の場合、やりたいことが決まっている顧客が、開発の専門組織に開発を発注するパターンが多いと思います。顧客は開発を発注し、開発側が受注する受発注の関係性になります。開発側の企業は成果物の納品まで契約に従って開発を進めます。 受発注型の契約は、納品時に「完成した」「してない」や「欲しい物じゃない」などでもめるケースが多いため、トラブルを防ぐための契約が重要です。よって、請負契約が中心です。 アジャイル開発を取り入れる企業をみると、自前で開発組織を持っているケースが多いので、社員の雇用契約以外の契約がない場合が多いです。自社で開発できるので特別な契約は必要なく、従業員が勤務時間に開発するだけです。 もし、自社の開発者が少ない場合は、外部に頼むケースもあるでしょう。しかし、何を作るかがはっきりしないアジャイル開発の場合は、完成の義務を追わない準委任契約が適しています。「ビジネスが必ず成功する機能を作ってください」と言われても約束できないので、完成の義務を負わない形にならざるをえません。 予算の比較 従来型の開発であれば、やることがすべて決まっている前提なので、プロジェクトを見積もるときに、かかる費用を綿密に計算できます。これらの費用をベースにして、年間計画を立てている企業も多いと思います。 アジャイル開発における予算管理は、よく質問される内容です。 基本的に予算の考え方は、従来型でもアジャイル開発でもかわりません。アジャイル型だと、アジャイルチームの人件費のみを定期的に計算する形が多いように思います。 アジャイル開発だと、プロダクトが続く限り開発が続くため、どこをひとくぎりとして予算を計算するか悩ましいところだと思います。たいていの企業は四半期、半期あたりで予算を立てるケースが多いように感じます。 ただ、このやりかただと、予算が固定されるので、変化に強いはずであるアジャイル開発でも柔軟な対応ができなくなってしまいます。 たとえば、プロダクトがヒットして急に人材を増やしたいときや、アクセスが集中したのでサーバを一気に増やしたい場合、予算が半年間固定されてしまうと柔軟に追加予算を使えません。対応策としては、予算を1年から3年先までの年間計画や人員計画に合わせてざっくり確保しておきます。また、予備的な追加予算も確保しておいて、緊急時に柔軟に追加投資してもいいでしょう。 様々な比較を終えて 前回と今回に分けて、従来型とアジャイル開発の様々な比較を行ってきました。こうやってひとつひとつ比べると、それぞれの違いがよく見えてきます。また、思った以上に違いが多いことにも気がつけるはずです。 そのとおり。従来型とアジャイル開発は、ほとんど違うと言ってもいいぐらい違いがあります。違いは優劣ではなく、それぞれに得意不得意があるだけでしかありません。 完璧なプロセスは存在しないため、それぞれの得意不得意を考慮してプロセスを選択していく必要があるのです。 第1回:アジャイル開発の過去、現在、未来を知ろう! 第2回:声に出して読みたいアジャイルマニフェスト 第3回:第3回 従来型開発とアジャイル開発の違い その1 The post 第4回 従来型開発とアジャイル開発の違い その2 first appeared on Sqripts .
Seleniumとは Seleniumの特徴 SeleniumはWebブラウザの操作を自動化することができるフレームワークです。現時点のSeleniumのコンポーネントは、簡単にブラウザ操作をレコードして再生できる「Selenium IDE」、プログラミング言語を利用してより複雑な操作を実現できる「Selenium WebDriver」、Selenium WebDriverを複数のOSやブラウザで動かすことができる「Selenium Grid」があります。 オープンソース(Apache License Version 2.0) であるため無料で利用できます。多くの人に長い間利用されているフレームワークであるためWeb情報や書籍が豊富にあり、 公式のサポート も充実しています。利用時に直面する問題はすでに質問されていることが多く、また解決済みである場合がほとんどです。たとえ誰も見たことがない問題が発生したとしても、Webサイトで質問をすれば世界中の利用者から情報やサポートを得ることができます。 Seleniumが活用される場面 Webアプリケーションのテスト 主にWebアプリケーションのテストで利用されています。自動テストはテストの実装に時間がかかりますが、テスト実行時間が手動テストよりも短くなる場合が多くあります(※操作対象によっては自動テストでも速度が出ない場合もあります。)。そのため、何度も繰り返し実行するリグレッションテストや、データを変更して同じテストを何十パターンも実行するデータ駆動テストで活用されています。 Jenkins、Travis Cl、BambooなどのCIツールと組み合わせると、アプリがデプロイされたら自動的にテストを実行する、毎週木曜日の21時にテストを実行するなどの定期実行が可能です。また、テストの開始終了をメールやSlackなどのメッセージングアプリに通知させたり、 単体テストフレームワークの組み込みのレポート機能 を利用することでテスト結果の視認性を高めたりすることも可能です。様々なツールやフレームワークと組み合わせることで、頻繁かつ手軽にテストができ、結果をすぐに確認できる環境を構築することができます。 クローリング、Webスクレイピング Web上の情報を広く収集するクローリングや、Web上の特定の情報を収集するWebスクレイピングで利用されています。手動でデータを収集するよりもはるかに高速に実行できます。Webアプリケーションのテストで紹介したClツールなどと組み合わせることで、定期的に新しい情報を自動収集することができます。ブログへのアクセス数を毎日取得してレポートに出力、特定のワードでSNSサイトやWebブログを検索しヒット数の推移を記録、自社および競合他社の製品の口コミや価格変動などマーケティング情報を自動収集するといった利用方法があります。 RPA Webブラウザを使用するタスクの自動化でRPAツールとして使用することができます。日報の入力やメール送信の自動操作、業務で使用するWebアプリへの自動ログイン、業務データの自動作成など、業務効率化に利用されています。 Seleniumのコンポーネント Selenium IDE Webブラウザの操作を簡単にレコーディングして再生することができます。ブラウザの拡張機能であるため、自動テストの作成にプログラミング言語は必要なく、自動テストの入門としても適しています。 動作環境 操作対象のブラウザ :Chrome、Firefox、Edge OS:上記ブラウザアプリが使用できるOS Selenium IDEは簡単に作成できますが、簡単なブラウザ操作しかできません。より複雑な操作を行いたい場合は以下のコンポーネントを利用します。 Selenium WebDriver Webブラウザを自動操作することができます。プログラミング言語でコードを書く必要があります。2018年から WebDriverはW3C(Web 標準の開発に取り組む国際コミュニティ)の推奨事項 になりました。主要なブラウザベンダーはWebDriverのサポートを行うため、安定した動作が期待できます。 動作環境 操作対象のブラウザ :Chrome、Firefox、Edge、Safari、Opera、Internet Explorer OS :Microsoft Windows、macOS、Linux 主要な プログラミング言語 :C#、Ruby、Java、Python、JavaScript (上記5つはSeleniumプロジェクトでサポートされています。) その他プログラミング言語 :Go、Haskell、Perl、PHP、R、Dart、Pharo Smalltalk (これらはSeleniumプロジェクトでサポートされていません。ライセンスも異なる場合があるため、利用する前に調査が必要です。) Selenium Grid 複数のOS、ブラウザでテストを並列実行することができます。WebDriverを利用して作成したテストスクリプトが必要です。 動作環境 Java 11 もしくはそれ以上がインストールされていること Selenium IDEの使い方 簡単に自動操作ができるSelenium IDEを紹介します。 環境構築 Chrome、Firefox、Edgeのいずれかのブラウザアプリを起動し、 こちらのリンク からSelenium IDEの拡張機能を追加します。 ※後述するSelenium WebDriverの説明でChromeを使用するため、できればChromeを利用することをお勧めします。 レコーディングする操作 テスト自動化の学習用の練習サイト にアクセス ブラウザ画面を最大表示にする 「ログイン」ボタンをクリック 「メールアドレス」をクリックして「ichiro@example.com」を入力 「パスワード」をクリックして「password」を入力 「ログイン」ボタンをクリック 「ログアウト」ボタンをクリック ブラウザを閉じる 操作のレコーディング ブラウザ右上にある拡張機能ボタンをクリックして「Selenium IDE」を起動します。 「Record a new test in a new project」を選択し、プロジェクト名を入力して「OK」ボタンをクリックします。 ベースURLに「https://hotel.testplanisphere.dev/ja/index.html」を入力して「START RECORDING」ボタンをクリックします。 手動で「レコーディングする操作」の操作を行います。 操作が終わったらSelenium IDEウィンドウの右上にある「Stop recording」ボタンをクリックします。 上記操作で作成したシナリオはこちらです。 レコードの再生 Selenium IDEウィンドウの上にある「Run current test」ボタンをクリックすると、自動でブラウザが立ち上がりレコードした操作が実行されます。操作が速すぎて見えない場合は、ストップウォッチアイコンの「Text execution speed」ボタンから実行速度を遅くすることができます。 Selenium IDEの制限 Selenium IDEが対応しているのは簡単な操作のみであり、画面スクロールなどレコードできない操作があります。また、操作対象はChrome、FireFox、Edgeのみです。Selenium IDEでレコードできない操作をしたい、別のブラウザを操作したい場合はSelenium WebDriverを利用する必要があります スクリプトのエクスポート Selenium IDEのレコードはいくつかの言語でエクスポートすることができます。 レコードタイトルを右クリックすると表示されるメニューから「Export」を選択します。 エクスポートする言語とテストフレームワークを選択します。次のSelenium WebDriverの使い方で使用するために「Python pytest」でダウンロードしています。下にあるチェックボックスはすべて空欄にしてください。 以下のpythonファイルがエクスポートされます # Generated by Selenium IDE import pytest import time import json from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support import expected_conditions from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.desired_capabilities import DesiredCapabilities class Test(): def setup_method(self, method): self.driver = webdriver.Chrome() self.vars = {} def teardown_method(self, method): self.driver.quit() def test_(self): self.driver.get("https://hotel.testplanisphere.dev/ja/index.html") self.driver.set_window_size(1874, 1096) self.driver.find_element(By.LINK_TEXT, "ログイン").click() self.driver.find_element(By.ID, "email").click() self.driver.find_element(By.ID, "email").send_keys("ichiro@example.com") self.driver.find_element(By.ID, "password").click() self.driver.find_element(By.ID, "password").send_keys("password") self.driver.find_element(By.ID, "login-button").click() self.driver.find_element(By.CSS_SELECTOR, ".btn-outline-success").click() self.driver.close() Selenium WebDriverの使い方 Python pytestでエクスポートしたSelenium IDE(Chromeを利用)のレコードを、Selenium WebDriverを利用してChromeで動かす方法を説明します。 環境構築 以下の説明ではWindowsPCを利用します。 Google Chromeブラウザを準備します。 こちらのページ からPythonをダウンロードしてインストールします。 ※pipを使用してモジュールをインストールするため、Python 3.4以降を使用してください。 自動操作に必要なPythonモジュールをインストールします。コマンドプロンプトを開いて以下のコマンドを入力します。 pip install pytest pip install selenium Chromeの「設定」>「Chromeについて」からChromeのバージョンを確認します。 こちらのページ からGoogleChromeのWebDriverのダウンロードページに遷移し、前の手順で確認したChromeのバージョンに対応するWebDriverをダウンロードします。 ダウンロードしたドライバを解凍し、ドライバファイルとエクスポートしたスクリプトファイルを同じフォルダに入れます。 スクリプトの実行 コマンドプロンプトを開き、「cd」コマンドでスクリプトとドライバを入れたフォルダに移動します。 cd {フォルダのパス} 「pytest」のコマンドを入力してスクリプトを実行します。 pytest ブラウザが自動で立ち上がり操作が実行されます。 ※実行ログに以下のエラーが表示される場合がありますが、テストに問題はありません。 エラーの詳細が気になる方は こちら を参照してください。 ERROR: Couldn't read tbsCertificate as SEQUENCE ERROR: Failed parsing Certificate まとめ SeleniumはWebブラウザの操作を自動化するためのフレームワークであり、主にWebアプリケーションのテストやWebスクレイピング、クローリングに活用されています。Seleniumには3つのコンポーネントがあります。 Selenium IDE: ブラウザの操作を簡単にレコーディングして再生することができるコンポーネントです。プログラミング言語は必要ありません。ただし、簡単な操作に限られます。 Selenium WebDriver: プログラミング言語でコードを書くことでWebブラウザを自動操作することができるコンポーネントです。主要なブラウザやプログラミング言語をサポートしており、Selenium IDEより複雑な操作が可能です。 Selenium Grid: WebDriverを使用したスクリプトを利用して、複数のOSやブラウザを操作するためのコンポーネントです。 ブラウザ操作を行う目的や操作の内容にあわせてコンポーネントを選択することが重要です。 The post WEBアプリケーションのテストができるSeleniumとは? first appeared on Sqripts .
こんにちは。 エンジニアの nobushi です。 今回は Python のマイグレーションツール Alembic を実際に運用してみたいと思います。 以前の ブログ で Alembic を紹介しましたが実際にどう運用するかについてまでは触れませんでした。 今回は GCP の CloudRun を主体としたシステムでの運用方法について紹介したいと思います。 CloudRun CloudRun は GCP のサーバーレスなコンテナ実行環境で、とても簡単にコンテナを実行することができます。 ロードバランサも内蔵されていてリクエスト数に応じて自動的にスケーリングしてくれるため、 特に何もしなくても堅牢なコンテナアプリケーションを運用できます。 しかし、この CloudRun ですが何でもできるというわけではなく HTTP 、 gRPC 等のリクエストを契機としてその処理中のみ動作する、というのが基本になっています。 ここで問題になるのが Alembic のマイグレーションです。 Alembic のマイグレーションはコマンドで動作する仕様のためコマンドの実行が必要です。 HTTP リクエストを契機としてコマンドを実行するという手もありますがセキュリティホールになりかねません。 CloudRun のままではマイグレーションを実行するのは難しそうです。 ComputeEngine ComputeEngine はプレーンな仮想マシンです。 実行に際して特に制限等がない代わりにマシンスペック、スケーリングの管理等は全て自分で行う必要があります。 もちろんコマンドを実行することも問題なくできるので Alembic のマイグレーションも実行できます。 CloudRun がオールインワンで運用しやすいのに対して ComputeEngine は自由度が高い代わりに手間がかかる、 と言ったところでしょうか。 運用案 前述の通り ComputeEngine は自由度が高く任意のコマンドも実行できるので Alembic のマイグレーションを実行するのにも特に不都合はありません。 ただし管理の手間がかかりますので、できればサーバーレスである CloudRun を使用したいというケースも多いと思います。 そこで CloudRun を主体として運用しながら Alembic のマイグレーションには ComputeEngine を使う、という方法です。 CloudRun はコンテナの実行環境ですが ComputeEngine もコンテナをそのまま実行可能です。 そのため同じアプリケーションを動かすのは難しいことではありません。 イメージとしては以下の通りです。 A は運用時の構成で、 アプリケーションのコンテナを CloudRun で実行し CloudRun は Database に接続しています。 しかし、このままでは前述の通り Alembic のマイグレーションを実行することができません。 そこで、マイグレーションが必要な変更のデプロイ時に B の構成を一時的に立ち上げます。 B は A と同じコンテナを実行し、同じデータベースに接続します。 この B でマイグレーションを実行し、完了したら削除します。 Terraform Terraform の場合、前述の [A.通常の運用構成] と [B.マイグレーション時のみ構築] を別々の実行単位(ディレクトリ)で構築します。 以下はマイグレーション側のterraformの例です。 terraform { backend "local" {} } provider "google" { project = "<project-name>" region = "us-west1" zone = "us-west1-c" } variable "container_image" {} data "google_sql_database_instance" "db" { name = "db" } data "google_service_account" "app" { account_id = "app-sample" } module "app_container" { source = "terraform-google-modules/container-vm/google" version = ">= 3.1.0, < 3.2.0" container = { image = "${var.container_image}" command = ["sh"] args = ["-c", "alembic upgrade head"] env = [ { name = "DB_HOST" value = "${data.google_sql_database_instance.db.private_ip_address}" }, ] } } resource "google_compute_instance" "migration" { name = "migration" machine_type = "e2-micro" boot_disk { initialize_params { image = module.app_container.source_image } } network_interface { network = "default" access_config {} } metadata = { gce-container-declaration = "${module.app_container.metadata_value}" } service_account { email = data.google_service_account.app.email scopes = [ "<https://www.googleapis.com/auth/cloud-platform>", ] } } ポイントは以下の通りです。 terraform { backend "local" {} } マイグレーション実行後には破棄すれば良いのでバックエンドはローカルに設定しています。 data "google_sql_database_instance" "db" { name = "db" } data "google_service_account" "app" { account_id = "app-sample" } データベースインスタンスとアプリケーション用のサービスアカウントは [A.通常の運用構成] の側で管理されている前提です。 そのため、こちらではすでにあるインスタンスを参照することになるため data で記述します。 module "app_container" { source = "terraform-google-modules/container-vm/google" version = ">= 3.1.0, < 3.2.0" container = { image = "${var.container_image}" command = ["sh"] args = ["-c", "alembic upgrade head"] env = [ { name = "DB_HOST" value = "${data.google_sql_database_instance.db.private_ip_address}" }, ] } } コンテナは [A.通常の運用構成] と同じものを私用しますが起動コマンドが異なります。 [A.通常の運用構成] ではWebサーバーの立ち上げコマンドを指定しているはずですが、 こちらでは Alembic の実行コマンドを指定しています。 これによりこちらのサーバーではマイグレーションを行うだけでコンテナは終了します。 この .tf ファイルを実行者のPC等から実行し、 ログ等でマイグレーションの正常終了を確認したらこのコンテナ環境自体が不要なので破棄 ( destroy ) します。 所感 マイグレーションを実行する場合には CloudRun のように自由度が低い場合に困りますが コンテナが主体であれば一時的に別のコンポーネントで実行することは簡単なので そういうアプローチで良いと思います。 また、マイグレーションを行うだけであれば終わったら破棄する前提にできるので セキュリティについてはあまり考慮しなくても大丈夫、という点もポイントです。 The post PythonのRDBマイグレーションツール「Alembic」をGCPのCloudRun主体の構成で運用してみる first appeared on Sqripts .
本連載では、ブロックチェーンの基本的な仕組みを解説しながら、オンチェーンデータを分析するための基本的な手法について、全8回で紹介します。 第2回となる今回は、ブロックチェーン技術が最初に発明された暗号資産(仮想通貨)であるビットコインの仕組みについて、技術的な観点やその目的などを中心に解説します。 ビットコインのデータ構造 本連載の最終的なゴールは、オンチェーンデータと呼ばれるブロックチェーン上のパブリックデータを用いたデータ分析ができるようになることですので、ブロックチェーンのデータ構造の理解が重要となります。 もちろん、異なるブロックチェーンシステムでは、データ構造が異なる部分もあります。そのため、複数のブロックチェーンのデータ構造を比較することで、多くのブロックチェーンに共通するデータ構造と、特定のブロックチェーンに固有のデータ構造が理解できるようになります。 今回はビットコインのデータ構造について概観し、次回記事にてイーサリアムのデータ構造を見ていく予定です。両者を比較することでブロックチェーンのデータ構造についての理解が深まると思います。 実データを観察する まずは、具体的なビットコインブロックチェーンの実データを見てみましょう。 ビットコインは誰もが参加可能なP2P型のアプリケーションですので、OSSとして公開されているプログラムを用いて誰でも自分のノードを立ち上げて、ビットコインのネットワークから情報を取得することができます。 しかし、ビットコインのデータをデータベース化して利用しやすくしたオンラインサービスも数多く存在していますので、まずはそれらを使ってデータにアクセスしてみましょう。 Google BigQuery Google Cloudが提供するデータウェアハウスサービスとして広く使われているBigQueryでは、同じくGoogle Cloudが提供する一般公開データセット(※1)を用いて簡単にデータ分析を始められます。 この一般公開データセットには、医療や経済、科学などをはじめ、さまざまなジャンルのデータが含まれており、主要なブロックチェーンのオンチェーンデータも提供されています。 また、BigQueryは従量課金制のクラウドサービスですが、毎月の無料枠も設定されており、課金を有効にしなくても一般公開データセットを用いた分析を始められます。詳しくはGoogle Cloudの公式ページのドキュメントを参照してください。 Google CloudとBigQueryのセットアップをおこない、テーブルID: 「bigquery-public-data.crypto_bitcoin」を検索すると、図1に示すようなビットコインのオンチェーンデータを格納したテーブルを表示できます。テーブルには「blocks」と「transactions」があり、アイコンの異なる「inputs」「outputs」は、他のテーブルから計算されたビューと呼ばれる特別なテーブルを示します。 BigQueryの画面上で特定のテーブルを選択し、「スキーマ」タブを選択するとテーブルのスキーマ定義が確認でき、「プレビュー」タブを選択するとテーブル内のサンプルデータを確認できます。 図1. BigQueryのBitcoin Cryptocurrencyデータセットにおけるblocksテーブルのサンプルデータ ※1 BigQuery の一般公開データセット Blockchain Explorer 多くのブロックチェーンには、オンチェーンデータにリアルタイムにアクセスし、トランザクションの内容などを確認するための「Explorer」と呼ばれるオンラインサービスが提供されています。 ビットコインでも、多くのExplorerサービスが提供されています。図2は、Blockchain.com Explorerと呼ばれるサービスの画面です。 図2. Blockchain.com Explorerのサービス画面 ※2 Blockchain.com Explorer トランザクションのデータ構造 実データをもとにしながら、まずはビットコインの送金の単位であるトランザクションのデータ構造について概観してみましょう。 Blockchain.com Explorerで適当なトランザクション(例: Hash ID e2d6a46ff3c0ac7977c4e56250cc8e3a3bfb566cf1fbc1f41975ce927f268daa)をクリックしてみると、そのトランザクションの概要(図3)が表示されます。 図3. Blockchain.com Explorerでのトランザクション表示例 それぞれのトランザクションには、Hash IDと呼ばれる固有のIDが振られています。トランザクションの中で特に重要なデータ構造は、「Inputs」と「Outputs」です。「Inputs」は、過去に自身がビットコインを受け取ったトランザクションを参照し、「Outputs」は新たにビットコインを送るアドレスを指定します。このビットコインのトランザクションの形式は、お金の取引を「借方」と「貸方」の2面で表現する複式簿記の考え方に似ています。 図4. 複式簿記とビットコイントランザクションの比較イメージ 複式簿記は、お金の取引を原因と結果に分け、借方と貸方に記載します。図4の複式簿記の例では、後払いで代金を受け取る権利である売掛金50,000円を、普通預金で受け取り、支払い手数料を自社負担した場合の記載を示しています。ここで、借方の普通預金と支払手数料の合計と、貸方の売掛金の合計は一致しています。 ビットコイントランザクションの考え方も、取引の原因に該当する「Inputs」と、結果に該当する「Outputs」の合計が常に一致する、という考え方です。厳密には、「Inputs」の合計を「Outputs」の合計が超えることはなく、差額がある場合はこの取引を実行するための手数料として定義されるため、結果的に両者の合計が一致する形になっています。 ブロックのデータ構造 図5. ビットコインホワイトペーパーにおけるブロックのデータ構造イメージ 上記のトランザクションを、複数まとめたデータ構造がブロックです。ブロックにも、固有のHash IDが割り振られています。そのHash IDの計算は、ある入力に対して固定長のランダムな値を返す「ハッシュ関数」と呼ばれる関数でおこなわれます。このハッシュ関数に、「そのブロックが含んでいるトランザクション」「一つ前のブロックのHash ID」「Nonce」などを入力して、ブロックのHash IDが計算されています。Nonceとは、「number used once」の略で、一度だけ使われる使い捨てのランダムな値です。 ビットコインのブロックがなぜこのようなデータ構造になっているのかを理解するためには、ビットコインが解決しようとしてる課題が何なのかという前提の説明が必要です。少し脇道に逸れますが、ビットコインが解決しようとした課題について、身近な事例に落とし込んだ解説をしてみましょう。 ビットコインが解決しようとした課題 ビットコインが解決しようとした課題を正確に理解するためには、コンピュータサイエンスにおける分散システムの基礎知識が必要です。厳密な議論をおこなうためには本連載のみでは紙面が足りませんので、ここでは「現実世界で独自の通貨を流通させる」という仮の事例を想定しながら、どのような問題が起こりうるのかを思考実験として考えみましょう。 実世界で独自の通貨を流通させる思考実験 子どもの頃、学校の教室内で独自の通貨を流通させて遊んでいたことがある、という人もいるかもしれません。ここでは、学校の教室で独自の通貨を流通させてみるという思考実験を通じて、通貨システムと分散システムの課題について考えてみます。 レベル0. 物理的な通貨の発行 教室内で独自の通貨を流通させるためには、まずは通貨の発行が必要です。よく事例として挙がるのは、瓶の王冠やシャープペンシルの芯など、ある程度の数量が均質化された品質で入手でき、個人での偽造が難しいものを通貨として利用する事例でしょう。 通貨の代表的な役割として、「価値の尺度」「交換の手段」「価値の貯蔵」が挙げられるため、これらの役割を満たすための機能性が通貨には求められます。 特に、通貨の価値を担保するためには、その通貨が使えるユーティリティを確保するという「強制通用力」と、決められた手順以外で勝手に通貨を増やしたりできない「偽造防止」という性質が重要です。 ここでは仮に、「教師の持つ印鑑で押印された紙幣」を通貨として設定してみます。教師の持つ印鑑は複製が難しく、紙幣をコピーしてもすぐに見分けられるという前提を置いて、「偽造防止」が成立しているものとします。 また、「強制通用力」としては、教師の出題する宿題などを免除したり、教師の準備した文房具などと交換できたりといったユーティリティを想定します(ここではその是非については深入りしません)。教師と生徒の間で、この独自紙幣を用いた取引が成立するようになると、通貨としての価値が確立され、生徒間同士での取引でも使われることが期待できます。 現実世界では、日本の中央銀行が偽造の困難な紙幣を発行し、法律で強制通用力を持たせる(租税貨幣論と呼ばれる考え方では、日本の居住者は日本円で税金を納めなければならないというユーティリティを持たせる)という事例に対応しています。 レベル1. データ化された通貨の発明 上記のように発行された紙幣が広く利用されるようになると、いくつかの課題が発生しそうです。例えば、大量に発行された紙幣を「毎日持ち運ぶのが大変」「枚数を数えたり額面を足し合わせたりといった計算が大変」「紛失・盗難に遭うリスクがある」といった問題が考えられるでしょう。 これらの課題を解決する一手段として、通貨をデータ化して管理するという解決方法を導入してみます。 データ化といっても、ここでは「ノートにお金のやりとりを記録した帳簿をつくる」といった形のアナログな手段を想定します。帳簿は教師が管理し、個々の取引は教師が承認し押印することで効力を持つこととします。 この仕組みは、現実世界での銀行口座や電子マネーのようなものに該当します。大量の紙幣を持ち歩かなくても自身の持っている残高を帳簿が保証してくれますし、帳簿が適切に管理されている限りは紛失や盗難などのリスクもありません。 レベル2. システムの分散化 教師が管理する帳簿を導入しても、別の課題が発生します。例えば「教室など帳簿が存在する場所でしかやりとりできない」という課題が考えられます。物理的な紙幣を使っていたときは、部室や学校外でも生徒間で紙幣を用いた取引ができていましたが、教師が管理している帳簿に記載しなければ取引が成立しないとすると、毎回教師の下にうかがって記載してもらう必要があり、利便性を損ないます。 そこで、帳簿を記載するノートを分散化することが考えられます。生徒各自が毎日、自分の取引に関連するノートの一部を持ち帰ることができ、教室外でも取引を記載できるようにします。教室外でやりとりを記録したノートは、毎日教室で教師がチェックし、押印することで効力を持つこととします。矛盾したやりとりがあれば、どちらかを無効にする等で解消します。最終的な取引の確定には最長丸1日かかりますが、教室外でも取引を発生させることができるようになります。 現実世界では、インターネットなどのネットワークを介した分散システムを構築することに該当します。 レベル3. 管理者の分権化 分散化した帳簿を導入しても、さらなる課題が存在します。最も大きな課題として、「承認者(教師)が不在のときに停止する」という問題が発生します。例えば、教師が病気や出張などで長期間不在となってしまうと、この通貨システムは承認が行われず機能停止してしまいます。 これは、処理の一部(取引の発生)を分散化したとしても、特権的な操作(取引の承認)を一部の管理者(教師)に依存してしまっていることが原因です。 この課題を解決するためには、取引の承認を生徒自身が行えるよう、権限を分権化することが考えられます。 例えば、生徒が毎日持ち回りで承認者の役割を担うようにして、もしその生徒が何らかの事情で対応できないときは、次の生徒が繰り上がりで承認作業をおこなう、といった運用です。 レベル4. 悪意を持った参加者への対策 生徒が持ち回りで承認作業をおこなう運用にした場合、一部の生徒による不正行為が発生しないか、という懸念が持ち上がることがあります。 例えば、自分が承認者のときに自分に有利なように取引を改ざんしたり、そこまではしなくとも、仲の良くない生徒からの取引申請を意図的に受け入れなかったり対応を遅れさせたり、といった検閲行為がされる可能性があります。 (こういった問題は教師が承認者を担う場合でも存在していましたが、教師への信用によって顕在化しにくい状態だったと言えます) こうした問題は、分散システムの領域では「ビザンチン将軍問題」(※3)として有名です。ビザンチン将軍問題とは、ビザンチン帝国の将軍たちが、物理的に離れた場所にいながら、敵国に攻撃するか撤退するかについてどのように合意形成すべきか、という問題です。このとき、将軍たちの中に複数名の裏切り者がいる場合でも、正しく合意形成を行うことができるアルゴリズムが考案されており、このようなアルゴリズムを「ビザンチン障害耐性」のある合意アルゴリズムと呼びます。 詳細なアルゴリズムの挙動については説明を省きますが、参加者たちがお互いに情報を共有しあい、矛盾した情報がある場合は多数決で情報を訂正しながら全体の合意を得る、といった流れがおおまかなアイデアになります。 ただし、古典的なビザンチン障害耐性アルゴリズムは、ネットワーク参加者のうち、裏切り者(ビザンチン障害ノード)が全体の3分の1未満であることが必要とされています。裏切り者が全体の3分の1以上の場合は解決手段が発見されていませんでした。 ビットコインのブロックチェーンは、このビザンチン将軍問題を、一部の妥協を許した形であれば、よりゆるい条件(ビザンチン障害ノードが全体の50%未満)で合意形成に到れるアルゴリズムを示した、と評価されることもあります。 ※3 Leslie Lamport, Robert Shostak, Marshall Pease: “The Byzantine Generals Problem”, ACM Transactions on Programming Languages and Systems, Vol.4, No.3, pp. 382-401, 1982. https://lamport.azurewebsites.net/pubs/byz.pdf レベル5. 不特定多数の参加者による利用 教室内に不正を働く可能性のある生徒が混ざっている状態において正しく取引を記録する仕組みが構築できたとしても、さらに困難な要求をされることがあります。 それは、自分たちのクラス以外の生徒など、不特定多数のメンバーも、そのクラス内で流通している通貨を使えるようにしたい、という要求です。 最初のレベル0の物理的な通貨であれば、通貨が本物であることが証明できればクラス外のメンバーなど誰でも通貨を使うことは可能でした。 しかし、物理的な紙幣を廃止し、データとしての通貨を利用しているレベル1からレベル4の状態は、いずれもクラス内の閉じた参加者の中で使われることが前提でした。 現実世界でも、現金のような物理的な通貨は、それをつかう人が誰であっても平等に使用することができる一方、銀行預金や電子マネーのようなデータ化された支払い手段は、信頼された特定の人々しか利用できない、といった制限がありました(例えば、子どもは親権者の同意がなければ銀行口座を作れない、等)。 レベル5に該当するような「不特定多数の誰もが自由に使えるデジタル通貨」の発明は、長らく開発者にとっての夢でしたが、ビットコインの登場によって初めてこの問題が実用的なレベルで解決されたのです。 余談ですが、昨今キーワードとして話題になる「Web3」という言葉は、レベル1~2のようなWebシステムを「Web2」として、レベル3以上の分権化の仕組みを実現したWebを指す言葉として使われることがあります。 レベル3~4の問題は従来の技術で解決できる範囲ではあったものの、多くのWebサービスはレベル2止まりのシステムでビジネスをおこなっていました。そこに、ビットコインがレベル5の問題を解決するソリューションとして登場し、レベル3以上のシステムの重要性が再評価されはじめています。 ただし、レベル3以上の問題のうち、どこまでを実現できていれば「Web3」と呼べるのか、という解釈については、意見が割れているところです。 ビットコインの発明 分散システムとしてのビットコインの新規性は、上記のレベル5の問題で示したような不特定多数が参加するネットワークにおいて、ビザンチン障害耐性を持った合意形成のための現実的な解を示したことです。 しかし、ビットコインの革新性はそれにとどまらず、通貨としての強制通用力の担保や、ゲーム理論的なインセンティブ設計などのアイデアもバランスよく取り込み、実運用に耐える全く新しいデジタル通貨システムを発明したことでしょう。 最後に、ビットコインの特徴といえるポイントをまとめます。 ブロックの特徴 ビットコインのブロックには、前述のとおり、そのブロックに含まれるトランザクションや、一つ前のブロックのIDなどから計算されたHash IDが振られています。 そのHash IDは、ある値以下の数値になるようにルールが設定されており、そのルールを満たす調整のために加えられたランダムなデータが前述のNonceです。 新しいブロックを生成するためには、このNonceを大量のパターンで試し、たまたまHash IDがある値以下になるようなパターンを見つけなければなりません。この処理に大量のコンピュータリソースが必要となる設計となっています。 ナカモトコンセンサス ビットコインにおいて、あるトランザクションが承認されているかどうかは、そのトランザクションを含むブロックの連鎖に対して、どれくらいのコンピュータリソースを投入されたで判断するルールとなっています。2つの矛盾するトランザクションがあった場合、そのトランザクションを含むブロックやその後続のブロックを発見するために、より多くのリソースを消費したほうを正しいとみなす、といったアイデアです。 このアイデアは「ナカモトコンセンサス」とも呼ばれ、分散システムにおける「不特定多数の参加者」という扱いにくい対象を、コンピュータの計算リソースという定量的な数値に置き換え、それによる多数決の問題に帰着させたことに革新性があります。 このアイデアの欠点として、「どのトランザクションも、あとから覆される可能性は永久にゼロにはならない」という点があり、伝統的な金融サービスからは懸念を示されることがあります。 しかし、「トランザクションの覆る可能性が、ある一定の確率以下(0.0000….1%未満等)になればゼロとみなして良い」という妥協を許せば、現実的に機能するシステムとなることが、ビットコインの運用によって証明されつつあります。 通貨としての通用力・インセンティブ設計 国の中央銀行が発行する法定通貨の場合、最終的には「その国の税金をその法定通貨で支払わなければならない」という点が、通貨としての通用力を担保している、という考え方があります。 ビットコインの場合、ビットコインを送金するための手数料をビットコインで支払わなければならないことが通用力の根拠となっていると考えられます。 また、インセンティブ設計に関しては、トランザクション手数料や新しく発行されるビットコインが、ブロック生成者に報酬として付与される仕組みとなっており、システムの持続可能性や不正の抑制を実現しています。 ビットコインの価値を信じる人は、ブロックの生成を通じてビットコインを得ることでビットコインの仕組みの維持に貢献し、ビットコインに貢献する人が増えることでさらにビットコインの信頼性が向上し価値も向上する、という好循環が生まれやすい仕組みとなっているのです。 次回予告 ビットコインの発明によって、これまで技術的に実現が困難だと思われた不特定多数の参加者で構成される分散システム上で、新しいデジタル通貨の概念である仮想通貨(暗号資産)が登場しました。 その後、ビットコインを実現した要素技術が「ブロックチェーン」という名前で抽象化され、ビットコイン以外の仮想通貨(アルトコイン)や、より汎用的な分散台帳システムに応用されはじめました。 次回の記事では、ブロックチェーン技術を用いた「ワールド・コンピュータ」の実現を目指すイーサリアムについて解説し、ビットコインと比較しながらブロックチェーン技術の理解を深めます。 第1回:ブロックチェーンとは The post 【第2回】ビットコインの仕組み first appeared on Sqripts .
こんにちは。性能テストグループのけんです。( 前回執筆時 まではテストオートメーショングループ配属でしたが、今年度から新たに性能テストグループが爆誕しました) 私が主に担当している性能テストについてあれこれ投稿していきます。 前回までは性能テストの概要やテスト計画について説明しましたが、今回は対象シナリオについて説明していきたいと思います。 <過去記事> #1 性能テストの目的と種類 #2 テスト計画 対象シナリオとは ISTQBのシラバスには性能テストの主要な活動として以下の項目が定義されています。 今回はテスト計画からテスト設計へと足を踏み入れていきます。 性能テストの主要な活動 テスト計画 テストのモニタリングとコントロール テスト分析 テスト設計 テスト実装 テスト実行 テスト完了 参考文献: 「ISTQB テスト技術者資格制度 Foundation Level Specialist シラバス 性能テスト担当者 Version 2018.J01」 性能テストの話をすると、まずどの機能または画面を対象とするのかという議論が自然に出るかと思います。 それを決定したものが対象シナリオになるのですが、もう少し詳しく説明していきます。 運用プロファイルとロードプロファイル 性能テストの対象として選定する画面や機能には、送信されるリクエストとその実行順序があります。 それらのリクエストを組み合わせた一連の流れをISTQBのシラバスでは「 運用プロファイル 」と定義しているように読み取れます。以下がISTQBのシラバスの説明文です。 システムの特定の使用方法について、アプリケーションを通じた再現可能なステップバイステップのフローを提供する。 運用プロファイルとは別に「 ロードプロファイル 」というものも定義されています。 ロードプロファイルは、運用プロファイルを使用してどのように負荷をかけるかを定義することになりますが、今回は詳細な説明については割愛します。 運用プロファイル=対象シナリオ ですが、そもそも「運用プロファイル」という字面だけを見た場合、何を指しているのかわからないですよね。 そのため当社では余計な補足説明が必要となることを避けるため「 対象シナリオ 」と定義しています。 対象シナリオについて、当社では以下の通り説明しています。 「 特定のユーザー操作を模倣して送信されるリクエストの一連の流れです。 」 手前味噌ながら簡潔かつ洗練された文言で定義されていますね。 また、「シナリオ」の前に「対象」という言葉を添えることで、それが性能テストの対象となるシナリオであることを表しており、 シナリオは選定する必要がある という意味も込めています。 対象シナリオの定義 対象シナリオを定義する上で基本方針となるのは、本番の運用でかかる負荷を再現するために、主となるユーザーの操作を模倣することです。 ユーザーがたどる動線からシナリオを作成するために以下を定義していきます。 シナリオ動線 シナリオ詳細 シナリオ動線 シナリオにどのような動線(ページまたは機能など)を含めるべきかを説明していきます。 アクセス量の多いページまたは機能 稼働中のシステムのアクセスログを確認して、アクセス量が多いリクエストを対象とする方法が最も妥当です。 「 アクセス量が多い = 負荷が高い 」となるため性能テストの対象とすべきという考え方です。 稼働前でアクセスログの確認ができない場合は、他の類似システムのデータを調査すると良いそうです。 アクセス量が多いものとしては以下があります。 直接アクセスされるURLリンク フロントとなるトップページやWeb検索でヒットしやすいページなど、外部サイト等からの入口として直接アクセスされるURLリンクのリクエストはアクセス過多になる可能性が高いため、対象にすべきと考えます。 ログイン システムを利用するために必要な動線として、最もよく使われる機能の一つです。 システムの主目的となるページまたは機能 システムの主目的となる機能や、アクセスできなくなることで損失が生じる可能性があるページまたは機能は対象とすべきです。 例としては以下があります。 ECサイトにおける「決済処理」 勤怠管理システムにおける「勤怠入力」 アンケートサイトにおける「アンケート回答送信」 また、基本的にはそこへ至るまでの動線についても同様、対象にすべきと考えます。(例外については後述します) 処理に時間がかかる機能 リクエストの処理に時間がかかる機能またはページは、その処理の完了を待つユーザーにとってはストレスと感じてしまうため、ユーザービリティを満たす性能を担保すべきと考えます。 また、処理しているサーバー側ではCPU使用率が上がって性能が低下するかもしれません。 さらに、サーバーの構成次第では他の主要な機能に影響が出る可能性もあるため、テスト対象にすべきと考えます。 以下は時間がかかる機能または処理とその例です。 機能または処理 例 大量のデータ処理 全件検索 ファイルサイズの大きなデータの処理 ファイルアップロード 複雑な演算処理 リアルタイム集計 ユーザーアクセスが多い時に実行されるバッチ(※) 定期実行バッチ(1時間毎) ※ バッチの実行が他のユーザーのアクセスに影響を及ぼさないかを確認するために対象として挙げていますが、実行時間の調整等で運用回避する方法も模索すべきです。 また、夜間バッチ等はユーザーアクセスが少ない時に実行されることから、性能テストの対象となる場合はバッチ単体のスループット計測が目的となる傾向があります。(趣旨がずれるため詳細説明は割愛します) シナリオ例 例として、ECサイトにおける主目的の機能となる決済処理のシナリオは以下の通りです。 「TOP画面(アクセス量の多いページ)」から「決済(システムの主目的となる機能)」まで一気に進むシナリオになります。 厳密に考えると全てのユーザーが決済完了までの動線を辿るわけではないので、ログインするまでのシナリオやTOP画面のみアクセスするシナリオ等を別途作成して、それぞれのシナリオで負荷量とその実行比率(あるいは割合)を調節する必要があります。 例外 前述のシナリオ例ではユーザー操作を模倣して作成していますが、テストの目的によっては必ずしもそれが正しいやり方とは限りません。 例えば、決済サーバーのスペック変更(プログラム変更なし)に伴う性能テストの場合は、決済処理のみをテストすればよいため、決済のAPIのみを単体のシナリオとして実行することもあります。余計なテストを含めないためには事前に要件を確認することが重要です。 対象外とすべきシナリオの考え方 もし対象シナリオを選定する際に「あれもこれも、あとそれもー」と大量のシナリオを実施することになった場合、負荷生成ツールの自動実行スクリプトの実装や、テスト実行にかかる作業工数が肥大化し、結局のところ期間内に終わりません(泣)ということになってしまう可能性があります。 そうならないためにプロダクトオーナーには最小限のリスクを許容していただいた上で「ムダの撤廃、作業コスト削減、生産性向上、働き方改革」などの大義名分を掲げ、強い使命感を持って対象シナリオを絞り込むための交渉をしてください。 交渉材料としてテスト対象外とすべきシナリオの考え方を説明すると、運用時に起こりうる悲観的な状況を想定し、 目的を満たせないことで起こる損失の度合い で検討すると良いと考えます。 逆に、以下の様な機能については予算、工数の都合によって優先度を下げる、あるいは除外してもよいのではないかと考えます。 機能・処理・ページ 例 使用ユーザー数が少ない機能 管理者機能 性能が低いことで直接的な損失にならない機能 ユーザー退会 類似機能、且つサーバーの同じリソースを使用している 別ページで同じ検索機能 データベースへのアクセスが発生しない静的コンテンツのみのページ 説明・ヘルプページ 付加価値として実装されている、主目的の実行とは直接関係のない機能 履歴・ポイント参照 シナリオ詳細 対象シナリオの動線が決定したら、今度はシナリオの詳細となる以下を定義していきます。 トランザクションの定義 滞留時間の設定 トランザクションの定義 トランザクションについて、ISTQBのシラバスでは以下の様に定義されています。 トランザクションとは、開始時点から1 つ以上のプロセス(リクエスト、操作、操作プロセス)が完了するまでにシステムが実行する一連のアクティビティのことである。 トランザクションの応答時間は、システムの性能を評価する目的で測定することができる。 性能テストでは、この測定値を修正や最適化が必要なコンポーネントを特定するために使う。 要するに、対象シナリオに含まれるリクエスト群の計測対象の範囲を定めたものになります。 例えば1ページビューを1トランザクションと定義した場合、メインとなるリクエストの他にサブのリクエストやリダイレクト、静的コンテンツの取得、機能実行に必要なAPI等が含まれる可能性があり、それら全ての応答結果の合計をレスポンスタイムとして計測します。 負荷生成ツールの制約 JMeterなどの負荷生成ツールを使用する場合、Webブラウザーの挙動を完全には模倣できません。(厳密には同じ様な振る舞いをするようにJMeterにプログラムを実装できる場合もありますが、それはブラウザーの挙動ではなくJMeterの挙動となります。) そのため、WebブラウザーがJavaScriptをダウンロードした場合は必要に応じてJavaScriptのプログラムを自動的に処理して機能を実行しますが、JMeterではJavaScriptのプログラムを処理しないため、JavaScriptをダウンロードするまでの時間のみが計測対象となります。 実際に確認してみると… Webブラウザー(例ではGoogle Chrome)の開発者ツールを開いた状態(F12押下)で本サイトのとあるページを開くと、以下の様に主となるリクエストの他にスタイルシート(CSS)やJavaScript(JS)等の大量の静的コンテンツを取得していることがわかります。 リクエストを一つずつ確認すると、ドメインがGoogleのサイトだったりするものが含まれるので、テストの対象外となるサイトにはアクセスしないように除外する必要があります。 また、クラウドサービスが提供しているストレージサービスに静的コンテンツを格納していてそこから直接取得しているような場合、それはクラウドサービスの性能テストになってしまうため対象外としてもよいという考え方もあります。 例 先ほどのECサイトにおける決済シナリオに対して、ページビュー毎にトランザクションを定義すると以下の通りになります。 ログイン処理とログイン後TOP画面が同じトランザクションになるのは、ログイン処理を実行すると、ログイン完了後にログイン後TOP画面へ自動的に遷移するためです。商品検索処理と決済処理も同様です。 滞留時間の設定 ユーザー操作をある程度模倣するため、ページビュー毎に滞留時間を設けます。 滞留時間の考え方は負荷生成方法によっても検討の余地がある部分ではありますが、1仮想ユーザーの動線の再現性を高めたい場合には、ユーザーが各ページをどのくらいの時間参照しているかを検討した上で設定します。 例えば、TOP画面へのアクセス後にログイン画面へ進む場合はそんなに時間を要しないですが、ログイン画面でログインIDとパスワードを入力する場合は時間がかかる想定です。(一定のユーザーはブラウザーに記憶させる場合があるので一概には言えませんが…) ただ、現実に即した長い滞留時間を設定してしまうと、その分だけ目標負荷量を達成するために仮想ユーザー(スレッド)を大量に作成することになります。 その場合、スレッドの大量生成のために負荷生成用のサーバーを増設しなければいけなくなるケースもあります。 そもそも滞留時間には個人差が大きいことから実のところ正解などないため、現実に即した滞留時間を必ずしも追求していく必要はないと考えます。 また、滞留時間は生成するための負荷量(特に時間あたりの処理時間)に大きく影響するため、負荷量の調節に滞留時間の調整が必要になる場合もあります。 必ず設定すべき滞留時間 実際にシナリオを実行する場合、1仮想ユーザー(スレッド)がシナリオを1回完了した後、また同じシナリオを最初からループ実行します。 正常時は特に問題はないのですが、例えばログインに失敗した場合にそのまま後続の処理を継続させると決済処理に進めなくてエラーが発生するので、ログインに失敗した時点でエラーとしてまた最初からループ実行するように設定しています。 もしエラーになってから次のループを開始するまでの間に滞留時間が設定されていない場合、ゼロタイムでのアクセスとなるためここで負荷が上昇してしまいます。 特に、システムへの負荷が原因で大量の仮想ユーザーがエラーとなった場合、エラーとなった仮想ユーザー全てがシナリオの最初のページへゼロタイムでアクセスしてしまうため、サーバーダウンの原因になってしまう可能性があります。 そのため当社ではシナリオの先頭には必ず滞留時間を設けることをルール化しています。 例 先ほどのECサイトにおける決済シナリオに滞留時間を定義すると以下の様になります。 ループの概念も考慮しました。 以上で対象シナリオ(運用プロファイル)の1つが完成となりました。 この対象シナリオをテスト仕様として提示する場合、当社ではドキュメントに以下の通り記載します。 対象シナリオ詳細:【EC-1】決済シナリオ 識別子 トランザクション 滞留時間(秒) EC-1-01 画面 3.0 EC-1-02 ログイン画面 6.0 EC-1-03 (ログイン処理)ログイン後TOP画面 5.0 EC-1-04 (商品検索処理)商品一覧画面 5.0 EC-1-05 商品詳細画面 5.0 EC-1-06 購入手続画面 3.0 EC-1-07 (決済処理)決済完了画面 5.0 EC-1-08 (ログイン処理)ログイン後TOP画面 5.0 ※ ※ 最後の滞留時間は【EC-1-01】TOP画面を実行する前に設定されます さいごに いかがでしたでしょうか。 今回は対象シナリオ(運用プロファイル)の話ができたので、次は対象シナリオを使ってどのように負荷をかけるのか(ロードプロファイル)の話に入っていきたいと考えています。 今後も性能テストについて深堀りしていきたいと考えていますので、次回記事もよろしくお願いいたします。 The post 性能テストのススメ #3 対象シナリオ(運用プロファイル) first appeared on Sqripts .
ISO/IEC/IEEE 29119は、ソフトウェアテストに関する国際標準であり、テストプロセスやドキュメントの標準化を目指しています。この標準で最も重要なのは、最初の4つのパートであり、それぞれが異なるテストの側面をカバーしています。本記事では、 ISO/IEC/IEEE 29119の重要な4つのパートについて解説を行います。 ISO/IEC/IEEE 29119の重要な4つのパート ISO/IEC/IEEE 29119の重要な4つのパートは以下の通りです。 Part 1: コンセプトと用語 Part 2: テストプロセス Part 3: テストドキュメント Part 4: テスト技法 それぞれのパートが相互に関連しており、ソフトウェアテストの様々な要素を網羅しています。 以下では、 ISO/IEC/IEEE 29119の各パートについて、より詳細に説明します。 Part 1: コンセプトと用語 Part 1では、ソフトウェアテストに関連する基本的なコンセプトと用語が定義されています。以下に、いくつかの重要な用語を紹介します。 a) テストケース: テスト対象の機能や特性を評価するために設計された、入力値、実行条件、および期待される結果を含む項目。 b) テストスイート: 関連するテストケースの集合。通常、テストスイートは、特定の機能や特性に焦点を当てたり、特定のテストレベルやテストタイプをカバーします。 c) テストレベル: ソフトウェア開発ライフサイクルの異なる段階で実施されるテストの階層。例えば、ユニットテスト、統合テスト、システムテスト、受け入れテストなど。 d) テストタイプ: テストの目的に基づいて分類されたテストのカテゴリ。例えば、機能テスト、性能テスト、セキュリティテスト、互換性テストなど。 Part 2: テストプロセス ISO/IEC/IEEE 29119 Part 2では、ソフトウェアテストプロセスが3つのレイヤーに分けられて規定されています。これらのレイヤーは、組織のテストプロセス、テストマネージメントプロセス、および動的テストプロセスです。以下では、それぞれのレイヤーについて更に詳細に説明します。 1) 組織のテストプロセス: 組織のテストプロセスは、企業全体で適用されるテストに関する方針や戦略を定めるレイヤーです。このレイヤーでは、以下のような活動が行われます。 a) テストポリシーの策定: テストポリシーは、組織のテストに関する基本的な原則や方針を定めた文書です。テストポリシーは、組織の品質管理体系と一致している必要があります。 b) 組織のテスト戦略の策定: 組織のテスト戦略は、組織全体のテストアプローチを定めた文書です。組織のテスト戦略は、テストの目的、範囲、リソース、リスク、スケジュール、および成果物に関する情報を提供します。 2) テストマネージメントプロセス: テストマネージメントプロセスは、プロジェクトレベルでのテスト活動を計画、監督、および制御するレイヤーです。このレイヤーでは、以下のような活動が行われます。 a) テスト計画の策定: テスト計画書は、個別のテストレベルやテストタイプに対する詳細なテスト計画を記述した文書です。テスト環境、テスト技法、テストケースの選択基準、テストスケジュール、リソース、およびリスク管理が含まれます。 b) テスト活動の進捗状況の追跡・評価: テストマネージメントプロセスは、テスト計画に基づいて、テスト活動の進捗状況を追跡し、評価します。これにより、問題点や遅れが早期に特定され、適切な対策が講じられます。 c) テスト終結: テスト活動が完了したら、テスト終結が行われます。テスト終結は、テスト活動の成果物のレビュー、テスト結果の承認、およびテスト環境の解放などが含まれます。また、テスト活動の振り返りが実施され、次のプロジェクトやテスト活動にフィードバックされます。 3) 動的テストプロセス: 動的テストプロセスは、実際にテストケースを実行し、ソフトウェアの品質を評価するレイヤーです。このプロセスは、以下のフェーズに分かれています。 a) テスト設計: このフェーズでは、テスト計画に基づいてテストケースやテストデータが作成されます。また、テスト技法が選択され、テストケースの優先順位が決定されます。 b) テスト環境とテストデータの準備: テスト環境は、テストケースを実行するために必要なハードウェア、ソフトウェア、ネットワーク、およびデータを含む環境です。テスト環境は、テスト計画に従って設定され、適切な構成と制御が行われます。テストデータは、テストに必要になるデータの要件を定義し、準備を行います。 c) テスト実施: テストケースが実行され、テスト結果が記録されるフェーズです。テストの進捗状況や問題点が監視され、必要に応じてテスト計画やテストケースが修正されます。 d) インシデント報告と追跡: テスト活動中に発見されたインシデントは、インシデント報告書に記録され、関係者に報告されます。インシデント報告書には、インシデントの詳細、再現手順、影響範囲、および優先度が記載されます。インシデント報告書は、バグ管理システムに登録され、追跡されます。 これらの3つのレイヤーは、 ISO/IEC/IEEE 29119 Part 2において相互に関連し、ソフトウェアテストプロセス全体を構成しています。各レイヤーは、ソフトウェアの品質を評価し、保証するために、独自の役割と責任を持ちます。 Part 3: テストドキュメント Part 3では、テストに関連するドキュメントのフォーマットや内容が規定されています。以下に、いくつかの重要なドキュメントを紹介します。 a) テストポリシー: 組織のテストに関する基本的な原則や方針を定めた文書。テストポリシーは、組織の品質管理体系と一致している必要があります。 b) テスト戦略: プロジェクト全体のテストアプローチを定めた文書。テスト戦略は、テストの目的、範囲、リソース、リスク、スケジュール、および成果物に関する情報を提供します。 c) テスト計画書: 個別のテストレベルやテストタイプに対する詳細なテスト計画を記述した文書。テスト環境、テスト技法、テストケースの選択基準、テストスケジュール、リソース、およびリスク管理が含まれます。 d) テストケース仕様書: テストケースの詳細を記述した文書。各テストケースには、入力値、実行条件、期待される結果が明記されています。 e) テスト結果報告書: テストの実施結果と評価を記述した文書。テスト結果報告書は、テストの成果物、達成度、品質、および問題点に関する情報を提供します。 Part 4: テスト技法 Part 4では、テストケースの設計に使用されるテスト技法が規定されています。以下に、いくつかの代表的なテスト技法を紹介します。 1) 仕様ベースのテスト技法(ブラックボックステスト技法とも呼ばれる): このアプローチでは、システムやソフトウェアの内部構造や実装を考慮せず、システムの要件や仕様に基づいてテストケースを設計します。この方法は、システムが期待される動作を満たすかどうかを確認するために使用されます。代表的な仕様ベースのテスト技法には、同値分割、境界値分析、および状態遷移テストなどがあります。 2) 構造ベースのテスト技法(ホワイトボックステスト技法とも呼ばれる): このアプローチでは、システムやソフトウェアの内部構造や実装に基づいてテストケースを設計します。この方法は、コードの品質を向上させるために使用され、コードカバレッジやパスカバレッジなどの指標を使って、コードのどの程度がテストされているかを評価します。代表的な構造ベースのテスト技法には、ステートメントカバレッジ、ブランチカバレッジ、および条件カバレッジなどがあります。 3) 経験ベースのテスト技法: 経験ベースのテスト技法は、テスターや開発者の知識、経験、直感に基づいてテストケースを設計するアプローチです。この方法では、過去の問題や欠陥の傾向、およびシステムのリスクを特定するための専門家の知識が活用されます。経験ベースのテスト技法は、エラー推定などのアプローチを含みます。 これらのテスト技法は、単独で使用されることもあれば、組み合わせて使用されることもあります。これらのテスト技法を適切に適用することで、効果的なテストケースを作成し、ソフトウェアの品質を向上させることができます。 まとめ ISO/IEC/IEEE 29119の各パートについて、以下の詳細を説明しました。 Part 1では、テストに関連する基本的なコンセプトと用語を定義し、共通言語を確立します。 Part 2では、テストプロセスの各フェーズを規定し、品質向上と効率化を図ります。 Part 3では、テストに関連する様々なドキュメントのフォーマットや内容を規定し、情報の共有や管理を容易にします。 Part 4では、テストケースの設計に使用される仕様ベースのテスト技法、構造ベースのテスト技法、および経験ベースのテスト技法を規定し、効果的なテストケースの作成が可能になります。 これらの説明を通じて、ISO/IEC/IEEE 29119について理解し、ソフトウェアテストの品質や効率を大幅に向上させることができることを願っています。 ISO/IEC/IEEE 29119とは? 学ぶ理由、メリット、デメリットを分かりやすく解説 The post ISO/IEC/IEEE 29119の重要な4つのパートと各パートの解説 first appeared on Sqripts .
こんにちは、テスシです。 私はソフトウェア開発で、システムテストに携わっています。この工程では、これまでに開発したプログラムを一つにまとめて、想定通りのものができているかどうかや本番環境でちゃんと動作するかどうかを確認しています。 はじめに 今回のお話は、プロジェクトが進行する中で発生する、環境構築ミスや思い込み(ヒューマンエラー)によるリスケジュールの回避がテーマです。環境はWeb系のある業務アプリで使用するクライアントPCやサーバーのことをイメージしてください。 効率よくテスト活動を進めるには、特にテスト開始直後の手戻り要因となりがちな環境構築ミスやヒューマンエラーといった事前に対処可能なところを十分抑えておくことが大切です。その対策を何もしなければ、本来必要のなかったスケジュール調整に繋がってしまうと私は考えています。 もしスケジュール調整が発生してしまうと、上記マイルストーンに示したような状態になります。複数のテスト実施予定の変更だけではなく、急な要員調整が発生するなど困難な状況に陥りやすいです。 同じような悩みを持っている方に、少しでも参考になれば幸いです。 テスト開始に向けた対策 環境構築前の確認6W1H 環境構築ミスやヒューマンエラーといった事前対策には6W1Hという分析技法の活用が有効です。 6W1Hは、問題や課題を解決するために、いつ、だれが、何を、どこで、なぜ、どのように行うのかを明確にする技法です。具体的には、「When(いつ)」「Where(どこで)」「Who(誰が)」「Whom(誰に)」「What(何を)」「Why(なぜ)」「How(どのように)」の7つの質問を用いて詳細に分析します。そして、それぞれの答えをまとめることで、問題を解決するための具体的な計画を立てることができます。 この分析技法を用いて、使用するテストケースから必要な環境の洗い出しを行って、どのような環境がテストで必要かをまとめておきます。 私のやり方ですが、テスト環境構築の6W1Hを行い、その分析結果を基に環境構築の進め方を整理して、最後にはストーリーというものを作ることで理解しやすくしています。そうすることで、テスト環境に関わるステークホルダー全員と認識合わせを行う際にも「自分たちはこういうテストをするので、このような環境が必要です。」ということをはっきり示すことができます。また、環境を変更する必要性が発生してしまった際にもすばやい対応ができます。(ストーリーについては後述します。) ここからは6W1Hで分析するポイントを示します。問題となりやすいポイントを中心に分析することで、環境構築時に発生する問題が見えやすく、事前に解決することが可能になってきます。 <テスト環境構築の6W1H> ・When「いつテスト環境を構築するのか」 テスト環境を構築する日程を決めます。 ・Where「どこで端末を使用するのか」 どこで端末を使用するのかを決めます。他チームと共用で使用しているような場合はテスト期間中の端末を早めに抑えておきます。 ・Who「だれがテスト環境を構築するのか」 環境構築する担当者が決まっているか確認します。また、担当者レベルでは端末の過不足が把握しにくいことがあるため、環境構築する担当者任せにはしないことです。テスト環境を使用する担当者と環境構築する担当者との間で十分に認識を合わせるか、環境構築する担当者と一緒にやるつもりでいることが大切です。 ・Whom「だれにテスト環境を使ってもらうのか」 他チームも一緒に使用する可能性がある場合は他チームの要件も確認します。 ・What「なにを使用するのか」 テストで使用する環境の組み合わせが揃っているかや端末の初期状態を確認します。 <確認するポイントの例> ・テスト対象製品の詳細バージョン ・OSの詳細バージョン(パッチなど) ・その他に使用するツールやアプリケーションと詳細バージョン ・使用するドライバー等 ・製品・アプリ・ドライバ類の初期設定と状態 ・旧製品の有無(新旧で製品比較が必要な場合など) ・Why「なぜテストするのか」 テストが必要な理由を再確認します。テストする理由と構築するテスト環境に矛盾がないことを確認します。そして、認識齟齬をなくすために、テスト担当者と必要な理由について会話することが大切です。 ・How「どのようにテストするのか」 テストしやすい端末の配置を確認します。例えば、新旧製品の画面比較をするような場合には、新旧で横並びになっているかを確認します。もし向かい側に設置されてしまうと、それだけテストがやりにくくなり、進捗が大幅に悪くなってしまいます。 ストーリーとは 環境構築の6W1Hが終わった後はストーリーを作ります。ここでのストーリーとは、テスト環境に関して6W1Hの分析結果を整理したものです。ストーリーには、必ず目的やテーマがあり、環境構築の担当者とそのステークホルダー、出来事やエピソード、それらが起こる場所や時期などが含まれます。以下にその例を示しました。ストーリーは、プロジェクトごとにテンプレートを用意すると効率がよくなると思います。 <ストーリーの例> 目的 :システムテスト開始までに期待通りのテスト環境を構築する テーマ :期待通りのテスト環境が構築されていることを余裕をもって確認する 登場人物 :αチームの環境構築の担当者A、αチームのテスト担当者B、端末を共有で使用するβチームのテスト担当者C When :〇〇要件で、システムテストを〇月〇日から□月□日まで行うことが決まった。 Where :今度のシステムテストでは複数のシステムが連携しており、システムごとに拠点が異なっている。そのため、テストをどの拠点で行うかを確認した結果、拠点Aであった。 また、テスト端末は他チームとテスト期間が重なることが判明し、共有で使用することがわかった。 Who :システムテスト開始の三営業日前までにAさんが環境構築を行う計画を立てた。 その後、Bさんが端末の配置と要件通りにテスト環境が設定されているかをチェックする。 Whom :構築したテスト環境の端末をαチームとβチームで共有して使用するため、Cさんと打ち合わせを行い、必要な数の端末を揃えた。 What :テスト環境は、OSのバージョンはなんでもよく、Microsoft Edgeを推奨ブラウザとしてメインで使用している。 業務アプリは比較のために、新旧製品を用意した。また、テストでは印刷するため、プリンタドライバが必要であり、プリンタのデフォルト設定は顧客の指定通り、モノクロ・両面に設定した。 Why :テスト目的は移行性調査である。 移行性調査とは、非互換機能を正確に把握するために行うもので、特に操作性の観点で、旧製品と同じように動作していなければならない。 How :テストは旧製品と比較する観点があるため、旧製品と新製品を用意し、その端末を横並びになるように配置した。テスト終了後はAさんが端末を次のテストのために初期設定に戻すことになっている。 このようにストーリーを基に関係者間で十分に認識合わせを行うと、どのように環境構築を行うかが明確となり、設定ミスなどの環境構築ミスや、思い込みによるテスト端末間違いなどのヒューマンエラーを未然に防ぐことに繋がります。 上記に加え、以下にテスト実施前に確認してほしいポイントを示しました。参考になれば幸いです。 テスト設計者がテスト環境を確認する テスト環境はテスト実施する上で非常に重要です。テスト環境で失敗しないためには、テスト設計者が自らの目でテスト環境が正しく構築されていることやテスト条件が揃っているかを確認する必要があります。 これで認識齟齬などのヒューマンエラーは少なくなると思います。 問題が起きてしまったときの対策 ここからは万が一それでも問題が起きてしまったときの対策について、少しだけお話したいと思います。 前述のように考えられる対策をしても、テスト開始直後は、想定外の環境構築ミスがあったり、初めて触るモノだったり、仕様理解が不十分な場合、思い込み(ヒューマンエラー)でテストを行ってしまい、期待結果にならないことがあります。 もし、このようなミスが出てしまった場合には、その場ですぐに何か暗黙知(知らなかったこと)がなかったかをよく確認することと有識者を集めて認識合わせを行うことが大事だと思います。ミス発生直後の問題意識が高い状態で確認や認識合わせを行うことでミスの原因を効率的に特定して、取り除けると考えます。その結果、今後のスケジュール遅延予防に繋げることができます。 それでも問題が続いてしまうような場合には、「顕在化してしまった問題が解決するまでチーム内で助け合う体制を作る。」ということは効果があると考えます。チーム内で助け合う体制とは、例えば問題を抱えている人が何に困っているのかを自らが発信して、同じ問題を抱える人を集めたり、解決できそうな人に協力を求めて解決していくことを指します。 この体制を作る際に大事なことは当事者が問題をどのように捉え、それをどのように解決しようとしているかを明瞭にし、解決するための期間がどのくらい必要かを当事者自らが示すことです。当事者の「やりたいこと」が明瞭化されることによって、はじめて周囲から助けられる状態になります。 おわりに 今回のお話は以上になります。いかがだったでしょうか? 環境構築ミスやヒューマンエラーをなくすために大切なことをまとめると以下の3つです。 事前対策:6W1Hを行ってストーリーを作ることで認識合わせを行い、潜在問題を早期に解決する 事後対策:チーム内で助け合う体制を作ることで、迅速に問題を解決する。また、その後に同じような問題が発生することを防ぐ 中長期的な対策:問題解決に際して当事者の「やりたいこと」を明瞭にすることで、チームとしての問題解決力向上に繋げる 最後まで読んでいただきありがとうございました。 The post 環境構築ミスやヒューマンエラーをなくすためのノウハウ first appeared on Sqripts .
この連載は、登場して20年が過ぎ、成熟期を迎えつつある「アジャイル開発」を解説します。アジャイル開発については、世の中にたくさんの書籍や情報があふれていますが、アジャイルコーチとして10年以上の現場経験をもとに、あらためて学び直したい情報を中心にまとめていきます。 第3回目のテーマは、「従来型開発とアジャイル開発の違い」です。 この内容はUdemyで公開しているオンラインコース「 現役アジャイルコーチが教える!半日で理解できるアジャイル開発とスクラム 入門編 」の内容を元にしています。 なぜ比較をするのか? 従来型の代表的な開発手法としてウォーターフォール手法があります。従来型は予測しやすい開発に適用しやすい方法なので、予測型と呼ばれたりもします。一方、アジャイル型は変化に積極的に対応していきます。そのため、適応型と呼ばれたりもします。 この記事では従来型とアジャイル開発を様々な点で比較していきます。 比較することでそれぞれの違いがわかるようになり、選択肢が増えるはずです。選択肢が増えるので、自分の置かれた状況で何を選択すべきか意思決定しやすくなるでしょう。 また、それぞれの方法の理解が進むと、上手に使えるようになるのと同時に、今やっている方法がうまくいかない場合、何が原因なのかを特定しやすくなります。 それでは、従来型とアジャイル開発の比較を進めていきましょう。 プロセス全体の比較 プロセス全体の流れの比較図 まずはプロセス全体を比較してみましょう。上記の図は従来型とアジャイル開発のプロセス全体の流れを表現したものです。 上側は従来型です。図を見てのとおり、リリースまで一方通行で、滝のように流れていく工程のためウォーターフォール型と呼ばれます。 従来型では、それぞれの工程(フェーズ)を重視しています。工程をきちんと完了させ、うまくできてない場合は、次の工程に進めません。従来型でよく失敗してしまうのは、工程がうまくいっていないのに、期限があるから次の工程に進んでしまうケースです。ちゃんとやれば、従来型でもプロジェクトは成功するはずです。 従来型は最後の最後で完成品をリリースするため、最後に大きな利益を期待する方法です。うまくいけば大きな利益を得られますが、うまく行かない場合はやり直すにも時間がかかる方法なので大損害になります。 下側はアジャイル開発を表した図です。アジャイル開発は、短い開発サイクルを繰り返しながら進んでいきます。 短い開発サイクルのたびに、小さくリリースを繰り返しながら進んでいくため、リリースのたびに利益を小さく生み出せます。従来型のように大きな利益は期待できませんが、収益は小さくとも、従来型よりはやく利益を生み出せます。さらに、小さなリリースの繰り返しでプロダクトの改善がうまくすすめば、利益を増やしていくことができます。 アジャイル開発は、短い開発サイクルを繰り返すので、変化が起きたときに柔軟に対応できます。課題の改善も、次の開発サイクルから試せるため、すばやくやり直せます。 それぞれの方法の特徴を見ると、作りたいものがクリアに見えていたり、スケジュールがはっきりしていたり、物事を予測できる情報が多いなら従来型が進めやすいと思います。 一方で、見通せる情報が小さかったり、軌道修正に柔軟に対応しなければならないのであれば、アジャイル開発が進めやすいはずです。 プロジェクト運営の比較 次にプロジェクトの運営方法の比較をしてみましょう。従来型の特徴をいくつか見ていきましょう。 管理でコントロール プロマネが全体を管理(成熟した手法PMBOKもある) 工程ごと 従来型のプロジェクト運営は、どちらかというとかっちりした運営になります。これは、お客様と契約の関係があるケースが多いからでしょう。スコープ、スケジュール、コストが大切な変数になるプロジェクト型が多く、プロジェクトマネジメント手法を活用して、全体をきちんと管理していく必要があります。管理と言うとあまりいいイメージがわかないかもしれませんが、従来型では変化をできるだけ小さくしたいと考えています。 工程に分かれているのも特徴的です。工程ごとに担当する人や企業がわかれる場合も多いので、事前に決めた責務を、各自がやり遂げていく必要があります。だから、次の工程に進む場合、間違いがないようにバトンを渡す必要があるので、必然的にドキュメントが増えます。 一方で、アジャイル開発のプロジェクト運営はどうでしょうか? 自主性を重視 サーバント・リーダーシップ 開発サイクルごと アジャイル開発は、誰かが管理するのではなく、アジャイルチームメンバー全員で管理していこうとしています。アジャイル開発は、チームの自律性を重視します。アジャイルチームは、自分たちのゴールを常に意識し、それが達成できるかを日々確認しながら開発を進めます。 となると、アジャイル開発には、プロジェクトマネージャーは必要ないのかもしれません。そのかわりに登場するのがサーバント・リーダーシップです。サーヴァントとは、召使いという意味になり、サーバントリーダーシップが、自律したアジャイルチームを支える存在になります。 アジャイル開発は短い開発サイクルでわかれています。開発サイクル こうやって比較してみると、管理を行うのは誰か? が大きな違いとしてあります。リーダーシップの点も大きく異なり、従来型のリーダーシップと比べると、サーバントリーダーシップはだいぶ毛色の違う考え方になります。 組織・チームの比較 組織・チームを比較していきましょう。従来型の特徴以下です。 工程ごとの専任チーム 階層構造 プロジェクトや工程ごとにチームは解散 従来型は、先程も書きましたが、工程ごとに担当する人や企業がわかれる場合も多い方法です。ひとつの工程に複数企業が階層的に参加するケースも多いでしょう。 チームは、プロジェクトや工程の終わりに解散するケースもあります。 次に、アジャイル開発を見ていきます。 職能横断型チーム フラット メンバー固定 アジャイル開発では、職能横断型のチームを作ろうとします。職能横断型チームとは、やりたいことを実現できる人材の揃ったアジャイルチームです。もちろん、メンバーごとに専門性が異なったりするでしょうが、チームとしてゴールするという点が考えの中心にあることを忘れないでください。チームメンバーはフラットな関係性です。 アジャイル開発の場合、チームメンバーを固定します。固定して継続的に開発を繰り返していくので、チームの練度がどんどん高まっていきます。 従来型は、管理体制下で効率よく働ける組織・チームの構成になっています。アジャイル型は、チームを中心とした構成で、成果物の価値を高めていきます。 要求・要件・仕様・タスクの比較 要求・要件・仕様・タスクを比較していきましょう。従来型の特徴は以下です。 ドキュメント重視 WBS(Work Breakdown Structure:作業分解構成図) 従来型は、要求や要件などをドキュメントにしっかり落とし込んでいきます。契約のためでもありますし、工程に分かれているプロセスなので、工程が変わるときに間違いがおこらないようにドキュメントをしっかり残します。 従来型は、実現したいことが要求として管理され、要求は形を変えて仕様やタスクへと分割されていきます。従来型の場合、はじめから「作りたいもの」が見えているので(はじめに見つけるのは難しいですがそれは別の話)、WBSなどを活用し、作業分解して達成したい期日(リリース日)に当てはめていきます。 アジャイル開発の特徴は以下になります。 ユーザーストーリー 優先順位形式 アジャイル開発では、ユーザーストーリーという仕事の単位を好みます。ユーザーストーリーの例をあげるとすれば以下のようなシンプルな文章です。 顧客として、〜〜という結果を得るために、〜〜〜をしたい 仕事をユーザへの価値提供に直結させます。たりない情報をコミュニケーションや対話で埋めていこうとします。アジャイル開発では、従来型のしっかりしたドキュメントと異なり、あえて情報が足りない状態を作っているのです。 アジャイル開発でも計画は立てますが、アプローチの方法が従来型と異なります。アジャイル開発では、ユーザーストーリーを優先順位で並べるだけです。定期的にリリースを繰り返すので、優先順位の高いものから順番に開発され、できたものからどんどんリリースされます。 従来型とアジャイル開発では、仕事の単位がそれぞれ異なっています。アジャイル開発でもユーザーストーリーをタスクに分割しますが、大切なのはタスクよりも、ユーザーストーリー。すなわち、ユーザに提供する価値です。 今回は、4つの観点で比較をしました。 プロセス全体の比較 プロジェクト運営の比較 組織・チームの比較 要求・要件・仕様・タスクの比較 次回は見積もりと計画づくり、プロジェクト期間、品質などの比較を行っていきます。 第1回:アジャイル開発の過去、現在、未来を知ろう! 第2回:声に出して読みたいアジャイルマニフェスト The post 第3回 従来型開発とアジャイル開発の違い その1 first appeared on Sqripts .
こんにちは。 テストオートメーショングループのおすしです。 自動テストのテスト結果を確認していると、手動テストなら「問題なし」と判断できるエラーが出ていることはありませんか? テスト精度にブレがないのは非常に良い点なのですが、もう少し臨機応変にできないものか…と思ってしまいます。 例えば、アプリのデータ登録機能をテストする場合に、「登録した日時(yyyy/MM/DD hh:mm)が正しく表示されていること」という確認項目があるとします。 手動テストで確認する場合は、以下の流れで問題なく確認できます。 <手動テストの場合> アプリを操作してデータを登録する アプリ上のデータの登録日時が「2023/02/03 11:59」と表示されている PCの現在日時を見ると「2023/02/03 12:00(:01))」だった 2秒くらい前に登録操作をしたから、日時の表示は正しい! (※数秒のズレが許容されるテストの場合) ところが、自動テストの場合はそうはいきません。 <自動テストの場合> アプリを操作してデータを登録する アプリ上のデータの登録日時が「2023/02/03 11:59」と表示されている 現在日時を取得すると「2023/02/03 12:00」だった 一致しないので、日時の表示は間違っている! 日時の確認で安定して自動テストを動かすには、許容されるズレを含めた確認をする必要があります。 また、SaaSのテスト自動化ツールの多くは海外サーバー上で動作しています。そのため、自動テストで現在日時を取得すると、アプリで使用しているタイムゾーンと異なる日時を取得してしまう場合があります。 指定したタイムゾーンの現在日時を取得する必要があります。 今回はこの2つの課題をJavaScriptで解決したお話です。 以下の順番で解説していきます。 【課題1】テスト実行環境のローカルタイムがテスト対象のタイムゾーンと異なる 【課題2】1秒でもずれるとテストが失敗してしまう 実装シナリオ ボタンを押した日時が記録されるWebアプリを例にして説明します。 テスト対象の画面仕様 ・トレーニングを3個選択し、「実行しました!」ボタンをクリックするとその時刻が「最終実行日時」に登録される ・日時の表示は「yyyy/mm/dd hh:mm:ss」 テスト内容 操作: 1.トレーニングリストの「チェック」欄を3箇所ONにする 2.「実行しました!」のボタンをクリックする 確認内容: チェックを入れたデータの「最終実行日時」が、ボタンをクリックした日時と一致していること レコード時の問題点 可変の現在日時を確認する機能がないため、既存機能だけではテストが実装できません。 JavaScriptのコード 【課題1】テスト実行環境のローカルタイムがテスト対象のタイムゾーンと異なる まずは手元のパソコンで現在日時を取得してみます。 ブラウザの開発ツールからコンソールウィンドウを開いて以下のJavaScriptコマンドを実行します。 Date(); <結果> Thu Feb 16 2023 14:41:57 GMT+0900 (日本標準時) 同じコマンドを、SaaSの自動化ツール上で実行してみます。 <結果> Thu Feb 16 2023 05:36:54 GMT+0000 (Coordinated Universal Time) テスト自動化ツールの実行サーバーは世界標準時のようです。 Date()はローカルタイムを取得するため、実行したマシンの影響を受けます。 テスト対象の「筋トレアプリ」は常に日本標準時で日時を記録する仕様です。 そのため、テスト時も日本標準時の時間を取得する必要があります。 自動テストツールの実行環境が常に世界標準時とは限らないため、取得したローカルタイムを世界標準時に合わせた後、日本標準時に調整することにします。 /** * 現在の日本標準時刻を返します。 * ローカルタイムにかかわらず常に日本標準時を返します。 * @returns{string} 日時 */ function getJapanStandardTime() { //現在日時を取得(1970 年 1 月 1 日 00:00:00 から経過したミリ秒数の形式) const localDateAndTime_ms = Date.now(); //ローカルタイムと世界標準時の差を取得(ミリ秒数に合わせる) const localTimezoneOffset_ms = new Date().getTimezoneOffset() * 60 * 1000; //日本標準時のオフセットを計算(ミリ秒数に合わせる) const JAPAN_TIMEZONE = 9; const JAPAN_TIMESONE_OFFSET_ms = JAPAN_TIMEZONE * 60 * 60 * 1000; //世界標準時との差をなくしてから日本標準時にする const utcDateTime = localDateAndTime_ms + localTimezoneOffset_ms; const japanDateTime = utcDateTime + JAPAN_TIMESONE_OFFSET_ms; return japanDatesAndTimes; } 【課題2】1秒でもずれるとテストが失敗してしまう 秒数までの日時を確認する場合、アプリのデータ登録と現在日時の取得が1秒でもずれると一致しないのでテストが失敗します。 そこで、テスト時にずれても許容範囲内の日時を準備します。 引数「offset_sec」に渡した秒数が許容範囲になります。 /** * 現在の日本標準時刻と、指定した秒数を±した時刻の3つを配列で返します。 * ローカルタイムにかかわらず常に日本標準時を返します。 * @param {number} offset_sec 許容範囲内とする秒数のズレ(秒) * @returns{arry} 現在時刻-offset_sec、現在時刻、現在時刻+offset_secの配列 */ function getJapanStandardTime(offset_sec) { //現在日時を取得(1970 年 1 月 1 日 00:00:00 から経過したミリ秒数の形式) const localDateAndTime_ms = Date.now(); //ローカルタイムと世界標準時の差を取得(ミリ秒数に合わせる) const localTimezoneOffset_ms = new Date().getTimezoneOffset() * 60 * 1000; //日本標準時のオフセットを計算(ミリ秒数に合わせる) const JAPAN_TIMEZONE = 9; const JAPAN_TIMESONE_OFFSET_ms = JAPAN_TIMEZONE * 60 * 60 * 1000; const offset_ms = offset_sec * 1000; //世界標準時との差をなくしてから日本標準時にする const utcDateTime = localDateAndTime_ms + localTimezoneOffset_ms; const japanDateTime = utcDateTime + JAPAN_TIMESONE_OFFSET_ms; const japanDatesAndTimes = []; japanDatesAndTimes.push(new Date(japanDateTime - offset_ms)); japanDatesAndTimes.push(new Date(japanDateTime )); japanDatesAndTimes.push(new Date(japanDateTime + offset_ms)); return japanDatesAndTimes; } <5を渡した場合の結果> 現在日時マイナス5秒、現在日時、現在日時プラス5秒の3つの日時が算出されます。 (3) [Thu Feb 16 2023 18:09:29 GMT+0900 (日本標準時), Thu Feb 16 2023 18:09:34 GMT+0900 (日本標準時), Thu Feb 16 2023 18:09:24 GMT+0900 (日本標準時)] 0:Thu Feb 16 2023 18:09:24 GMT+0900 (日本標準時) {} 1:Thu Feb 16 2023 18:09:29 GMT+0900 (日本標準時) {} 2:Thu Feb 16 2023 18:09:34 GMT+0900 (日本標準時) {} 次に、渡した日時が許容範囲内かを判定する処理を作成します。 Date.parse()は日付形式のテキストを渡すと、1970 年 1 月 1 日 00:00:00 から経過したミリ秒数の形式に変換してくれるメソッドです。 先程作成した「getJapanStandardTime」を中に入れています。 /** * 引数で渡した日時が、現在日時の±指定秒数以内であるかを判定します。 * @param date {string} "yyyy/mm/dd hh:mm:ss"形式の日時 * @param offset_sec {number} 許容範囲内とする時間のズレ(秒) * @author osushi */ function checkDateAndTimeAcceptable(date, offset_sec) { //引数チェック if (!offset_sec) { throw new Error("2番目の引数が入力されていません"); } else if (typeof(offset_sec) !== "number"){ throw new Error("offset_secは数値を入力してください") } //テストで使用する日時を取得 const dates = getJapanStandardTime(offset_sec); //テスト対象の日時、比較対象の日時をミリ秒表記にする const dateAndTimeMinus = Date.parse(dates[0]); const dateAndTimeNow = Date.parse(date); const dateAndTimePlus = Date.parse(dates[2]); if (dateAndTimeMinus < dateAndTimeNow && dateAndTimeNow < dateAndTimePlus) { console.log("日時データは許容範囲内です"); } else { console.log("dateAndTimeMinus : ",dateAndTimeMinus); console.log("dateAndTimeNow : ",dateAndTimeNow); console.log("dateAndTimePlus : ",dateAndTimePlus); throw new Error("日時データが許容範囲内ではありません"); } /** * 現在の日本標準時刻と、指定した秒数を±した時刻の3つを配列で返します。 * ローカルタイムにかかわらず常に日本標準時を返します。 * @param {number} offset_sec 許容範囲内とする秒数のズレ(秒) * @returns{arry} 現在時刻-offset_sec、現在時刻、現在時刻+offset_secの配列 */ function getJapanStandardTime(offset_sec) { //現在日時を取得(1970 年 1 月 1 日 00:00:00 から経過したミリ秒数の形式) const localDateAndTime_ms = Date.now(); //ローカルタイムと世界標準時の差を取得(ミリ秒数に合わせる) const localTimezoneOffset_ms = new Date().getTimezoneOffset() * 60 * 1000; //日本標準時のオフセットを計算(ミリ秒数に合わせる) const JAPAN_TIMEZONE = 9; const JAPAN_TIMESONE_OFFSET_ms = JAPAN_TIMEZONE * 60 * 60 * 1000; const offset_ms = offset_sec * 1000; //世界標準時との差をなくしてから日本標準時にする const utcDateTime = localDateAndTime_ms + localTimezoneOffset_ms; const japanDateTime = utcDateTime + JAPAN_TIMESONE_OFFSET_ms; const japanDatesAndTimes = []; japanDatesAndTimes.push(new Date(japanDateTime - offset_ms)); japanDatesAndTimes.push(new Date(japanDateTime )); japanDatesAndTimes.push(new Date(japanDateTime + offset_ms)); return japanDatesAndTimes; } } テスト実装 あとは「最終実行日時」のテキストを取得し、作成した関数に渡すだけです。 <テストの流れ> トレーニングリストの「チェック」欄を3箇所ONにする 「実行しました!」のボタンをクリックする ページから「最終実行日時」を取得する※1 「checkDateAndTimeAcceptable」に手順3のテキストと許容範囲とする秒数を渡して確認する ※1 ページ内の特定のテキストを取得するJavaScriptスニペットは、Autifyの公式ページで紹介されています。 Autify JavaScript Snippets おわりに 今回は以下の課題と解決案を解説しました。 【課題1】コードを実行したローカル環境の現在日時を取得してしまう → 解決策:オフセットを利用して現在日時を取得したいタイムゾーンに調整する 【課題2】1秒でもずれるとテストが失敗してしまう → 解決策:ズレの許容範囲を指定して、その範囲内かを判定する 将来、優秀なテスターのようにテストを実行してくれるAIが開発されたら、自動的に許容範囲かを判断してテストできるようになるかもしれません。 テストはすべてAIにおまかせして、実装にかける工数を増やせるようになるといいですね。 The post テスト自動化ツールで使えるJavaScriptテクニック紹介「日時を確認する」 first appeared on Sqripts .
前回のおさらい 前回の記事 では、E2Eテストの自動化において最初に気をつけるべき目的の設定と毎日テストを実行することの重要性、そして導入のステップについてお伝えしました。第2回となる今回は、実際に毎日の自動テストの運用を始めてから遭遇しがちな具体的な課題と対策についてお話ししたいと思います。 運用時にありがちな課題 自動テストの運用で、必ずと言っていいほど出てくるのが以下のような課題です。 失敗したテストの解析に時間がかかる 自動テストは実行したら当然結果を確認し、失敗したテストがあればアプリケーションの不具合によるものなのか、テストケースに誤りがあるのか、または環境要因かを切り分けてそれぞれ対処する必要があります。毎日の作業なので、ここに時間がかかり過ぎると「自動テスト=つらいもの」という認識が生まれ、自動テストをさらに有効活用していこうというモチベーションが失われてしまいます。 Flakyなテスト(結果が一定にならず、成功したり失敗したりするテスト)がある 実行の内容やどのようなアサーション(結果の確認)を入れているかにもよりますが、「同じ手順で実行しているはずなのになぜか時々失敗してしまうテスト」というのは非常によく発生します。前述の「失敗したテストの解析」をひときわ難しくするのがこのFlakyなテストです。原因はテスト対象のアプリケーションのレスポンスタイムのちょっとしたずれ、ブラウザのバージョンアップなど様々で、筆者が経験した中では「テスト用のPCでウィルスチェックが走って動作が重くなったため」というものもありました。 実行時間が長い E2EテストはUnitテストに比べてどうしても実行時間が長くなりがちです。そのため前回記事の冒頭でも「テストのピラミッド」として紹介したようにそもそも数を多く作りすぎないことも重要なのですが、必要なテストだけでも数時間となってしまうこともあります。すると前日の開発分のテストが翌日朝に終わらないという状況になり、フィードバックが遅れることで自動テストへの対応が遅くなる→メンテナンスしづらくなり陳腐化するというリスクがあります。 これらの問題をすべて解決する銀の弾丸は存在しませんが、意識しておくべきかどうかで大きく結果が変わってくるのが「テストケースの独立性」というキーワードです。 独立性とは? 「良い単体テストの条件」として有名な「F.I.R.S.Tの原則」というものがあります。それぞれFast(迅速)、Isolated/Independent(独立)、Repeatable(繰り返し可能)、Self-validating(自己検証可能)、Timely(タイムリー)の頭文字を取っています。単体テストとE2Eテストでは前提条件が大きく異なりますが、E2EテストでもIndependent(独立)とRepeatable(繰り返し可能)の原則はとても重要です。テストが独立していて繰り返し可能であるということは、つまり日次実行のときと同じ順序で実行する必要がなく1ケースだけで実行可能であり、何度実行しても同じ結果になるということです。 これが達成されていると、以下のようなメリットがあります。 失敗したときに素早く単独で再実行できる:テストケースが独立していると、失敗したテストだけを再実行することが容易になります。これにより、毎日の解析と修正が迅速に行えるようになります。 Flakinessにも対応しやすい:上と同じ理由で手軽に再実行できるためどれくらいFlakyであるかを簡単にチェックできるというメリットが1つあります。加えて、そもそもテストが繰り返し実行可能でないこと自体がFlakinessを生んでいる場合も多い(前回のテストで生成されたデータを正しく削除していないと次回のテストが失敗する等)ため、対処すべきFlakinessが減るというメリットもあります。 実行時間を短くできる:独立性が保たれているテストケースは、(多くの場合)並列実行が可能になります。その結果、テスト全体の実行時間が短縮され、開発者に素早いフィードバックを提供できます。 いかがでしょうか。ありがちな課題に応えられているように見えますね。 具体的に独立性を保つための工夫 では、テストケースの独立性を保つための具体的な工夫を紹介していきましょう。必要に応じて、AIを利用した自動テストサービス「MagicPod」を使ってどのように設定ができるかも一緒に見ていきます。 開始時の状態に依存しない 「独立性を保つ」とほとんど意味は同じなのですが、ここではテスト対象のアプリケーションを操作する上で開始時にどういう状態になっているか、というような意味でとらえていただければと思います。代表的なものとしては、「ログインしている」「ログインしていない」のような状態の違いが考えられますね。もしくは、「最初に必要なチュートリアルを終えている」「終えていない」といったものもあります。 たとえばテストケースの最初に「ログイン画面でIDとパスワードを入力してログインする」といったステップを入れてしまうと、アプリケーションの仕様にもよりますが実行開始時にすでにログイン済みだった場合は違う画面に遷移してしまって失敗することが多いでしょう。状態に依存しないテストにするためには、「(ログイン後でないと開けない)マイページに遷移する。もしログイン画面が表示されたら、IDとパスワードを入力してログインする」といったように条件分岐を使えばOKです。 実際に両者のテストケースを作成してみるとこんな風になります。 データ・アカウントを分ける これは特に全体を並列実行したいときに重要な項目です。複数のテストケースで必要なデータを共有してしまうと、1つのケースを変更したときに他のケースが動かなくなってしまい非常にメンテナンスしづらくなります。表示確認するだけのようなケースならそれほど問題ありませんが、大抵のテストではデータに何らかの変更を加えてその結果を確認すると思いますのでケース毎に分離させるのは重要です。また、テスト対象のシステムにもよりますが多くのシステムではアカウント(ユーザ)毎に異なるデータを持ちますのでアカウントから分けてしまうのも手です。あまり分けすぎると認証情報などの管理が大変になるので、筆者のチームでは アカウントの特性によらない一般的な操作のテスト→汎用のテスト用アカウント 外部ID連携、エンタープライズユーザなどアカウントの特性に合わせたテスト→ケース毎の専用アカウント といった分け方で運用しています。 使用するデータは極力テストケース内で作る 前の項目と似ていますが、さらに繰り返し可能性を高めるために「ケース1ではデータAを使う」というような分離ではなく「ケース1を実行するときは毎回必要なデータを生成する」という仕組みにしておくと便利です。こうしておけば、実行時に何らかの不具合でデータがおかしくなったとしても次回実行ではクリーンな状態で始めることができます。 「毎回データを作る」というとそれだけで実行時間が長くなってしまいそうな気がしますが、テスト対象のシステムにデータを登録できるAPIがあれば素早くデータを準備できます。MagicPodには「Web APIコール」というコマンドがあり、ブラウザの操作とは別に任意のAPIを実行することができます。この機能を使うことで、画面操作だけでは実現が難しかったり時間がかかりすぎたりする操作も簡潔に行えます。 変数の活用 データの話が続きましたが、色々と工夫を重ねても毎回全く同じ結果にはできないようなものもあります。日付が絡む処理や、ニュースのように日々変わる内容の表示などです。こういった固定できない内容を使ったテストでは、変数を活用しましょう。 たとえば、ホテルの予約ページのテストをする際に毎回未来の日付を入力しなければいけないとします。下図のように日付を格納する変数(ここでは「DATE」という名前)を用意し、常に2日後の日付を入れるようにすればテストを実行するたびに適切な日付を入力できます。 また、ニュースの見出しが記事の一覧画面と詳細画面で一致していることを確認するなら、一覧画面で見出しの内容を変数「TITLE」に保存しておき、詳細画面の見出しと比較することができます。 テスト環境の日付やニュースの内容もテスト環境の構築方法によっては頑張って固定化できなくもないですが、あまりに固執しすぎると特定のデータで起きる不具合を見逃す可能性もあります。変数を使って緩やかにテストできる部分では積極的に使ってみましょう。 毎回同じ環境で実行する こちらは少し毛色が変わって、「独立」よりも「繰り返し可能」に重点をおいたポイントです。E2Eの自動テストはとにかくちょっとした外部要因で結果が変わりやすいので、外部要因の差を排除したクリーンな環境で実行することが大切です。 最近はクラウド環境で指定のブラウザ・デバイスでテストできるサービスも沢山あります。実行環境の整備はそれだけでかなりの手間がかかりますので、テストの内容に集中するためにも環境を安定させるのはそういったサービスに任せてしまったほうが良いでしょう。 毎回同じ環境でテストを実行しているとスクリーンショットも基本的にまったく同じになるので、下のように期待値の画像とピクセル単位で比較することも可能です。 こちらは上の2つの画像から差分だけを抽出したものです。レイアウトに変更があった箇所だけがハイライトされ、OKかどうかの確認がしやすくなっています。 まとめ 今回は、自動テストの運用を無理なく続けるために意識すべきテストの独立性についてお伝えしました。「独立」というキーワードを意識することで、実行時間の長さ・解析時間の長さ・Flakyなテストによる苦痛などをある程度解決することができます。テストツールによって解決できる課題もありますが、どんなデータを使ってどのようにテストケース間の依存を防ぐかという設計の部分はツールによらず工夫が必要なのでテストエンジニアの腕の見せどころです。 次回は、さらに短い時間で自動テストの恩恵を受けるためのテストケース作成時の工夫をお伝えします。 第1回:E2Eテストの自動化を最速で成功させる秘訣 The post 第2回:毎日の自動テストを無理なく続けるためのキーワード first appeared on Sqripts .
お久しぶりです。インフラソリューション部の“のなか”です。 今回は 前回 に続き、AWS上で稼働している既存WordPressを更新する際にかかっているデプロイ時間を30分から5分に圧縮した話をしていきます。 前編ではWordPressを構築しましたが、後編では自動デプロイを設定していきます。 それではWordPressのデプロイ自動化の後編を始めていきましょう! 注意点 – 前編 で説明した内容は省略 前提条件 – 前編 を実施済み – SSHの公開鍵と秘密鍵を作成済み – WSL2にzipパッケージをインストール済み 用語説明 EC2 Image Builderとは 後編に入る前にEC2 Image Builderについて説明します。 EC2 Image Builderとは公式ドキュメントのユーザーガイドで以下のように説明されています。 EC2 Image Builder is a fully managed AWS service that helps you to automate the creation, management, and deployment of customized, secure, and up-to-date server images. You can use the AWS Management Console, AWS Command Line Interface, or APIs to create custom images in your AWS account. 説明を1行でまとめるとイメージの作成、管理、デプロイを自動化するツールです。例えば 公式ドキュメント では以下の図で説明されています。 以下の順番で実行し、この一連の処理を イメージパイプライン と言います。 1. イメージからインスタンスを起動 2. (ビルド)元のイメージにソフトウェアをインストール 3. インスタンスを終了 4. ソフトウェアをインストールイメージからインスタンスを起動 5. (テスト)作成したイメージをテスト 6. インスタンスを終了 7. テストしたイメージから ゴールデンイメージ を作成 イメージのビルドとテストが可能になるため、イメージの管理やセキュリティの担保がマネージドサービスから行えますが、2回インスタンスの起動と終了が行われるため、実行時間が30分程度かかります。 ※実行時間はイメージ毎で異なります。 ドキュメントルート配下をデプロイするだけであれば、CodeDeployのみでも良いですが、EC2自体を更新したい場合は試してみると良いと思います。 後編のリソース作成手順 手順 1. TerraformでCodeCommitを作成 2. TerraformでDeployを作成 3. TerraformでCodePipelineを作成し、動作確認 4. TerraformでEC2 Image Builderを作成 5. TerraformでLambdaを作成 6. TerraformでCodePipelineにLambdaを追加し、動作確認 後編のシステム図と使用するAWSのリソース システム図 使用するAWSのリソース – CodeCommit – CodeDeploy – CodePipeline – S3 – Lambda – EC2ImageBuilder 後編のディレクトリ構成 Terraform 後編の ~/terraform-blog は以下のディレクトリ構成になります。 . ├── .terraform │ └── providers │ └── registry.terraform.io │ └── hashicorp │ └── aws │ └── 4.57.1 │ └── linux_amd64 │ └── terraform-provider-aws_v4.57.1_x5 ├── .terraform.lock.hcl ├── README.md ├── aws_asg.tf ├── aws_codepipeline.tf ├── aws_data.tf ├── aws_ec2.tf ├── aws_iam.tf ├── aws_imagebuilder.tf ├── aws_s3.tf ├── aws_vpc.tf ├── lambda_function.py ├── lambda_function.py.zip ├── provider.tf ├── terraform.tfstate └── terraform.tfstate.backup 構築 IAMを設定 1. AWSのコンソールにサインインし、Basic_Groupユーザーグループに以下ポリシーをアタッチ – AmazonS3FullAccess – AutoScalingFullAccess – AWSCodeCommitFullAccess – AWSCodeDeployFullAccess – AWSCodePipeline_FullAccess – AWSImageBuilderFullAccess – AWSLambda_FullAccess 1. vi ~/terraform-blog/aws_iam.tf でROLE_BLOGロールのポリシーを追加 #---------------------------------------- # IAMロールを作成 #---------------------------------------- resource "aws_iam_role" "ROLE_BLOG" { name = "ROLE_BLOG" assume_role_policy = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}" description = "Allows EC2 instances to call AWS services on your behalf." path = "/" managed_policy_arns = [ "arn:aws:iam::aws:policy/AmazonEC2FullAccess", "arn:aws:iam::aws:policy/AmazonSSMFullAccess", # 追加 "arn:aws:iam::aws:policy/AmazonS3FullAccess", "arn:aws:iam::aws:policy/AWSCodePipeline_FullAccess", "arn:aws:iam::aws:policy/AWSImageBuilderFullAccess" ] tags = { Name = "ROLE_BLOG" } } CodeCommitを設定 まずはドキュメントルートを自動デプロイするため以下システムを構築していきます。 ※①~④の説明は 前編 を確認して下さい。 1. BlogUserのセキュリティ認証情報画面で、AWS CodeCommitのSSH公開キーに作成済みのSSH公開鍵をアップロードして、SSHキーIDをメモ 1. WSL2で vi ~/terraform-blog/aws_codepipeline.tf を実行し、CodeCommitの設定を追記 resource "aws_codecommit_repository" "BlogCodecommitRepo" { repository_name = "BlogCodecommitRepo" tags = { Name = "BlogCodecommitRepo" } } 1. Terraformを実行し、CodeCommitにリポジトリを作成 terraform planterraform apply 1. CMSサーバー(EC2)とCMSサーバー(ASG)にSSHし、AWS CodeCommitのSSH公開キーに登録した公開鍵をauthorized_keysに追記し、秘密鍵を配置 以下は秘密鍵がid_rsaの場合のディレクトリ例です。 [root@ip-10-0-0-10 .ssh]# ls -al合計 8drwx------ 2 root root 43 5月 16 10:26 .dr-xr-x--- 6 root root 185 5月 16 10:25 ..-rw------- 1 root root 553 5月 16 09:45 authorized_keys-rw------- 1 root root 1675 5月 16 10:25 id_rsa 1. vi ~/.ssh/config でSSHの設定ファイルを作成 以下は秘密鍵がid_rsaの場合の設定ファイルです。 Host git-codecommit.*.amazonaws.com User (1でメモしたSSHキーIDをここに入力) IdentityFile ~/.ssh/id_rsa 1. chmod 600 ~/.ssh/config でSSHの設定ファイルの権限を変更 drwx------ 2 root root 76 5月 12 10:35 .dr-xr-x--- 6 root root 203 5月 12 10:35 ..-rw------- 1 root root 553 5月 8 10:19 authorized_keys-rw------- 1 root root 89 5月 8 10:58 config-rw------- 1 root root 1675 5月 2 09:56 id_rsa-rw-r--r-- 1 root root 1230 5月 8 13:53 known_hosts 1. CMSサーバー(EC2)にSSHし、 vi /var/www/html/appspec.yml で自動デプロイするための設定ファイルを作成 version: 0.0os: linuxfiles: - source: / destination: /var/www/htmlfile_exists_behavior: OVERWRITE 1. CodeCommitのリポジトリにドキュメントルート配下をpush cd /var/www/html/yum install -y gitgit init .git add .git commit -m "first push"git push --set-upstream ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/BlogCodecommitRepo master ※以降は以下のコマンドでCodeCommitにpushします。 cd /var/www/html/git add .git commit -m "change config"git push CodeDeployを設定 1. WSL2で vi ~/terraform-blog/aws_codepipeline.tf を実行し、CodeDeployの設定を追記 #---------------------------------------- # CodeDeployのアプリケーションを作成 #---------------------------------------- resource "aws_codedeploy_app" "BlogCodedeployApp" { name = "BlogCodedeployApp" compute_platform = "Server" tags = { Name = "BlogCodedeployApp" } } #---------------------------------------- # CodeDeployのデプロイグループを作成 #---------------------------------------- resource "aws_codedeploy_deployment_group" "BlogCodedeployDeployGroup" { app_name = aws_codedeploy_app.BlogCodedeployApp.name deployment_group_name = "BlogCodedeployDeployGroup" service_role_arn = aws_iam_role.CodeDeployServiceRole.arn deployment_config_name = "CodeDeployDefault.AllAtOnce" autoscaling_groups = [aws_autoscaling_group.BlogASG.name] auto_rollback_configuration { enabled = true events = ["DEPLOYMENT_FAILURE"] } deployment_style { deployment_option = "WITHOUT_TRAFFIC_CONTROL" deployment_type = "IN_PLACE" } tags = { Name = "BlogCodedeployDeployGroup" } } 1. vi ~/terraform-blog/aws_iam.tf でCodeDeployのサービスロールの設定を追記 #---------------------------------------- # IAMロールを作成 #---------------------------------------- resource "aws_iam_role" "CodeDeployServiceRole" { name = "CodeDeployServiceRole" assume_role_policy = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"codedeploy.amazonaws.com\"},\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}" description = "Allows CodeDeploy to call AWS services such as Auto Scaling on your behalf." path = "/" managed_policy_arns = [ "arn:aws:iam::aws:policy/AWSCodeDeployFullAccess", "arn:aws:iam::aws:policy/AmazonEC2FullAccess" ] tags = { Name = "CodeDeployServiceRole" } } 1. Terraformを実行し、CodeDeployを作成 terraform planterraform apply 1. CMSサーバー(EC2)とCMSサーバー(ASG)にSSHし、CodeDeployのエージェントをインストール sudo su -yum -y install ruby wget gitwget -P /tmp https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/installchmod +x /tmp/install/tmp/install auto 1. CMSサーバー(ASG)にSSHし、WordPressのドキュメントルートをクローン cd /var/www/html/rm -rf /var/www/html/*git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/BlogCodecommitRepo . CodePipelineを設定 1. vi ~/terraform-blog/aws_s3.tf を実行し、データを格納するためのS3のバケットを作成 resource "aws_s3_bucket" "blogbucketwp" { bucket = "blogbucketwp" tags = { Name = "blogbucketwp" } } resource "aws_s3_bucket_server_side_encryption_configuration" "blogasbssec" { bucket = aws_s3_bucket.blogbucketwp.bucket rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } bucket_key_enabled = true } } resource "aws_s3_bucket_request_payment_configuration" "blogbucketwpasbrpc" { bucket = aws_s3_bucket.blogbucketwp.bucket payer = "BucketOwner" } 1. WSL2で vi ~/terraform-blog/aws_codepipeline.tf を実行し、CodePipelineの設定を追記 #---------------------------------------- # CodeCommitのリポジトリを作成 #---------------------------------------- resource "aws_codecommit_repository" "BlogCodecommitRepo" { repository_name = "BlogCodecommitRepo" tags = { Name = "BlogCodecommitRepo" } } #---------------------------------------- # CodeDeployのアプリケーションを作成 #---------------------------------------- resource "aws_codedeploy_app" "BlogCodedeployApp" { name = "BlogCodedeployApp" compute_platform = "Server" tags = { Name = "BlogCodedeployApp" } } #---------------------------------------- # CodeDeployのデプロイグループを作成 #---------------------------------------- resource "aws_codedeploy_deployment_group" "BlogCodedeployDeployGroup" { app_name = aws_codedeploy_app.BlogCodedeployApp.name deployment_group_name = "BlogCodedeployDeployGroup" service_role_arn = aws_iam_role.CodeDeployServiceRole.arn deployment_config_name = "CodeDeployDefault.AllAtOnce" autoscaling_groups = [aws_autoscaling_group.BlogASG.name] auto_rollback_configuration { enabled = true events = ["DEPLOYMENT_FAILURE"] } deployment_style { deployment_option = "WITHOUT_TRAFFIC_CONTROL" deployment_type = "IN_PLACE" } tags = { Name = "BlogCodedeployDeployGroup" } } #---------------------------------------- # CodePipelineを作成 #---------------------------------------- resource "aws_codepipeline" "BlogCodepipelinePipeline" { name = "BlogCodepipelinePipeline" role_arn = aws_iam_role.ServiceRoleCodePipeline.arn stage { name = "Source" action { name = "Source" namespace = "SourceVariables" category = "Source" owner = "AWS" provider = "CodeCommit" version = "1" region = "ap-northeast-1" output_artifacts = ["SourceArtifact"] configuration = { BranchName = "master" OutputArtifactFormat = "CODE_ZIP" PollForSourceChanges = "true" RepositoryName = aws_codecommit_repository.BlogCodecommitRepo.repository_name } } } stage { name = "Deploy" action { name = "Deploy" namespace = "DeployVariables" category = "Deploy" owner = "AWS" provider = "CodeDeploy" version = "1" region = "ap-northeast-1" input_artifacts = ["SourceArtifact"] configuration = { ApplicationName = aws_codedeploy_app.BlogCodedeployApp.name DeploymentGroupName = aws_codedeploy_deployment_group.BlogCodedeployDeployGroup.deployment_group_name } } } artifact_store { location = aws_s3_bucket.blogbucketwp.bucket type = "S3" } tags = { Name = "BlogCodepipelinePipeline" } } 1. vi ~/terraform-blog/aws_iam.tf でCodePipelineのサービスロールの設定を追記 #---------------------------------------- # IAMロールを作成 #----------------------------------------] resource "aws_iam_role" "ServiceRoleCodePipeline" { name = "ServiceRoleCodePipeline" assume_role_policy = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"codepipeline.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}" description = "" path = "/service-role/" managed_policy_arns = [ "arn:aws:iam::aws:policy/AWSCodePipeline_FullAccess", "arn:aws:iam::aws:policy/AWSCodeCommitFullAccess", "arn:aws:iam::aws:policy/AWSCodeDeployFullAccess", "arn:aws:iam::aws:policy/AWSLambda_FullAccess", "arn:aws:iam::aws:policy/AmazonS3FullAccess", "arn:aws:iam::aws:policy/AWSImageBuilderFullAccess", "arn:aws:iam::aws:policy/AmazonEC2FullAccess" ] tags = { Name = "ServiceRoleCodePipeline" } } 1. Terraformを実行し、CodePipelineを作成 terraform planterraform apply 1. CodePipelineのSourceとDeployが成功することを確認 自動デプロイの動作確認 1. CMSサーバー(EC2)にSSHし、権限を変更 sudo chmod 777 -R /var/www/html/wp-content/* 1. CMSサーバー(EC2)の管理画面のテーマエディターで背景色を修正 以下はデフォルトのテーマTwenty Twenty-Oneのstyle.cssのbodyの背景色を白色に修正した例です。 1. CMSサーバー(ASG)にブラウザからアクセスし、背景色がデフォルトであることを確認 1. CMSサーバー(EC2)にSSHし、ドキュメントルート配下をCodeCommitにpush sudo su -cd /var/www/htmlgit add .git commit -m "change config"git push 1. CMSサーバー(ASG)にブラウザからアクセスし、背景色を修正されていることを確認 ※CodePipelineが処理中であれば反映されていないことがあるため、5分程度おいて再度確認してください。 EC2 Image Builderを設定 1. WSL2で vi ~/terraform-blog/aws_data.tf を実行し、アカウント情報を取得する設定を追記 data "aws_caller_identity" "current" {} 1. vi ~/terraform-blog/aws_imagebuilder.tf を実行し、EC2 Image Builderの設定を追記 #---------------------------------------- # EC2 Image Builderのビルド用コンポーネントを作成 #---------------------------------------- resource "aws_imagebuilder_component" "BlogBuildComponent" { name = "BlogBuildComponent" platform = "Linux" supported_os_versions = ["Amazon Linux 2"] version = "1.0.0" data = "name: HelloWorldTestingDocument\ndescription: This is hello world testing document.\nschemaVersion: 1.0\n\nphases:\n - name: build\n steps:\n - name: HelloWorldStep\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello World! Build.\"\n\n - name: validate\n steps:\n - name: HelloWorldStep\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello World! Validate.\"\n\n - name: test\n steps:\n - name: HelloWorldStep\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello World! Test.\"\n" tags = { Name = "BlogBuildComponent" } } #---------------------------------------- # EC2 Image Builderのテスト用コンポーネントを作成 #---------------------------------------- resource "aws_imagebuilder_component" "BlogTestComponent" { name = "BlogTestComponent" platform = "Linux" supported_os_versions = ["Amazon Linux 2"] version = "1.0.0" data = "name: HelloWorldTestingDocument\ndescription: This is hello world testing document.\nschemaVersion: 1.0\n\nphases:\n - name: test\n steps:\n - name: HelloWorldStep\n action: ExecuteBash\n inputs:\n commands:\n - echo \"Hello World! Test.\"\n" tags = { Name = "BlogTestComponent" } } #---------------------------------------- # EC2 Image Builderのイメージレシピを作成 #---------------------------------------- resource "aws_imagebuilder_image_recipe" "BlogImageRecipe" { name = "BlogImageRecipe" parent_image = aws_ami_from_instance.BlogAMI.id version = "1.0.0" working_directory = "/tmp" block_device_mapping { device_name = "/dev/xvda" ebs { delete_on_termination = true encrypted = false volume_size = 8 volume_type = "gp2" } } systems_manager_agent { uninstall_after_build = false } component { component_arn = aws_imagebuilder_component.BlogBuildComponent.arn } component { component_arn = aws_imagebuilder_component.BlogTestComponent.arn } tags = { Name = "BlogImageRecipe" } } #---------------------------------------- # EC2 Image Builderのイメージレシピを作成 #---------------------------------------- resource "aws_imagebuilder_infrastructure_configuration" "BlogInfra" { name = "BlogInfra" instance_profile_name = aws_iam_role.ROLE_BLOG.name instance_types = ["t2.micro"] key_pair = "KEY_BlogSample" security_group_ids = [aws_security_group.sg_blog.id] subnet_id = aws_subnet.pub_subnet1a_blog.id terminate_instance_on_failure = true tags = { Name = "BlogInfra" } } #---------------------------------------- # EC2 Image Builderのディストリビューションを作成 #---------------------------------------- resource "aws_imagebuilder_distribution_configuration" "BlogDist" { name = "BlogDist" distribution { region = "ap-northeast-1" ami_distribution_configuration { name = "BlogAMI{{imagebuilder:buildDate}}" ami_tags = { Name = "BlogImageBuilderAMI" } } launch_template_configuration { account_id = data.aws_caller_identity.current.id default = true launch_template_id = aws_launch_template.BlogTemplate.id } } tags = { Name = "BlogDist" } } #---------------------------------------- # EC2 Image Builderのイメージパイプラインを作成 #---------------------------------------- resource "aws_imagebuilder_image_pipeline" "BlogImagePipeline" { name = "BlogImagePipeline" status = "ENABLED" distribution_configuration_arn = aws_imagebuilder_distribution_configuration.BlogDist.arn enhanced_image_metadata_enabled = true image_recipe_arn = aws_imagebuilder_image_recipe.BlogImageRecipe.arn infrastructure_configuration_arn = aws_imagebuilder_infrastructure_configuration.BlogInfra.arn image_tests_configuration { image_tests_enabled = true timeout_minutes = 720 } tags = { Name = "BlogImagePipeline" } } 1. Terraformを実行し、イメージパイプラインを作成 terraform planterraform apply 1. イメージパイプラインを実行し、動作確認 以下のようにエラーが出力されていないことを確認します。 CodePipelineでEC2 Image Builderを呼び出す 1. WSL2で vi ~/terraform-blog/lambda_function.py を実行し、EC2 Image Builderを呼び出すLambdaのソースコードを作成 import boto3 import logging import json import os import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) codepipeline_client = boto3.client('codepipeline') imagebuilder_client = boto3.client('imagebuilder') # AMI作成の成功時の処理 def put_job_success(job_id): logger.info('Putting job success') codepipeline_client.put_job_success_result(jobId=job_id) # AMI作成中の時の処理 def continue_job_later(job_id,image_build_version_arn): logger.info('Putting job continuation') continuation_token = json.dumps({'ImageBuildVersionArn':image_build_version_arn}) codepipeline_client.put_job_success_result( jobId=job_id, continuationToken=continuation_token ) # AMI作成の失敗時の処理 def put_job_failure(job_id, err): logger.error('Putting job failed') message = str(err) codepipeline_client.put_job_failure_result( jobId=job_id, failureDetails={ 'type': 'JobFailed', 'message': message } ) # codepipelineからlambda_functionを呼び出し def lambda_handler(event, context): try: job_id = event['CodePipeline.job']['id'] job_data = event['CodePipeline.job']['data'] image_pipeline_arn = os.environ['IMAGE_PIPELINE_ARN'] pipeline_name = os.environ['CODEPIPELINE_NAME'] logger.info('ImagePipelineArn is %s', image_pipeline_arn) logger.info('CodePipeline Event is %s',event['CodePipeline.job']) # 継続トークンの有無を確認 if 'continuationToken' in job_data: continuation_token = json.loads(job_data['continuationToken']) image_build_version_arn = continuation_token['ImageBuildVersionArn'] logger.info('ImageBuilderVersionArn is %s', image_build_version_arn) # ビルドの状態を取得 response = imagebuilder_client.get_image( imageBuildVersionArn = image_build_version_arn ) build_status = response['image']['state']['status'] logger.info('ImageBuild Status is %s',build_status) # 処理の結果が成功なら状態をAVAILABLEに遷移 if build_status == 'AVAILABLE': put_job_success(job_id) # 処理の結果が失敗なら状態をFAILEDに遷移 elif build_status == 'FAILED': errmsg='Build Error' put_job_failure(job_id, errmsg) # 処理が継続中の場合continue_job_later関数を呼び出す else: continue_job_later(job_id,image_build_version_arn) else: # ビルドを実行 response = imagebuilder_client.start_image_pipeline_execution( imagePipelineArn=image_pipeline_arn ) image_build_version_arn = response['imageBuildVersionArn'] logger.info('imageBuildVersionArn is %s', image_build_version_arn) continue_job_later(job_id,image_build_version_arn) # 例外処理 except Exception as err: logger.error('Function exception: %s', err) traceback.print_exc() put_job_failure(job_id, 'Function exception: ' + str(err)) logger.info('Function complete') return "Complete." 1. Lambdaのソースコードをzip形式で圧縮 cd ~/terraform-blog/sudo zip lambda_function.py.zip lambda_function.py 1. vi ~/terraform-blog/aws_s3.tf を実行し、Lambdaのソースコードを保持するS3の設定を追記 resource "aws_s3_object" "lambdacode" { bucket = aws_s3_bucket.blogbucketwp.bucket key = "lambda_function.py.zip" source = "~/terraform-blog/lambda_function.py.zip" etag = filemd5("~/terraform-blog/lambda_function.py.zip") } 1. Terraformを実行し、Lambdaのソースコードを保持するS3を作成 terraform planterraform apply 1. vi ~/terraform-blog/aws_codepipeline.tf を実行し、Lambdaリソースを作成する設定とLambdaを呼び出す設定を追記するためファイルを書き換える #---------------------------------------- # CodeCommitのリポジトリを作成 #---------------------------------------- resource "aws_codecommit_repository" "BlogCodecommitRepo" { repository_name = "BlogCodecommitRepo" tags = { Name = "BlogCodecommitRepo" } } #---------------------------------------- # CodeDeployのアプリケーションを作成 #---------------------------------------- resource "aws_codedeploy_app" "BlogCodedeployApp" { name = "BlogCodedeployApp" compute_platform = "Server" tags = { Name = "BlogCodedeployApp" } } #---------------------------------------- # CodeDeployのデプロイグループを作成 #---------------------------------------- resource "aws_codedeploy_deployment_group" "BlogCodedeployDeployGroup" { app_name = aws_codedeploy_app.BlogCodedeployApp.name deployment_group_name = "BlogCodedeployDeployGroup" service_role_arn = aws_iam_role.CodeDeployServiceRole.arn deployment_config_name = "CodeDeployDefault.AllAtOnce" autoscaling_groups = [aws_autoscaling_group.BlogASG.name] auto_rollback_configuration { enabled = true events = ["DEPLOYMENT_FAILURE"] } deployment_style { deployment_option = "WITHOUT_TRAFFIC_CONTROL" deployment_type = "IN_PLACE" } tags = { Name = "BlogCodedeployDeployGroup" } } #---------------------------------------- # Lambdaを作成 #---------------------------------------- resource "aws_lambda_function" "BlogImageBuilderFunction" { architectures = ["x86_64"] s3_bucket = aws_s3_bucket.blogbucketwp.bucket s3_key = "lambda_function.py.zip" function_name = "BlogImageBuilderFunction" handler = "lambda_function.lambda_handler" memory_size = 128 package_type = "Zip" reserved_concurrent_executions = -1 role = aws_iam_role.ServiceRoleLambda.arn runtime = "python3.9" timeout = 3 tracing_config { mode = "PassThrough" } ephemeral_storage { size = 512 } environment { variables = { CODEPIPELINE_NAME = "BlogCodepipelinePipeline" IMAGE_PIPELINE_ARN = aws_imagebuilder_image_pipeline.BlogImagePipeline.arn } } tags = { Name = "BlogImageBuilderFunction" } } #---------------------------------------- # CodePipelineを作成 #---------------------------------------- resource "aws_codepipeline" "BlogCodepipelinePipeline" { name = "BlogCodepipelinePipeline" role_arn = aws_iam_role.ServiceRoleCodePipeline.arn stage { name = "Source" action { name = "Source" namespace = "SourceVariables" category = "Source" owner = "AWS" provider = "CodeCommit" version = "1" region = "ap-northeast-1" output_artifacts = ["SourceArtifact"] configuration = { BranchName = "master" OutputArtifactFormat = "CODE_ZIP" PollForSourceChanges = "true" RepositoryName = aws_codecommit_repository.BlogCodecommitRepo.repository_name } } } stage { name = "Deploy" action { name = "Deploy" namespace = "DeployVariables" category = "Deploy" owner = "AWS" provider = "CodeDeploy" version = "1" region = "ap-northeast-1" input_artifacts = ["SourceArtifact"] configuration = { ApplicationName = aws_codedeploy_app.BlogCodedeployApp.name DeploymentGroupName = aws_codedeploy_deployment_group.BlogCodedeployDeployGroup.deployment_group_name } } } stage { name = "Invoke" action { name = aws_lambda_function.BlogImageBuilderFunction.function_name namespace = "InvokeVariables" category = "Invoke" owner = "AWS" provider = "Lambda" version = "1" region = "ap-northeast-1" input_artifacts = [] output_artifacts = [] configuration = { FunctionName = aws_lambda_function.BlogImageBuilderFunction.function_name } } } artifact_store { location = aws_s3_bucket.blogbucketwp.bucket type = "S3" } tags = { Name = "BlogCodepipelinePipeline" } } 1. Terraformを実行し、CodePipelineを作成 terraform planterraform apply 1. 作成したCodePipelineを実行し、動作確認 動作確認 1. CMSサーバー(EC2)の管理画面のテーマエディターで背景色を修正 以下はデフォルトのテーマTwenty Twenty-Oneの style.css のbodyの背景色を黒色に修正した例です。 1. CMSサーバー(ASG)にブラウザからアクセスし、背景色が白色であることを確認 1. CMSサーバー(EC2)にSSHし、ドキュメントルート配下をCodeCommitにpush sudo su -cd /var/www/htmlgit add .git commit -m "change config"git push 1. CMSサーバー(ASG)にブラウザからアクセスし、背景色を修正されていることを確認 ※CodePipelineが処理中であれば反映されていないことがあるため、30分程度おいて再度確認してください。 改善点 今回は権限を非常に緩く設定しましたが、実際に使用する際は適宜読み替えて権限を設定してください。 バージョン管理もgitを使ったことがない人でも使えるようにコマンドを固定していますが、コンフリクトが発生する等のリスクがあるため、gitを使える人はブランチを切ったりコミットメッセージを変更する等適宜読み替えてください。 また、イメージの管理にEC2 Image Builderを使用しましたが、ゴールデンイメージ作成に30分程度かかるため、ビルドとテストを行う必要が無ければ AWS Backup を使用する等の別の方法を使用した方が良いです。 IAMをTerraformで resource で管理していますが、 data source を使用した方がスクラップ&ビルドしやすいです。 所感 今回はイメージの管理を自動化しましたが、EC2からAMIを取得する作業や、AMIが正常に取得しているかの確認をする作業がマネージドサービスで自動化できるため非常に便利でした。 前編 と合わせて、ドキュメントルート配下の自動デプロイ、AMI管理の自動化、Ansibleによるプロビジョニングの自動化、Terraformによるインフラのコード化等の様々なツールを紹介しましたが、全てのツールを使用しなくても何か一つでも試すと作業が快適になると思います。 前編と後編を合わせるとかなりボリュームがありますが、ここまで読んで頂きありがとうございました。 The post 【後編】WordPressをIaCで管理して自動デプロイを実現!! first appeared on Sqripts .
テスト設計をする際には、テスト技法を使うことで、効率的に効果的なテストケースを作ることができます。今回、本稿で紹介する技法となる「順序組み合わせテスト」と「波及全使用法:IDAU法」は、バージョンアップ開発や派生開発などで、テスト対象に変更が入ったときに役立つテスト技法です。これまでの7回の連載では、前半の4回はこの技法の特徴や具体的な使い方を湯本から紹介し、連載の後半では、後続研究として取り組んだCode Based IDAU法(CB-IDAU)とグラフ特徴量バグ予測モデル(GMT)を武田から紹介しました。 連載の最終回である今回はすこし話を変えて、この技法を今後どうしていくとよいのかを武田と湯本の対談でお伝えしたいと思います。 スクリプター: 武田 友宏(たけだ ともひろ)のプロフィールはこちら これまでの7回の連載を終えて 湯本: 武田さん、今回はIDAU法の連載に協力してもらってありがとうございました。連載を通じて、私も改めて武田さんの研究成果を見直す機会になったので、とてもよかったです。武田さんはどうでしたか? 武田: 論文で書いたことを要約しつつ、わかりやすく読者の方々に伝える機会ができて、自分の頭の中を整理できたのでとてもよかったです。ありがとうございました。 湯本: 今後の展開について話すのが今日のテーマなのですが(笑)。私は、IDAU法はバージョンアップ開発や派生開発などで、テスト対象に変更が入ったときに役立つテスト技法として研究しましたが、一番の想いは、現場で多くの人に適用してもらいたいことであるため、ツール化して汎用的に使えるようにできないかなって思っているんです。武田さんが後続研究でテーマにしたCB-IDAUなんかは、ツール化して汎用的に使ってもらうのがやりやすいんじゃないかなって思っています。武田さんはどう思いますか? 武田: 実は、私がCB-IDAUについて研究していたころと事情が異なってきていると思っています。最近ではChatGPTのようにすでにプログラムやコーディングパターンを大規模言語モデルとして学習済みのAI技術が出てきたので、CB-IDAUのようなテストは、うまくプロンプトを書けばできるのではないか?と思うようになりました。プログラムを学習済みの大規模言語モデルを使うことで、そもそも誰でもコードがプロンプトを使って簡単に作れるようになりました。なので、テストコードも同様に作れます。コードがあり、そこに対して一定のルールベースでテストを導き出すだけのことであれば、もはやAIのほうが確実に作れます。わざわざ人間がやるような時代ではなくなるのではないかと思います。 セマンティックなテストは人間が行なわなければならない 武田: ただし、システムテストで行うリグレッションテストをAIに学習させて良いテストが作れるようにするのは今後も可能性を感じます。セマンティック(データの持つ意味をコンピュータに理解させ処理する技術)なテストには人間が入れる余地が十分にあると思います。湯本さんとしては、IDAU法を今後どのように広げていきたいのですか? 湯本: IDAU法に基づいたテストケースのパターンが導き出せるツールが作れると良いと思っています。状態遷移モデルを描くとスイッチカバレッジのパターンを出してくれるようなツールがあるのですが、そのIDAU法バージョンのようなものです。 武田: それは、ソフトウェア設計者が作成したDFDをベースにするようなイメージですか? 湯本: 私のイメージは、システムテストをテスト設計する際にモデリングするようなイメージです。そして、単なるDFDではなく、CRUDの情報も付加できるように拡張したモデルにして、テストに必要なCRUDのパターンが導き出せるようにしたいです。 ソースコードからリバースして確認する 武田: Code Based IDAU法(CB-IDAU)がソースコードからIDAU法の考え方に基づくテストパターンを生成する方法ですので、ソースコードからリバースしたパターンと湯本さんが話している方法で生成したパターンを比較して確認するのはどうでしょうか?そこで差異があれば、それはバグなのではないかと考えられます。 湯本: なるほど、いいところに目をつけていますね!それは、実はデシジョンテーブルで同様の先行研究があります。筑波大学大学院の研究室で私や武田さんの先輩にあたる植月さんの研究がまさにそれで、” An Efficient Software Testing Method by Decision Table Verification ”という論文にて、研究成果を発表しています。 武田: コードからのリバースはどのような方法で実現しているのですか? 湯本: コンコリックテスティングです。 武田: なるほど。全パス解析をして、そこからデシジョンテーブルを作るのですね。 湯本: そうです。何か良い説明資料はないかな?(グーグルで検索をする)あー、植月さんがJaSST(ソフトウェアテストシンポジウム)で講演している資料で「 はじめてのコンコリックテスト 」というのがありますね。研究の内容も要約して説明されています。 武田: ありがとうございます。また後でしっかり読んでみます。このような話を自分で切り出しておきながらあえて言うのですが、課題が二つあると思いました。一つは、仕様から導いたパターンと、コードからリバースしたパターンでは途中経過で多くの設計行為が入り、単純に同じにならないので、比較が難しいと思うということです。もう一つは、コードからリバースしたらパターン数が爆発するので、絞り込みルールが必要になるということです。 湯本: まず、パターンの爆発に関しては、それを防ぐために最初に機能セット(feature set)を特定するようにしています。IDAU法は、データアクセスに対する順序性でパターンを作るので、変更が入ったタスク群、つまり先行の立脚点になるタスクが含まれている機能セットを選んで、その後に波及するタスク群、つまり後続の選択肢となるフィーチャーが洗い出されるので、選ばれるコードも絞り込まれます。絞り込まれることによって、爆発は防げるはずです。また、比較が難しい件に関しては、デシジョンテーブルで行った先行研究でも全く同じ課題はあるので、先行研究の中に解決の鍵があると思っています。 武田: コードからリバースする場合なのですが、選ばれるコードを絞り込む際に、入力のデータセットとエンティティとの関係を洗い出さないといけないと思います。コードレベルになると、現実的にデータセットがそのまま一つのエンティティに入るわけではなく、一部はここ、もう一部はここというようなロジックが複雑に入るので、入力のデータセットとエンティティの関係に対する解析が必要です。 湯本: 確かに。画面から入力した情報がデータベースに書き込まれるときに、画面とエンティティが1対1のような関係になることは稀ですね。マイクロサービスアーキテクチャーのような構造だとさらに複雑な関係になることも十分考えられます。最初から全部いっぺんに解決できる方法を頭の中だけで考えていくのは大変だから、ステップ切って少しずつ試していかないと解決策見いだせなさそうですね。 武田: データの遷移(1カラムのデータに対する処理の順番)に絞ってスモールスタートでプロトタイプ検証していきたいです。 湯本: ぜひやりたいですね。データのCRUDレベルで変更が入ったときの影響範囲は、確実にテストできるようにしていきたいです。このレベルのバグは重篤度(Severity)がCriticalになるものが多くいからです。 まとめ 今回は、順序組み合わせテストとIDAU法というテスト技法について説明をする連載の最終回目として、武田と湯本でIDAU法の未来を話し合う対談をさせてもらいました。この後は、「このようなツールを作るとしたら、資金調達しないといけない」という話になり、世の中では、このようなことを実現したい時にはどうやって資金調達するのかといったビジネス的な話で盛り上がりました。 以上で連載は終わりになりますが、今回の対談にあるような研究を継続し、またどこかで成果を発表できるようにしていきたいと思っていますので、そのときをぜひ楽しみにしてください。 The post 【第8回】変更の影響範囲に対するテスト技法の今後の展開 first appeared on Sqripts .
こんにちは。QAエンジニアをしている有名じゃない方の高橋です。 お客様先で品質支援やテストマネージャーをしています。 5/26に開催された、JaSST’23Tohokuにオンライン参加してきました。 テーマに「アジャイルとテストと私たち~明日「アジャイル」と言われたときに困らないためのヒント~」とあるとおり、アジャイルをテーマにしたセッションが並びます。 今回は、S1)基調講演 「アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発」 についてレポートしたいと思います。 JaSSTとは JaSSTとは「ソフトウェアテストおよびソフトウェア品質に関心のある方が深い学びを得ることを目指して、 ソフトウェアテスト分野の幅広い情報と、参加者同士の交流や議論ができる場を提供」するため、特定非営利活動法人ソフトウェアテスト技術振興協会 (ASTER)が主催する日本最大級のソフトウェアテストのシンポジウムになります。 公式ページ JaSST’23Tohoku公式ページ S1)基調講演「アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発」 基調講演をされた川口恭伸さんは「ユーザーストーリーマッピング」監訳を始め、スクラム関連の書籍を複数、共訳、監修しているお方です。 今回のセッションでは、ユーザーストーリーマッピングは何を求められて生まれ、何が出来るかの説明から入り、ユーザーストーリーマッピングの作成方法についてお話されていました。 要点をまとめつつ、セッションを通して感じたこと、学んだことを記していこうと思います。 ユーザーストーリーマッピングとは ユーザーストーリーマッピングを提唱するジェフ・パットンさんや、UXでは知らない人がいないペルソナを生み出したアラン・クーパーさんの話からなぜユーザーストーリーマッピングが必要なのか説明していました。 ユーザーストーリーマッピングは、プログラマとデザイナーの間で認識齟齬をなくすため、共通認識を作り上げるためために必要です。 両者が協調ワークショップを通じて共通体験をすることで情報の力(共有知)を得ることが出来ます。 一緒に作り上げることが重要であると再三言われていました。 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf P17 バケーションフォト 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p19 壁を使用して付箋を使い作成していきます。 付箋を使用するときに気を付けてること すべての情報を記載しない 付箋にすべては書ききれない 共通認識を思い出すためのトリガーとして使う 作成したバケーションフォトは壁にそのまま貼っておくとよいそうです。画像に残して片づけてはいけないとのことです。 なぜならプロジェクト中に何度も見に戻って来て、そのたびに作成時に会話した共通理解を思い出すことが出来るからだそうです。 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p22 ユーザーストーリーマッピング作成の流れ 1.必要なことを書き出す 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p41 2.並べる 以降は※基調講演の内容から作成したイメージ図 3.ラベルを付ける 4.ラベルに大項目を付ける 5.リリースまでに必要なラインを決める 6.POが優先度をつけて減らす 7.ファーストリリースから外す 8.価値が提供できるか検証する (ウォークスルー) ペルソナを使用して検証 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p42 POやスポンサーがリリースのために優先度を付けているところ 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p43 まとめ アジャイル開発においてどのようにQAするか、どこまでテストするかなどのお話はほとんどありませんでした。 ただユーザーストーリーマッピングの本質を理解することで要求から品質を作りこむことが出来ると感じました。 テスト量によるリスク検知 機能数が多くなるにつれてシステムテスト工数が増大する セキュリティや性能テストのタイミング どの機能まで出来れいれば対象機能のテストが可能か 自動化対象の対象選定 開発順を考慮してリグレッションテストの価値が最大化できるように選定する また一番心に響いた話が、「製品開発の目標は、製品を作ることではない。」です。 出典: J 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p62 私達はどうしてもアウトプット部分に拘ってしまいがちです。 どの機能を追加した 全体的な品質は担保出来た 仕様を整理した資料を書き残した しかし、それは結果コンテキストから見ると関係ありません。 製品がユーザーに届き利用してもらった、結果(成果)と、価値(インパクト)の最大化が製品開発の目標です。そのため結果コンテキストが同じであればアウトプットはなるべく小さい方がよいと教えて頂きました。 自分の中で言語化出来ていない部分だったので、今回お話を聞きながら赤べこの様に頷いていました。 おまけ JIRA(タスク管理)で有名なATLASSIAN開発チームも壁と付箋でユーザーストーリーマッピングを整理していた事があるそうです。 出典: 20230526JaSST-Tohoku_アジャイルテスター視点で、ユーザーストーリーマッピングを活用した効果的なプロダクト開発.pdf p50 The post ユーザーストーリーマッピング作成で大事な事とQAのポイント~JaSST’23Tohoku参加レポート first appeared on Sqripts .