diff --git a/.gitignore b/.gitignore index d1640e6..a4a2828 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # Qiita CLI .qiita-cli +.remote node_modules diff --git a/public/.remote/003c8c78f35570a6fc27.md b/public/.remote/003c8c78f35570a6fc27.md deleted file mode 100644 index b12c491..0000000 --- a/public/.remote/003c8c78f35570a6fc27.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: AWS CDKはグローバルでインストールしない -tags: - - AWS - - npx - - CDK -private: false -updated_at: '2020-12-25T02:11:26+09:00' -id: 003c8c78f35570a6fc27 -organization_url_name: null -slide: false -ignorePublish: false ---- -## はじめに - -結論を先に書くと、ローカルにインストールし、`npx cdk`で呼びましょう、と言う話です。 - -## 本文 - -### グローバルにインストールするデメリット - -グローバルにインストールをして暫くたつと、以下のようなエラーがでるようになります。 - -``` -This CDK CLI is not compatible with the CDK library used by your application. -Please upgrade the CLI to the latest version. -(Cloud assembly schema version mismatch: Maximum schema version supported is 4.0.0, but found 7.0.0) -``` - -原因としては、グローバルに入れたCDKとローカルのCDKのバージョンに違いがあるからです。 -インストールした直後には違いはないので、グローバルに入れて、そのまま利用してしまう人が多いと思いますが、後日新しいバージョンが出た時に修正をして、`npm run build`をすると新しいバージョンが出ているメッセージが出て、更新を促され、以下のようなコマンドを実行します。 - -``` shell -$ ncu -u -$ npm i -``` - -しかし、これはローカルのみの更新となる為、グローバルは更新されず、バージョンの違いが発生して上記のエラーとなります。 - -### ローカルにインストールする方法 - -これを回避する為、AWS CDKはローカルにインストールします。 - -``` shell -npm install aws-cdk -``` - -こうする事でCDK自体が`package.json`でバージョン管理されるようになり、バージョンを纏めて管理できるようになり、`ncu`の実行時に違いが発生する事がなくなります。 - -### ローカルでインストールした場合の実行方法 - -``` shell -bash: cdk: command not found -``` - -しかし、このやり方だと`cdk`では上記のようなエラーとなって、呼び出せなくなってしまいます。cdkが`.\node_module\.bin`にあり、パスが通ってないからです。パスを通す事で実行可能になりますが、プロジェクト毎で切り替えるのは辛く、もっと簡単な方法があります。 - -``` shell -npx cdk bootstrap -``` -npxを使う事で、複雑な事はせず、CDKを実行する事ができます。 - -## さいごに - -CDKはたまにしか触らないのに、嵌りポイントが多く、ネットにまだ記事が少なく、自分も直ぐに忘れてしまうので、少しずつ、増やしてきます。 - -## 参考文献 - -- npxでnodeモジュールを実行する - - https://qiita.com/tatakahashiap/items/1c4ab221c4993e7c4ebf -- AWS CDKでハマったこと&解決法 - - https://qiita.com/honmaaax/items/d1467b1f49df2ae09b97 diff --git a/public/.remote/247e0c086dc39d6f1102.md b/public/.remote/247e0c086dc39d6f1102.md deleted file mode 100644 index 1c1f18d..0000000 --- a/public/.remote/247e0c086dc39d6f1102.md +++ /dev/null @@ -1,592 +0,0 @@ ---- -title: 開発マネージャがメンバーに知って欲しい事 ※随時更新 -tags: - - 初心者 - - まとめ - - 書籍紹介 - - マネージャー -private: false -updated_at: '2025-04-22T21:29:41+09:00' -id: 247e0c086dc39d6f1102 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -開発マネージャーがメンバーに知って欲しい事を纏めた記事です。随時、[更新](#更新履歴)します。 - -## 前提 - -- 新人向け -- Webアプリケーション開発 - -# Learning - -開発は常に学び続ける事になるので、「どう学ぶか」を考える。 - -## メタ認知 - -自分を客観的に認知する。 - -https://www.kaonavi.jp/dictionary/metacognition/ - -## Self Management - -自己管理を行う。 - -https://minchalle.com/blog/self-management - -## 守破離 - -学びのプロセスを理解する。 - -https://suthio.hatenablog.com/entry/2018/03/26/070304 - -## 継続力 - -継続する手法を理解する。 - -https://all-special-life.com/?p=33421 - -## Thinking - -開発では考える事が多いので、その為の基本を学ぶ。 - -### Logical Thinking - -論理的な思考方法の基本を理解する。 - -https://www.recruit-ms.co.jp/glossary/dtl/0000000192/ - -参考書: - -https://str.toyokeizai.net/books/9784492531129/ - -### Thinking Framework - -思考を整理する際に利用するフレームワークを知る。 - -https://studyhacker.net/business-frameworks - -### Thinking Backwards - -逆から考えると言う思考法を習慣づける。 - -https://forbesjapan.com/articles/detail/38145/2/1/1 - -参考書: - -https://www.njg.co.jp/book/9784534049445/ - -### The Golden Circle - -なぜから考えると言う思考法を習慣づける。 - -https://www.ida-web.com/rederisejapan/remedia/golden_circle/ - -TED:「優れたリーダーはどうやって行動を促すか」 - -https://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action?language=ja - - - -## Document - -### Business Document - -ビジネス文書の書き方の基本を理解する。 - -https://www.kokuyo-furniture.co.jp/solution/mana-biz/2021/08/content-1.php - -文章は長くなりがちなので、削る習慣をつける。 - -https://studyhacker.net/how-to-shorten-sentences - -参考書: - -https://str.toyokeizai.net/books/9784492555545/ - -### テクニカルライティングの3C - -技術文書に関する基本的な3つの観点を理解する。 - -https://www.u-english.co.jp/blog/?p=231 - -### テクニカルライティングの基本 - -テクニカルライティングの概要を把握する。 - -https://speakerdeck.com/naohiro_nakata/technicalwriting2023 - -書籍: - -https://www.socym.co.jp/book/post-19000 - -### Google Technical Writing One / Two - -テクニカルライティングの詳細を把握する。 - -https://qiita.com/yasuoyasuo/items/c43783316a4d141a140f - -### システム開発文書品質モデル - -文書品質に対する観点を理解する。 - -https://asdoq.jp/uploads/ASDoQ_SystemDocumentationQualityModel_v1.0a.pdf - -### Markdown - -開発文書を作成時の標準的な形式を理解する。 - -https://ja.wikipedia.org/wiki/Markdown - -## Presentation - -プレゼンテーションの目的を理解する。 - -https://news.mynavi.jp/article/purezengohun-1/ - -プレゼンテーション資料の作り方。 - -https://note.com/toyomane/n/n992f1f468fb4 - -### Marp - -Markdownでプレゼンテーション資料を作成する。 - -https://qiita.com/tomo_makes/items/aafae4021986553ae1d8 - -https://marp.app/ - -## Schedule & Task - -スケジュールとタスク管理の基本を理解する。 - -https://task-management-compilation.com/introduction_todo/ - -### アイゼンハワーマトリクス - -緊急度・重要度でタスク管理をする。 - -https://www.miraimanagement.co.jp/mmedia/personneltraining-keyword/%E3%80%90%E3%82%A2%E3%82%A4%E3%82%BC%E3%83%B3%E3%83%8F%E3%83%AF%E3%83%BC%E3%83%9E%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9%E3%80%91 - -### WBS - -作業を分解して整理する方法を知る。 - -https://backlog.com/ja/blog/wbs-introduce-how-to-make-excel-template-and-useful-tools/ - -### Critical Path - -致命的になる作業の見極め方法を知る。 - -https://next-sfa.jp/journal/skill/criticalpath/ - -# Development - -## プログラマーの三大美徳 - -開発の行動指針を知る。 - -https://www.java-career.com/column/industry-knowledge/three-cardinal-virtues/ - -## 基本情報技術者試験 - -開発の基本的な知識を得る。 - -https://www.ipa.go.jp/shiken/kubun/fe.html - -## Agile - -主流となりつつある開発手法を理解する。 - -https://agilemanifesto.org/iso/ja/manifesto.html - -参考書: - -https://www.ohmsha.co.jp/book/9784274068560/ - -## Scrum - -最も使われているアジャイル開発手法の1つを理解する。 - -https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf - -### ryuzee.com - -スクラムに関する有用な記事が掲載されている。 - -https://www.ryuzee.com/ - -# Tools - -良く使うツールをインストールする。 - -## Sakura - -シンプルに使えるテキスト・エディタ。 - -https://sakura-editor.github.io/ - -## VSCode - -便利な統合開発環境。 - -https://azure.microsoft.com/ja-jp/products/visual-studio-code/ - -### 拡張機能 - -Markdown関連の拡張機能。 - -https://qiita.com/84zume/items/1e6c720caba9898f5af2 - -## WSL - -Windows上でLinuxが利用できる。 - -https://docs.microsoft.com/ja-jp/windows/wsl/install - -## Git - -開発で必ず使うバージョン管理ツール。 - -https://backlog.com/ja/git-tutorial/ - -### Learn Git Branching - -Git操作の練習をする。 - -https://learngitbranching.js.org/?locale=ja - -### Git Command Reference - -コマンド - -https://git-scm.com/docs - - -## ダイアグラム - -### Mermaid - -テキストで図を作成できる記法を理解する。 - -https://mermaid.js.org/ - -## PlantUML - -コードで作図するツール。主にシステム構成図に利用している。 - -https://qiita.com/irongineer/items/23fcd55830ae2de96ca8 - -https://plantuml.com/ja/ - -# Programing - -## Readable Code - -読みやすいコードを理解する。 - -https://qiita.com/hsmtknj/items/8e126c81e7a055242135 - -理解しやすいコードを理解する。 - -https://qiita.com/goataka/items/ae1959c29036dc4929fe - -参考書: - -https://www.oreilly.co.jp/books/9784873115658/ - -## Refactoring - -改善すべき兆候やポイントを理解する。 - -https://zenn.dev/masumomo/articles/d552c723d3e2d5 - -参考書: - -https://www.ohmsha.co.jp/book/9784274224546/ - -# Design - -## Pattern - -有名なデザインパターン。Java以外でも参考になる。 - -https://www.techscore.com/tech/DesignPattern/ - -参考書: - -https://www.hyuki.com/dp/ - -## ドメイン駆動設計 - -ドメイン知識に焦点をあてた設計手法。難解だが有用。 - -https://www.slideshare.net/masuda220/ss-115547910 - -参考書: - -https://www.shoeisha.co.jp/book/detail/9784798126708 - -# Programing Language - -利用している言語を理解する。 - -## Typescript - -フロント、バック、CIなど多くの目的に利用している。 - -https://www.typescriptlang.org/ - -実務に使える形で理解する。 - -https://typescriptbook.jp/ - -### Deep Dive - -より深く理解する。 - -https://typescript-jp.gitbook.io/deep-dive/ - -## Java - -業務ロジックの記述に多く利用している。 - -https://www.java.com/ja/ - -基本的な内容を理解する。 - -https://www.javadrive.jp/start/ - -### 100本ノック - -スキル向上を目的とした問題集。 - -https://github.com/JustSystems/java-100practices - -### Effective Java - -良本(らしい)。 - -https://qiita.com/nyandora/items/3e5ec76ca3881bc17924 - -参考書: - -https://www.maruzen-publishing.co.jp/book/b10120506.html - -## Kotlin - -簡潔かつ安全に記述できるJVM言語。 - -https://kotlinlang.org/ - -### Learn Kotlin by Example - -ハンズオン形式で学べる。昨年、社内勉強でやった。 - -https://play.kotlinlang.org/byExample/overview - -## Rust - -C, C++に代わると期待される言語。まだ仕事では使っていない。 - -https://www.rust-lang.org/ja - -### Rust By Example - -ハンズオン形式で学べる。今、社内勉強でやっている。 - -https://doc.rust-jp.rs/rust-by-example-ja/ - -# Test - -## テスト駆動開発(TDD) - -テストコードを書いてから実装する開発方法を理解する。 - -https://it-trend.jp/development_tools/article/32-0036 - -参考書: - -https://www.ohmsha.co.jp/book/9784274217883/ - -### t-wada - -テスト駆動開発などに関して有用な資料がある。 - -https://speakerdeck.com/twada - -## Jest - -JavaScript向けのテスティング・フレームワーク。TypeScriptと組み合わせて利用している。 - -https://jestjs.io/ja/ - -## JUnit - -Java向けのテスティング・フレームワーク。Kotlinと組み合わせて利用している。 - -https://junit.org/junit5/ - -## E2E - -EndToEndのテストについて理解する。 - -書籍: - -https://www.shoeisha.co.jp/book/detail/9784798172354 - -### CodeceptJS - -E2Eのフレームワークについて理解する。 - -https://codecept.io/ - -# Security - -## 情報セキュリティの3要素(CIA) - -セキュリティの基本となる要素を理解する。 - -https://www.fujitsu.com/jp/solutions/business-technology/security/secure/column/201703-1/ - -## OWASP 10 - -危険性が高い脅威を知る。 - -https://github.com/owasp-ja/Top10/blob/master/2021/docs/index.ja.md - -## 安全なウェブサイトの作り方 - -IPAが纏めた良くある脆弱性とその対策方法を知る。 - -https://www.ipa.go.jp/security/vuln/websecurity.html - -# Management - -マネジメントの基本的な考え方を理解する。 - -https://schoo.jp/biz/column/497 - -参考書: - -https://drucker.diamond.co.jp/works/detail/39.html - -### Harvard Business Review - -マネジメントに関する新しい知識を得る。 - -https://www.dhbr.net/ - -## Team Management - -### Servant Leadership - -これからのリーダの基本となる考え方を理解する。 - -https://talknote.com/magazine/servantleadership/ - -参考書:昔の上司から教えて貰った本。 - -https://www.php.co.jp/books/detail.php?isbn=978-4-569-63774-7 - -参考書:まだ読んだ事はないが読んでみたい本。 - -https://eijipress.co.jp/products/2040 - -### OneOnOne - -マズローの欲求5段階説に基づいた 1on1 のやり方を理解する。 - -https://note.com/radiocat/n/n28af762605f0 - -## Project Management - -プロジェクト管理の基本を理解する。 - -https://backlog.com/ja/project-management-guide/ - -### PMBOK - - -アジャイルベースのプロジェクト管理を理解する。 - -https://note.com/miz_kushida/n/n103a7da460c5 - -日本語訳された公式本。 - -https://www.pmi-japan.shop/shopdetail/000000000028/ - -## 見積 - -工数の見積もり方を知る。 - -https://doppon.hatenablog.com/entry/2020/04/01/103457 - -アジャイルな見積りと計画づくりを知る。 - -https://book.mynavi.jp/ec/products/detail/id=22141 - -## 2点見積り - -良く利用する見積方法。 - -https://qiita.com/naoqoo2/items/e4fac9a8ba047a3881a3 - -# Business - -## Customer Success - -顧客に対して提供する価値を理解する。 - -https://blog.hubspot.jp/customer-success-and-cutomer-support - -参考書:グローバルで有名な本。大分前に社内で輪読会をした。 - -https://eijipress.co.jp/products/2260 - -参考書:日本向けに書かれた本。今、社内で輪読会を実施中。 - -https://eijipress.co.jp/products/2268 - -## Marketing - -誰に、何を、どのように売るか、マーケティングの基本を知る。 - -https://www.profuture.co.jp/mk/column/4107 - -## Innovation - -新たな価値を創造するイノベーションの基本を知る。 - -https://www.salesforce.com/jp/blog/2020/08/innovation-definition.html - -# 追加候補 - -- 問い合わせ -- デバッグ -- コミットコメント -- CI/CD -- クラウドプラットフォーム -- ネットワーク -- SQL -- DX Criteria -- ナレッジ管理(フロー、ストック) -- MVP -- 在宅 -- アウトプット -- 技術的負債 -- 振り返り(FDL, KPT, YWT) -- ピープルマネジメント - -# 最後に - -リンク切れ等ありましたら、コメントにてお知らせ頂けると助かります。 diff --git a/public/.remote/26bc0d52cb0b706ca4a5.md b/public/.remote/26bc0d52cb0b706ca4a5.md deleted file mode 100644 index 1390508..0000000 --- a/public/.remote/26bc0d52cb0b706ca4a5.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: 認定スクラムマスター資格をとるまでの流れ -tags: - - scrum - - スクラム - - LSM - - scrummaster - - RSM -private: false -updated_at: '2022-10-07T18:23:56+09:00' -id: 26bc0d52cb0b706ca4a5 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# 始めに - -本記事は、資格取得に関する内容で、スクラムに関する内容は含みません。また、内容は私が取得したRSM (Registered Scrum Master)に基づいて記載しています。本記事が資格取得の助けになれば幸いです。 - -# 注意事項 - -本内容は記事を記載した時点での情報となりますので、申し込み時には実際のサイトで最新の内容を確認する事をお勧めします。 - -# 目次 - -基本的な流れは以下になります。 - -1. 取る資格を決める。 -1. 日付を決める。 -1. 料金を振り込む。 -1. トレーニングに参加する。 -1. テストを受ける。 -1. 証明書を発行する。 -1. 費用を精算する。 - -# 手順 - -## 取る資格を決める - -### 資格の種類 - -有名な認定スクラムマスターの資格は3種類あります。 - -#### PSM (Professional Scrum Master™) / Scrum org. - -1時間程度のテストのみで、費用も数万円と安いです。ただし、英語のみのようです。 - -https://www.scrum.org/assessments/professional-scrum-master-i-certification - -#### CSM (Certified Scrum Master®)/ Scrum Alliance® - -本家サイトはこちらです。 - -https://www.scrumalliance.org/get-certified/scrum-master-track/certified-scrummaster - -研修はこちらから。3~5日の研修で、3,200ドルの費用が掛かるようです。 - -https://www.odd-e.jp/ja/service_scrumalliance/#service_csm - -#### RSM (Registered Scrum Master™) / Scrum Inc. - -旧LSM(Licensed Scrum Master)です。名前が変わったようです。 -2日の研修で、20万円の費用が掛かります。 - -https://scruminc.jp/training/master/ - -##### 選択理由 - -私が選択したのはRSMでした。理由は以下です。 - -- 同僚がRSMを取っていたので実態が把握できた。 -- 5日間業務を明けるのは厳しい。 -- 一度通しで研修を受けたかった。 -- 資格の取得ができると会社で全額補助して貰える。 -- 英語でのテストは辛い。 -- CSMは厳しいと言う[記事](https://note.com/otossy/n/n1839dfd2760b)を幾つか見た。 - -と言う事で、一番~~甘そう~~優しそうな資格にしました。 - -## 日付を決めて、申し込む - -- [サイト](https://scruminc.jp/training/master/)を開く。 -- トレーニングの候補日を確認する。 -- 2日間9-18時を明けられる日を選択する。 - - 15日以上前までであれば日程は変更できるそうです。 -- 詳細を記載し、申し込みをする。 - -## 料金を振り込む - -- 申し込みをするとメールに請求書のPDFが送られる。 -- 記載された内容に基づいて振り込みをする。 - - 通常14日前までに振り込まないと、キャンセルされてしまうようです。 -- 振り込みが完了したメールが来るので確認する。 - -## トレーニングに参加する - -- 事前にメールが送付されるので確認する。 - - オンラインミーティングのURL - - 資料のURL - - 可能なら事前に読んでおく。 -- 当日、オンラインミーティングのURLにアクセスする。 - -## テストを受ける - -- 研修の後半でテストを受けるサイトへの登録を一緒にする。 -- 研修が終わったら、登録したサイトでテストを受ける。 - - 資料を見ながら受験をする事ができる。 - - 1回までは無料で再受験できる。 - - 最悪で2回落ちても相談すると何しかしてもらえるかも? - - テストの結果は受講後直ぐに分かります。 - -個人的な感想ですが、真面目に研修を受けて、資料で確認しながら受験すれば落ちる確率は低い内容だと思いました。 - -## 証明書を発行する - -- 無事にテストに受かると先ほど登録したサイトから証明書を発行する事ができます。 - -## 費用を精算する - -会社で受験する場合、費用の精算が必要になる事が多いので、必要な場合は忘れずに。 - -- 領収書の発行を依頼する。 - - 依頼方法は[こちら]( -https://scrumincjapan.zendesk.com/hc/ja/articles/360050665714-%E9%A0%98%E5%8F%8E%E6%9B%B8%E3%81%AF%E3%81%84%E3%81%9F%E3%81%A0%E3%81%91%E3%81%BE%E3%81%99%E3%81%8B-)で案内されています。 -- 領収書を受領する。 - - 依頼してから数営業日でメールに送られてきます。 - - 繁忙によって変わると思うので、必要なら早めに依頼しておきましょう。 -- 経費申請をする。 - - 会社ごとでやり方が異なるので、そのやり方で。 - -# 最後に - -簡単ですが、認定スクラムマスター資格をとるまでの流れについて紹介をさせて頂きました。スクラムは非常に有用な方法ですので、改めてもっと広がると良いと思いました。その為にも今回の記事が参考になれば幸いです。 diff --git a/public/.remote/3994a57b9f14fe242764.md b/public/.remote/3994a57b9f14fe242764.md deleted file mode 100644 index f135e1e..0000000 --- a/public/.remote/3994a57b9f14fe242764.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: 実践:「質とスピード」を維持するには -tags: - - プロジェクト - - 品質 - - 工数 - - スピード - - whi-advent -private: false -updated_at: '2021-12-21T07:01:19+09:00' -id: 3994a57b9f14fe242764 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -先日、弊社内で開催された**[@t_wada](https://twitter.com/t_wada)**さんのセッションを受けて、自分なりに得た実践論を記載します。 - -## 前提 - -こちらとほぼ同じ内容を踏まえた記事になるので、お時間があれば是非ご一読ください。 - -[![質とスピード~ソフトウェア開発の典型的な誤解を解く~](https://pbs.twimg.com/card_img/1470997630142775297/CuTE3cS9?format=jpg&name=small)](https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition)」 - -乱暴に要約すると**「質を落としても、早くはならない」**と言う話です。 - -## 要点 - -以下、個人的に解釈した要点を幾つか見ていきます。 - -### 要点1:プロジェクトのメンバーとして「できる人」しかアサインさせない - -セッションの内容を整理すると、 - -- 「できる人」は早く書いても品質が高い -- 「できない人」は時間をかけても品質が低い - -となります。 - -個人的な感覚と合致します。 - -ですが、現実的には自分も含め「できない人」の方が多い気がします。 - -では、「できない人」はどうしたら良いのでしょうか? - -### 要点2:「できない人」は「できる人」になってもらう - -当たり前感がありますが、改めて役割を整理すると、 - -- 「できる人」 - - **プロジェクトを実現する事** -- 「できない人」 - - **できる人になる事** - -ですが、認識はしていても**対策**されている事は多くありません。 - -と言う事で、 - -## 対策:「できる人」になる工数を計上しましょう - -各プロジェクトには**必要なスキルセット**があります。 - -ですが、メンバーがアサインされるタイミングで全て**備わってない**方が普通です。 - -特に**内部品質**に関するスキルセットに関しては条件として明記されている方が稀です。 - -## 実践 - -進め方を整理すると、 - -1. プロジェクトに関して**必要なスキルセット**を明確化する - 1. **内部品質**に関しても明確化する -1. メンバーが**持っているスキルセット**を明確化する -1. ギャップを埋める**学習時間**を工数として計上する - -となります。 - -## 終わりに - -上記を実施する事で、**メンバーをアサインする経営側の期待値**と**プロジェクトを実現する現場側の実態**を少しでも埋める事ができるのではないかと考えています。 - -実践するのは結構大変だと思いますが、その際の一助になれば幸いです。 - - - - - - diff --git a/public/.remote/43d7cebc6507b5c5d97a.md b/public/.remote/43d7cebc6507b5c5d97a.md deleted file mode 100644 index caef227..0000000 --- a/public/.remote/43d7cebc6507b5c5d97a.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: 長く売れる製品を考える為の観点 -tags: - - 設計 - - マーケティング - - whi-advent -private: false -updated_at: '2020-12-24T10:31:46+09:00' -id: 43d7cebc6507b5c5d97a -organization_url_name: null -slide: false -ignorePublish: false ---- -## はじめに - -本稿では標準的な差別化戦略の話はせず、いかに**長く売れる製品を考えられるか**についてのみ記載しました。この方法を記載した理由は、**難易度が最も高い方法であるが故に一番楽しい**と思われるからです。 - -前職ですが、約9年程の**プロダクトオーナーの経験**から得た観点を共有する事で、**長く売れる製品を考える楽しさ**を共有できたら幸いです。 - -## 長く売れる製品とは? - -端的に表現するとそれは「**良い製品**」と言う事ですが、さすがに曖昧過ぎるので、もう少し明確化をすると「**他の製品と比べて格段に良い製品**」であると言えます。 - -## 長く売れる製品を考える為の観点 - -「**他の製品**」と言うのは、市場における「**普通**」である事を意味し、これを**否定する**事で「**長く売れる製品**」の示唆を得る事ができると考えられます。 - -聞けば簡単な事と感じられるかもしれませんが、日々の中でそれをする事は容易ではありません。**手間**を惜しまず、**地道**に頑張り、現状に不満を言わない**謙虚さ**は、日本人にとって**美徳**だからです。 - -## 「普通」を否定した製品例 - -Googleの検索エンジンが登場する前、情報を探す人は**図書館の本のように分類された**HPの中から、**地道**に、**手間**を掛かけて探していました。しかし、Googleが出した検索エンジンでは、圧倒的に**速く**、**簡単に**情報を得る事ができるようになり、今でも検索エンジンのデファクトで在り続けています。この例では、「**情報は分類された中から探す**」と言う「**普通**」を否定する事に成功したのです。 - -その他にも、**Salesforce.com**が提示したアプリケーションを**所有しない**SaaSモデルや、**AWS**が確立したインフラを**所有しない**IaaSと言うのも分かりやすい、否定の例です。それまで**所有する**事が「**普通**」だった事を否定し、実現する事で新たな分野を築きました。 - -## 「普通」を否定する実践例 - -次は勤怠システムの「**普通**」を掘り下げて、それを**否定する**例を記載します。 - -### 「良くあるシナリオ」を記載します - -「ある社員が朝会社に行くと、PC打刻で打刻を行い、勤務を開始します。夕方、残業をする事になり、上長に口頭で確認を行い、残業をします。勤務が終了すると再度打刻を行い、帰宅をします。 -翌日、勤務開始後に前日の勤怠の確定を行い、上長はそれを受け取り、承認を行います。休憩時間が長い場合など、何か確認したい点がある場合などは後ほど声をかけ、確認をします。 -月末近くになり、今月は残業をしすぎた事により36協定時間を超えてしまう為、超過申請を行い、上長の承認を得て、残業を行います。 -翌月初めに前月の勤怠を確定し、上長はそれを承認し、給与計算担当者に勤怠情報が渡されます。」 - -ややレガシー感が強いですが、なんの面白味もない「**良くあるシナリオ**」になっています。 - -### 「埋もれた行間」も追記します - -「ある社員が朝会社に行くと、PC打刻で打刻システムで(**社員番号とパスワードを使って**)打刻を行い、勤務を開始します。夕方、残業をする事になり、上長に口頭で確認を行い、残業をします。勤務が終了すると(**社員番号とパスワードを使って**)再度打刻を行い、帰宅をします。 -翌日、勤務開始後に(**自らPCで勤怠システムのWEBページを開き、ログインをし、さらに勤務実績の画面を開き**)前日の勤怠の確定を行い、上長は(**メールで**)それを受け取り、(**自らのWEBページを開き、ログインをし、さらに勤務実績承認の画面を開き**)承認を行います。休憩時間が長い場合など、何か確認したい点がある場合などは(**自ら気づき**)後ほど(**口頭で**)声をかけ、(**忘れないうちに**)確認をします。 -月末近くになり、(**自ら**)今月は残業をしすぎた事により36協定時間を超えてしまう(**に気づいた**)為、(**自ら**)超過申請を行い、上長の承認を得て、残業を行います。 -翌月初めに(**自ら**)前月の勤怠を確定し、上長はそれを(**メールで通知を受けて**)承認し、(**システムがCSVで自動的に連携する事で**)給与計算担当者に勤怠情報が渡されます。」 - -見づらいので割愛していますが、行間には多くの「普通」が埋もれています。 - -### 「前後にある文脈」も追記します - -「(**システム導入時に勤怠担当者が勤怠計算に関する設定を1つ1つ行いました。毎夜、社員の入退社に合わせ、アカウントの改廃がCSV連携により行われています。入社時に、ある社員は勤怠システムの使い方のマニュアルを読み、利用の仕方を学習します。**) -ある社員が朝会社に行くと、PC打刻で(社員番号とパスワードを使って)打刻を行い、勤務を開始します。夕方、残業をする事になり、上長に口頭で確認を行い、残業をします。勤務が終了すると(社員番号とパスワードを使って)再度打刻を行い、帰宅をします。 -翌日、勤務開始後に(自らPCで勤怠システムのWEBページを開き、ログインをし、さらに勤務実績の画面を開き)前日の勤怠の確定を行い、上長は(メールで)それを受け取り、(自らのWEBページを開き、ログインをし、さらに勤務実績承認の画面を開き)承認を行います。休憩時間が長い場合など、何か確認したい点がある場合などは(自ら気づき)後ほど(口頭で)声をかけ、(忘れないうちに)確認をします。 -月末近くになり、(自ら)今月は残業をしすぎた事により36協定時間を超えてしまう(に気づいた)為、(自ら)超過申請を行い、上長の承認を得て、残業を行います。 -翌月初めに(自ら)前月の勤怠を確定し、上長はそれを(メールで通知を受けて)承認し、(システムがCSVで自動的に連携する事で)給与計算担当者に勤怠情報が渡されます。 -(**連携後、給与担当者は給与計算システムにログインし、勤怠情報に基づき残業代や休日出勤手当などの計算を自ら行い、給与に反映し、振り込みを行います**)」 - -こちらも見づらいので割愛していますが、実際にはここにはより多くの「普通」が隠されていると考えられます。 - -### 文中から「変えられる」部分を探します - -「(システム導入時に**勤怠担当者が**勤怠計算に関する設定を**1つ1つ**行いました。毎夜、社員の入退社に合わせ、アカウントの改廃が**CSV連携**により行われています。入社時に、ある社員は勤怠システムの使い方の**マニュアルを読み**、利用の仕方を学習します。) -ある社員が朝会社に行くと、**PC打刻**で(**社員番号とパスワードを使って**)打刻を行い、勤務を開始します。夕方、残業をする事になり、上長に**口頭**で確認を行い、残業をします。勤務が終了すると(**社員番号とパスワードを使って**)再度打刻を行い、帰宅をします。 -翌日、勤務開始後に(**自らPCで勤怠システムのWEBページを開き、ログインをし、さらに勤務実績の画面を開き**)前日の勤怠の確定を行い、上長は(**メールで**)それを受け取り、(**自らのWEBページを開き、ログインをし、さらに勤務実績承認の画面を開き**)承認を行います。休憩時間が長い場合など、何か確認したい点がある場合などは(**自ら気づき**)後ほど(**口頭で**)声をかけ、(**忘れないうちに**)確認をします。 -月末近くになり、(**自ら**)今月は残業をしすぎた事により36協定時間を超えてしまう(**に気づいた**)為、(**自ら**)超過申請を行い、上長の承認を得て、残業を行います。 -翌月初めに(**自ら**)前月の勤怠を確定し、上長はそれを(**メールで通知を受けて**)承認し、(**システムがCSVで自動的に連携する事で**)給与計算担当者に勤怠情報が渡されます。 -(連携後、給与担当者は給与計算システムに**ログイン**し、勤怠情報に基づき残業代や休日出勤手当などの計算を**自ら**行い、給与に反映し、振り込みを行います)」 - -**業務の主筋**は変えずに、別の方法でも成立する部分を探します。これが「**普通**」である部分です。 - -### 文中の「普通」を否定します - -・「システム導入時に**勤怠担当者が**勤怠計算に関する設定を**1つ1つ**行いました」 - -勤怠計算の設定は勤怠担当がやらなければならないのでしょうか?設定は**BPO**に依頼したりする事もできますし、**勤怠の規定**に関する内容から、または**過去の実績と計算結果により機械学習**させる事で自動的にさせる事が可能かもしれません。また、**コミュニケーションツール**の普及により、設定変更も**ボットによるナビゲーション**で行われるようになるのは、そう遠くないように思われます。業務システムの設定は改善が**後回し**にされやすいですが、逆にそこには革新的に変えられる部分がまだ多く残っているかもしれません。 - -・「毎夜、社員の入退社に合わせ、アカウントの改廃が**CSV連携**により行われています。」 - -これは既に古いやり方で、**API**での連携や**外部認証**を利用するやり方がでてきています。社員情報を各システムへ伝播させる仕組みに課題は多く、**アカウント管理**の製品には伸びしろがありそうです。今後はクラウドベースで作られた仕組みに、**オンプレ対応のエージェント**を組み合わせの製品が増えていくのではないかと思われます。 - -・「入社時に、ある社員は勤怠システムの使い方の**マニュアルを読み**、利用の仕方を学習します」 - -これも既に前時代的になりつつあります。マニュアルを作成するのではなく、**チュートリアル**を埋め込んだり、**項目にヘルプ**をつけたり、**チャットボット**で**QA**を提供するなど、様々な方法が出てきています。今後は**Slack**や**Teams**などの**統合されたインターフェース**からの操作が普通になりますが、そこでの利用方法のサジェストの仕方の**デファクトがまだない**ので、そこに革新性を見出せるかもしれません。 - -・「ある社員が朝会社に行くと、**PC打刻**で(**社員番号とパスワードを使って**)打刻を行い、勤務を開始します。」 - -これもやや古い感じがしますが、まだ主流のやり方の一つです。今後はSlackやTeams、Lineなどの**勤務開始連絡**と**勤怠の打刻**は連携していく可能性が高く、**カレンダーの連動**なども考える事ができます。**コミュニケーションツール**やカレンダーとの連携の当たりでもある程度の革新性を見出せ事はできそうです。 - -・「夕方、残業をする事になり、上長に**口頭**で確認を行い、残業をします。」 - -これも既に古い感じがします。この程度の内容であれば、SlackやTeamsで十分だと思います。加えれば、その**やり取りを検知**して、**ボット**が残業申請の提出を**レコメンド**をする位はできそうです。コミュニケーションツールを介したレコメンド機能にもある程度の革新性は見出せそうです。 - -・「勤務が終了すると(**社員番号とパスワードを使って**)再度打刻を行い、帰宅をします。」 - -ログインそのものの否定は上記に書いたので、パスワードにフォーカスをしてみます。パスワードの安全性は低すぎるので、ここも既に幾つかやり方が出てきていて、**デバイス認証**などは普及していく可能性が高いと考えられます。この領域はあまり詳しくないですが、**能動的に認証をしない**で済むようになって欲しいです。 - -・「翌日、勤務開始後に(**自らPCで勤怠システムのWEBページを開き、ログインをし、さらに勤務実績の画面を開き**)前日の勤怠の確定を行い、」 - -上述していますが、業務システムにログインするやり方は既に古く、また、社員が**能動的に**動かなければ進まない仕組みも前時代的です。前日の勤怠情報の確定の**レコメンド**が勤務開始時に**コミュニケーションツール**上にサマリとともに表示され、修正がなければ、そのまま提出する事ができるようになる位は既にできそうな範囲ですが、実現している会社が少ないので、ある程度の革新性は得られそうです。 - -・「上長は(**メールで**)それを受け取り、(**自らのWEBページを開き、ログインをし、さらに勤務実績承認の画面を開き**)承認を行います。」 - -こちらも同様で、上長のコミュニケーションツールに対応すべき内容としてサマリと供に**レコメンド**され、承認もそこでできる位の革新性は予見可能です。 - -・「休憩時間が長い場合など、何か確認したい点がある場合などは(**自ら気づき**)後ほど(**口頭で**)声をかけ、(**忘れないうちに**)確認をします。」 - -この当たりも同様ですが、休憩時間が長いなどの通常の勤務とは異なる部分で確認をすべき部分を上長に**レコメンド**する位もできると思われます。**勤怠の異常に関する部分**も少なくともルールベースでの抽出は可能で、**機械学習**による休職者、退職者に見られる傾向などから予測を行い、**警告**を出す、と言う方向の革新性も考える事が容易です。 - -・「月末近くになり、(**自ら**)今月は残業をしすぎた事により36協定時間を超えてしまう(**に気づいた**)為、(**自ら**)超過申請を行い、上長の承認を得て、残業を行います。」 - -この部分は前述と同様の内容になるので割愛しますが、**システムに対して利用者が能動的に何かをする**時代はそろそろ終わりにしたいですね。 - -・「翌月初めに(**自ら**)前月の勤怠を確定し、上長はそれを(**メールで通知を受けて**)承認し、(**システムがCSVで自動的に連携する事で**)給与計算担当者に勤怠情報が渡されます。」 - -CSV連携のような連携に関しては、将来的にもっと**ファジー**に連携の設定をできるようになる可能性を考えています。具体的には**システム間のインターフェース**のマッチングを**自然言語**によって行う方法です。不可能と感じる人は多いと思いますが、20年位先であれば可能な話だと思います。システム間で**ネゴシエーション**する時代が来るのではないかと考えています。大分**SF**チックですね。 - -・「(連携後、給与担当者は給与計算システムに**ログイン**し、勤怠情報に基づき残業代や休日出勤手当などの計算を**自ら**行い、給与に反映し、振り込みを行います)」 - -こちらも観点は前述した内容と同様ですが、給与計算に関する様々なチェックや試算が自動的に行われ、その中で検出された**データの不足**や**計算結果の異常値**に関する検出程度は**レコメンド**され、**対応方法の決定**だけするようになる位の革新性を見出す事は可能です。 - -### 「普通」を変えて見た例 - -「(システム導入時に**就業規則と過去の勤怠データと計算結果を元に機械学習で**勤怠計算に関する設定を**自動的に**行いました。毎夜、社員の入退社に合わせ、アカウントの改廃が**API連携**により行われています。**システムの利用時に**、ある社員は勤怠システムの使い方を**チュートリアルやオンラインマニュアルで**、利用の仕方を学習します。) -ある社員が朝会社に行くと、**入室の記録**から**自動的に**打刻を行い、勤務を開始します。夕方、残業をする事になり、上長に**コミュニケーションツール**で確認を行い、残業をします。勤務が終了すると**退室の記録からで**再度打刻を行い、帰宅をします。 -翌日、勤務開始後に**コミュニケーションツールに来た通知に対応する事で**前日の勤怠の確定を行い、上長も**コミュニケーションツールで**それを受け取り、**その画面上で**承認を行います。休憩時間が長い場合など、何か確認すべき点がある場合などは**システムが検出し、コミュニケーションツールに自動的に通知された**後、**必要な分のみコミュニケーションツールで**声をかけ、**即座に**確認をします。 -月末近くになり、**システムが**今月は残業をしすぎた事により36協定時間を超えてしまう**アラートを出している**為、**コミュニケーションツール上で**超過申請を行い、上長の承認を得て、残業を行います。 -翌月初めに**コミュニケーションツール上で**前月の勤怠を確定し、上長はそれを**コミュニケーションツールで受けて、**承認し、**システムがAPIで自動的に連携する事で**給与計算担当者に勤怠情報が渡されます。 -(連携後、給与担当者は給与計算システムから**コミュニケーションツール上に計算実行の可否の通知を受け**、勤怠情報に基づき残業代や休日出勤手当などの計算を**そこから自動的に**行い、給与に反映し、振り込みを行います)」 - -今回はコミュニケーションツールの登場が増えすぎた感はありますが、ご覧のように勤怠システムのほぼログインする事がない事がわかります。このように「**否定**」をし、「**置き換える**」事で、「**普通**」ではない「**製品**」の示唆を得る事ができました。 - -### その他の「普通」の例 - -今回の例では記載する事ができなかった多くの「**普通**」がまだ多く存在しています。 - -何の**デバイス**で、どの**OS**で、どのような**ブラウザ**で、UIは**文字**なのか、**フォーム**なのか、**表**なのか、**グラフ**なのか、入力は**マウス**か、**キーボード**か、**ファイル連携**なのか、**API**なのか、**AIで読み取る**のか、「**普通**」として認識してしまっている事がまだまだ多くあり、ここからも**示唆**を得る事ができるかもしれません。 - -## おわりに - -このように「**普通**」を見つけ、それを「**否定する**」事で、「**長く売れる製品**」を考える観点を纏めてみました。 - -実際には、**示唆**を得た後に何に注力するかと言う**意思決定**をし、**推進**し、**実現する**必要があり、これこそが最も「**難しい**」事です。「**普通**」ではない程にそれは「**難しい**」ですが、しかし、これは非常に「**楽しい難しさ**」なので、是非チャレンジしてみて頂ければと考えています。 diff --git a/public/.remote/6000f803dfccd0240c83.md b/public/.remote/6000f803dfccd0240c83.md deleted file mode 100644 index 2d5e090..0000000 --- a/public/.remote/6000f803dfccd0240c83.md +++ /dev/null @@ -1,557 +0,0 @@ ---- -title: CodeceptJSにトライしてみた。 -tags: - - bdd - - gherkin - - e2e - - テスト自動化 - - CodeceptJS -private: false -updated_at: '2023-11-11T11:33:02+09:00' -id: 6000f803dfccd0240c83 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -## 最初に - -本記事は[GitHub: GOAMI-Takaaki/codeceptjs-hotel-planisphere](https://github.com/GOAMI-Takaaki/codeceptjs-hotel-planisphere)の転記になります。 - -## 概要 - -自動化練習サイト「HOTEL PLANISPHERE」を対象に、Gherkin記法のテストを、CodeceptJS で実装したサンプルコードを紹介します。 - -### 対象 - -- サービス - - [HOTEL PLANISPHERE - 自動化練習サイト](https://hotel.testplanisphere.dev/ja/) -- シナリオ - - [testplanisphere/hotel-example-webdriverio-ja](https://github.com/testplanisphere/hotel-example-webdriverio-ja/) - -### 構成 - -- 自動化フレームワーク - - [CodeceptJS](https://codecept.io/) + [Playwright](https://playwright.dev/) -- プログラミング言語 - - [TypeScript](https://www.typescriptlang.org/) -- テスト記法 - - [Gherkin](https://cucumber.io/docs/gherkin/reference/) - -### 環境 - -- ライブラリ - - [Node.js](https://nodejs.org/ja) -- OS - - [WSLg](https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps) + [Ubuntu 22.04.2 LTS](https://apps.microsoft.com/store/detail/ubuntu-22042-lts/9PN20MSR04DW) - -## 基本 - -### CodeceptJS とは - -- E2Eテストフレームワークである。 -- Node.jsプロジェクトである。 -- Gherkin記法をサポートしている。 - -#### Pros - -- コードが直感的で分かりやすい。 - - ex. `I.click('ログイン')` -- 対応しているテストツールが多い。 - - ex. Playwright, WebDriver, Puppeteer, TestCafe, Appium -- プラグインが豊富である。 - - ex. ビジュアルテスト、データ駆動テスト、テストレポートなど - -#### Cons - -- ドキュメント通りに動作しないことがある。 - - ex. iframeやポップアップ -- 日本語ドキュメントが少ない。 - - CodeceptJS に関する Qiita は 44 記事だけである。 -- Gherkin記法がサブ的な位置づけである。 - - 機能強化の見通しが不透明である。 - -### Gherkin 記法とは - -- 自然言語で記述するシナリオ・フォーマットの1つである。 - - ex. Feature / Scenario / Given / when / Then で記述する。 -- 振る舞い駆動開発 (Behavior Driven Development: BDD) で利用される。 - - TDD としての SpceBDD と 受け入れテストとしての StoryBDD がある。 -- [Cucumber](https://cucumber.io/)で利用されている記法として知られる。 - - [Gherkin Reference](https://cucumber.io/docs/gherkin/reference/) で詳述されている。 - -#### Pros - -- 自然言語で記述できる。 - - 誰でも理解・記述でき、関係者と認識を合わせやすい。 -- シナリオだけで記述できる。 - - 画面操作を含まず、実装前に定義できる。 -- 記述方法が共通化されている。 - - ナレッジの再利用性がある。 - -#### Cons - -- 記述が冗長になりやすい。 - - ex. `ログイン画面のメールアドレスに{string}を入力する。` -- 曖昧になりやすい。 - - 実装者との認識が一致しない可能性がある。 -- フォーマットの拡張性がない。 - - デシジョン・テーブルなどパターンテストには利用しづらい。 - -## プロジェクト作成 - -ref. [Quickstart | CodeceptJS](https://codecept.io/quickstart/) - -```sh -# フォルダを作成する。 -$ mkdir codeceptjs-hotel-planishpere -$ cd codeceptjs-hotel-planishpere - -# CodeceptJS と Playwright をインストールする。 -$ npx create-codeceptjs . - -# プロジェクトの初期化をする。 -$ npx codeceptjs init -# TypeScriptは利用する。 -? Do you plan to write tests in TypeScript? Yes -# テストを各ファイル名のルールだが、今回は使用しない。 -? Where are your tests located? ./*_test.ts -# 使うテストツールは Playwright にする。 -? What helpers do you want to use? Playwright -# 出力フォルダ名は output にする。 -? Where should logs, screenshots, and reports to be stored? ./output -# ローカライズは英語のままにする。ja-JP だと不具合もある。 -? Do you want to enable localization for tests? http://bit.ly/3GNUBbh English - -# ブラウザは chromium を選択する。 -Configure helpers... -? [Playwright] Browser in which testing will be performed. Possible options: chromium, firefox, webkit or electron chrom -ium -# ベース URL は HOTEL PLANISPHERE に指定する。 -? [Playwright] Base url of site to be tested https://hotel.testplanisphere.dev/ja/ -# テスト時の画面は非表示にする。 -? [Playwright] Show browser window No -# 最初に作るシナリオ名は login にする。 -? Feature which is being tested (ex: account, login, etc) login -# シナリオを記述するファイル名は login.ts にする。 -? Filename of a test login.ts - -# Gherkin 用の初期化をする。 -$ npx codeceptjs gherkin:init -``` - -## フォルダ構成 - -### 自動作成 - -- features - - Gherkin形式で書くシナリオを配置する。 -- output - - 実行時のスクリーンショットなどが配置される。 -- step_definitions - - シナリオで記載されるステップを配置する。 -- [codecept.conf.js](https://github.com/GOAMI-Takaaki/codeceptjs-hotel-planisphere/tree/main/codecept.conf.ts) - - 動作を切り替える設定ファイル。 -- [step_file.ts](https://github.com/GOAMI-Takaaki/codeceptjs-hotel-planisphere/tree/main/steps_file.ts) - - 共通で利用するステップを配置する。 -- [steps.d.ts](https://github.com/GOAMI-Takaaki/codeceptjs-hotel-planisphere/tree/main/steps.d.ts) - - defコマンドによりTypescript用の定義が自動生成される。 - -### 手動作成 - -- data - - シナリオに利用するファイルを配置する。 -- src - - 共通のコードを配置する。 - -### 設定 - -### 自動作成 - -ref. [Configuration | CodeceptJS](https://codecept.io/configuration/) - -```typescript -export const config: CodeceptJS.MainConfig = { - tests: './*_test.ts', // テスト対象(未使用) - output: './output', // 出力先 - helpers: { - Playwright: { - browser: 'chromium', //ブラウザ - url: 'https://hotel.testplanisphere.dev/ja/index.html', // 初期URL - }, - }, - include: { - I: './steps_file' // 共通ステップを定義するファイルを指定する。 - }, - gherkin: { - features: [ - // シナリオ毎に作成する。 - ], - steps: [ - // ページ毎に作成する。 - ] - }, - name: 'hotel-example-codeceptjs-ja' // プロジェクト名 -} -``` - -### 手動作成 - -ref. [Configuration](https://codecept.io/helpers/Playwright/#configuration) in Playwright | CodeceptJS - -```typescript -export const config: CodeceptJS.MainConfig = { - ... - helpers: { - Playwright: { - ... - windowSize: '1980x1080', // 画面サイズ - locale: 'ja-JP', // 言語 - video: false, // 動画を取得するか - keepVideoForPassedTests: false, // 成功時も動画を残すか - disableScreenshots: false, // スクリーンショットを無効にするか - fullPageScreenshots: true, // スクリーンショットを全画面にするか - uniqueScreenshotNames: true, // スクリーンショット名をユニークにするか - highlightElement: false, // エラー箇所をハイライトするか(不具合?) - show: false, // 画面表示をするか - trace: true, // 詳細な記録(htmlやスクリーンショット)を残すか - keepTraceForPassedTests: false, // 成功時も詳細な記録を残すか - }, - }, - ... -} -``` - -## テスト作成 - -ref. [Behaivior Driven Development | CodeceptJS](https://codecept.io/bdd/) - -### シナリオ記述 - -- features にファイルを追加する。 - ```sh - $ touch https://github.com/GOAMI-Takaaki/codeceptjs-hotel-planisphere/tree/main/features/login.feature - ``` -- シナリオを記述する。 - - login.feature - ```gherkin - Feature: ログイン - シンプルなテキストインプットとボタンの画面です。 - ログイン情報はCookieに保存されます。 - 会員登録画面で保存したユーザの他、登録済みのユーザ(下記)があります。 - - Scenario: 定義済みユーザでログインができること - Given ホームを開く。 - And ログインペ―ジに移動する。 - And "ichiro@example.com" "password"でログインする。 - Then マイペ―ジである事を確認する。 - ``` -- codecept.conf.ts の features に追記する。 - ```typescript - export const config: CodeceptJS.MainConfig = { - ... - gherkin: { - features: [ - './features/login.feature', // 追記 - ... - ], - }, - ... - } - ``` - -### ステップ実装 - -ref. [Playwright Helper](https://codecept.io/helpers/Playwright/), [Locators](https://codecept.io/locators/) | CodeceptJS - -- step_definitions にファイルを追加する。 - ```sh - $ touch ./step_definitions/login.ts - $ touch ./step_definitions/home.ts - $ touch ./step_definitions/mypage.ts - ``` -- 各ステップを記述する。 - - home.ts - ```typescript - const { I } = inject(); - - const URL = 'https://hotel.testplanisphere.dev/ja/index.html'; - Given('ホームを開く。', () => { - // URLを開く - I.amOnPage(URL); - }); - - export {}; - ``` - login.ts - ```typescript - const { I } = inject(); - - Given('ログインペ―ジに移動する。', () => { - I.click('ログイン', locate('nav')); - }); - - const login = (email: string, password:string) => { - I.fillField('メールアドレス', email); - I.fillField('パスワード', password); - I.click('ログイン', '#login-button'); - }; - - Given('{string} {string}でログインする。', login); - - export {}; - ``` - mypage.ts - ```typescript - const { I } = inject(); - - const URL = 'https://hotel.testplanisphere.dev/ja/mypage.html'; - - Then('マイペ―ジである事を確認する。', () => { - I.seeCurrentUrlEquals(URL); - }); - - export {}; - ``` -- codecept.conf.ts の step_definitions に追記する。 - ```typescript - export const config: CodeceptJS.MainConfig = { - ... - gherkin: { - steps: [ - './step_definitions/home.ts', //追記 - './step_definitions/login.ts', //追記 - './step_definitions/mypage.ts', //追記 - ] - }, - ... - } - ``` - -## テスト実行 - -ref. [Commands | CodeceptJS](https://codecept.io/commands/#commands) - -```sh -# ログインを実行する。 -$ npx codeceptjs run features/login.feature - -# 特定のシナリオだけ実行する。 -$ npx codeceptjs run --verbose --grep "定義済みユーザでログインができること" - -# 全シナリオを実行する。 -$ npx codeceptjs run -``` - -### プロジェクト作成してない場合 - -```sh -# ライブラリをインストールする。 -$ npm ci - -# Playwright の関連ライブラリをインストールする。 -$ npx playwright install-deps -``` - -## デバッグ実行 - -### デバック用引数を指定して実行する。 - -```sh -$ npx codeceptjs run --verbose -``` - -### ステップの実行状況を確認する。 - -```sh -ログイン -- - シンプルなテキストインプットとボタンの画面です。 - ログイン情報はCookieに保存されます。 - 会員登録画面で保存したユーザの他、登録済みのユーザ(下記)があります。 - ✖ 定義済みユーザでログインができること in 7514ms - --- FAILURES: - - 1) ログイン - 定義済みユーザでログインができること: - expected url of current page "https://hotel.testplanisphere.dev/ja/mypage.html" to equal "https://hotel.testplanisphere.dev/ja/login.html" - - Scenario Steps: - - I.seeCurrentUrlEquals("https://hotel.testplanisphere.dev/ja/mypage.html") at ./step_definitions/mypage.ts:26:5 - - I.click("ログイン", "#login-button") at login (./step_definitions/login.ts:24:5) - - I.fillField("パスワード", "wrong") at login (./step_definitions/login.ts:23:5) - - I.fillField("メールアドレス", "ichiro@example.com") at login (./step_definitions/login.ts:22:5) - - I.click("ログイン", nav) at ./step_definitions/login.ts:10:5 - - I.amOnPage("https://hotel.testplanisphere.dev/ja/index.html") at ./step_definitions/home.ts:6:5 -``` - -### 出力された画像や動画、トレースを確認する。 - -```sh -Artifacts: -- screenshot: ~/output/定義済みユーザでログ_1693978807.failed.png -- video: ~/output/videos/6bdb1195-5850-431b-8722-14924907c83c_定義済みユーザでログインができること.failed.webm -- trace: ~/output/trace/39dade40-4344-4e00-98d3-ea5953f89d14_定義済みユーザでログインができること.failed.zip -``` - -### 画面を表示して確認する。 - -codeceptjs.conf.ts -```typescript -export const config: CodeceptJS.MainConfig = { - helpers: { - Playwright: { - show: true // false -> true - }, - }, -}; -``` - -### 変数を出力して確認する。 - -login.ts -```typescript -const login = (email: string, password:string) => { - console.log(`email=${email}`); - I.fillField('メールアドレス', email); - I.fillField('パスワード', password); - I.click('ログイン', '#login-button'); -}; -Given('{string} {string}でログインする。', login); -``` - -## Tips - -### 複数データでシナリオ実行する。 - -Paramterized Testのような動作になる。 - -ref. [Examples](https://codecept.io/bdd/#examples) in Behavior Driven Development | CodeceptJS - -mypage.feature -- Scenario を Outline にする。 - ```gherkin - Scenario Outline: 定義済みユーザの情報が表示されること - ``` -- 変数を`<カラム名>`で指定する。 - ```gherkin - Given ホームを開く。 - And ログインペ―ジに移動する。 - And "" ""でログインする。 - Then マイペ―ジである事を確認する。 - And メールアドレスが""である事を確認する。 - And 氏名が""である事を確認する。 - And 会員ランクが""である事を確認する。 - ... - ``` -- Examples にデータを表形式で記載する。 - ```gherkin - Examples: - | email | password | rank | username |...| - | ichiro@example.com | password | プレミアム会員 | 山田一郎 |...| - | sakura@example.com | pass1234 | 一般会員 | 松本さくら |...| - | jun@example.com | pa55w0rd! | プレミアム会員 | 林潤 |...| - | yoshiki@example.com | pass-pass | 一般会員 | 木村良樹 |...| - ``` - -### 複数データでステップを実行する。 - -ref. [Tables](https://codecept.io/bdd/#tables) in Behavior Driven Development | CodeceptJS - -- ステップの下にデータを表形式で記載する。 - - ex. カラム名: planName - - plan.feature - ```gherkin - Scenario: 未ログイン状態でプラン一覧が表示されること - Given ホームを開く。 - And 宿泊予約ペ―ジに移動する。 - Then プラン数が7である。 - And 以下のプランが表示されている。 - | planName | - | お得な特典付きプラン | - | 素泊まり | - | 出張ビジネスプラン | - | エステ・マッサージプラン | - | 貸し切り露天風呂プラン | - | カップル限定プラン | - | テーマパーク優待プラン | - ``` -- ステップ実装 - - plan.ts - ```typescript - // 変数 table で受け取る。 - Then('以下のプランが表示されている。', (table: any) => { - // データを行単位に分割する。 - const rows = table.parse().hashes(); - for (const row of rows) { - // 値をカラム名で取得する。 - I.see(row.planName); - } - }); - ``` - -### 共通で利用するステップを追加する。 - -- step_files.ts に追記する。 - ```typescript - export = function() { - return actor({ - // 独自定義の関数を追加する。 - seeNumberOfTabs: async (expected: number)=> { - const actual = await this.grabNumberOfOpenTabs(); - assert(actual == expected, `期待されたタブの数は${expected}だが、実際は${actual}である。`); - }, - }); - } - ``` -- ステップで利用する。 - - reserve.ts - ```typescript - Given('宿泊予約確認が閉じられる。', () => { - // どこからでも利用可能になる。 - I.seeNumberOfTabs(1); - }); - ``` - -### アクションをステップにする。 - -- シナリオに記載できるよう、ステップとしてラップする。 - - action.ts - ```typescript - Given('{int}秒待つ。', (sec: number) => { - I.wait(sec); - }); - ``` -- シナリオに記載する。 - - ```gherkin - Scenario: 未入力でエラーとなること - Given ホームを開く。 - And 3秒待つ。 - And ログインペ―ジに移動する。 - ... - ``` - -## TODO - -### 修正 - -- ポップアップ不具合 -- 金額計算不具合 - -### 追加 - -- [Reports](https://codecept.io/reports/) -- [Custom Helper](https://codecept.io/helpers/) -- [Mobile](https://codecept.io/helpers/Appium.html) -- [Visual Testing](https://codecept.io/visual/) -- [AI Testing](https://codecept.io/ai/) - -## 最後に - -本記事が自動化検討のお役に立てば幸いです。 diff --git a/public/.remote/61384223da96c7e6c064.md b/public/.remote/61384223da96c7e6c064.md deleted file mode 100644 index dd0cf78..0000000 --- a/public/.remote/61384223da96c7e6c064.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -title: AWS ネットワーク構成図サンプル(VPC) -tags: - - Network - - AWS - - PlantUML - - vpc -private: false -updated_at: '2024-12-23T07:05:03+09:00' -id: 61384223da96c7e6c064 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -AWSの最初の壁の1つであるネットワークについて敷居を下げられるよう、標準的な構成を簡単ですが纏めました。 - -どこかしらには書いてある構成ですが、色々と見て回らずに比較できるようにしました。 - -# VPC - -時間の都合でゲートウェイをメインに、エンドポイントは対象外にしました。 - -https://docs.aws.amazon.com/vpc/ - -## Private Subnet - -### 単一 VPC - -- 初期状態です -- VPC内だけ接続できます -- VPC外とは接続できません - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PrivateSubnetGroup(private,"Private Subnet") { - EC2(ec21,"EC2","") - EC2(ec22,"EC2","") - } - } -} - -ec21-r->ec22 - -@enduml -``` - -### VPC 間接続:VPC Peering - -- 同一アカウント内のVPCと接続できます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist - -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/GenericAlt.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/NetworkingContentDelivery/VPCPeeringConnection.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc1,VPC){ - PrivateSubnetGroup(private1,"Private Subnet") { - EC2(ec21,"EC2","") - } - } - GenericAltGroup(group,"") { - VPCPeeringConnection(peering,"VPC Peering","") - } - - VPCGroup(vpc2,VPC){ - PrivateSubnetGroup(private2,"Private Subnet") { - EC2(ec22,"EC2","") - } - } -} - -ec21-r->peering -vpc1-r[hidden]->peering -peering-r[hidden]->vpc2 -peering-r->ec22 - -@enduml -``` - -https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-peering.html - -### VPC 間接続:Subnet Sharing - -- 共有したSubnetで、異なるアカウントと接続します - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/ManagementGovernance/Organizations.puml -!include AWSPuml/NetworkingContentDelivery/VPCInternetGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCNATGateway.puml -!include AWSPuml/SecurityIdentityCompliance/ResourceAccessManager.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -Organizations(organization,"AWS Organization","AWS Organization") { - - ResourceAccessManager(ram, "Resource Access Manage","") - - AWSCloudGroup(cloud1,"VPC Owner"){ - VPCGroup(vpc1,"Shared VPC"){ - PrivateSubnetGroup(private1,"Private Subnet (Share)") { - EC2(ec21,"EC2","") - } - } - } - - AWSCloudGroup(cloud2,"VPC Paticipant"){ - VPCGroup(vpc2,"Shared VPC"){ - PrivateSubnetGroup(private2,"Private Subnet (Shared)") { - EC2(ec22,"EC2","") - } - } - } - -} - -vpc1-u->ram:share -ram-d->vpc2:shared -private1-u[hidden]->ram -private1-r-private2:同一 - -@enduml -``` - -- [共有したSubnetを利用できるリソースには制限がある](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-sharing-service-behavior.html) - -https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-sharing.html - -### VPC 間接続:Transit Gateway - -- 異なるアカウントのVPCと接続できます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist - -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/CorporateDataCenter.puml -!include AWSPuml/Groups/GenericAlt.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/Groups/Region.puml -!include AWSPuml/General/Traditionalserver.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCCustomerGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnectGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnect.puml -!include AWSPuml/NetworkingContentDelivery/TransitGateway.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -GenericAltGroup(ga,"") { - AWSCloudGroup(cloud1){ - VPCGroup(vpc1,VPC){ - EC2(ec21,"EC2","") - } - } - - AWSCloudGroup(cloud2){ - VPCGroup(vpc2,VPC){ - EC2(ec22,"EC2","") - } - } -} - -AWSCloudGroup(cloud3){ - TransitGateway(tgw, "Transit Gateway", "") -} - - -vpc1-r->tgw - - -vpc1-d[hidden]-vpc2 - -vpc2-r->tgw - -cloud1-r[hidden]->cloud2 - - -@enduml -``` - -https://docs.aws.amazon.com/ja_jp/vpc/latest/tgw/what-is-transit-gateway.html - -## Public Subnet:Internet Gateway - -### Public Subnet - -- インターネットに公開されます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/NetworkingContentDelivery/VPCInternetGateway.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PublicSubnetGroup(public,"Public Subnet") { - EC2(ec2,"EC2","") - } - VPCInternetGateway(igw,"Internet Gateway","") - } -} -Internet(internet,"Internet","") - -ec2<-r->igw -igw<-r->internet - -@enduml -``` - -https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Internet_Gateway.html - -### Private Subnet + NAT Gateway - -- 公開せずに、インタネットにアクセスできます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/NetworkingContentDelivery/VPCInternetGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCNATGateway.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PrivateSubnetGroup(private,"Private Subnet") { - EC2(ec2,"EC2","") - } - PublicSubnetGroup(public,"Public Subnet") { - VPCNATGateway(nat,"NAT Gateway","") - } - VPCInternetGateway(igw,"Internet Gateway","") - } -} -Internet(internet,"Internet","") - -ec2-r->nat -nat<-r->igw -igw<-r->internet - -@enduml -``` - -- V4 IP Adress: NAT Gateay -- V6 IP Adress: Egress-only Internet Gateway - -https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html - -https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/egress-only-internet-gateway.html - -### Public / Private Subnet + NAT Gateway - -- 公開・非公開サーバーの組み合わせです - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/NetworkingContentDelivery/VPCInternetGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCNATGateway.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PrivateSubnetGroup(private,"Private Subnet") { - EC2(ec21,"EC2","") - } - PublicSubnetGroup(public,"Public Subnet") { - EC2(ec22,"EC2","") - VPCNATGateway(nat,"NAT Gateway","") - } - VPCInternetGateway(igw,"Internet Gateway","") - } -} -Internet(internet,"Internet","") - -ec21<-r->ec22 -ec21-r->nat -nat<-r->igw -ec22<-r->igw -ec22-d[hidden]->nat -igw<-r->internet - -@enduml -``` - -## AWS Site-to-Site VPN - -https://docs.aws.amazon.com/ja_jp/vpn/latest/s2svpn/Examples.html - -### 単一接続 - -- 自社環境に1台接続できます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/CorporateDataCenter.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/General/Traditionalserver.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCCustomerGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNConnection.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PrivateSubnetGroup(private,"Private Subnet") { - EC2(ec21,"EC2","") - } - VPCVPNGateway(vgw,"Virtual Private Gateway","") - } -} - -VPCVPNConnection(connection,"VPN Connection","") - -CorporateDataCenterGroup(corporate,"Corporate") { - VPCCustomerGateway(customer,"Customer Gateway","") - Traditionalserver(server,"Server","") -} - -ec21-r->vgw -vgw-r->connection -connection-r->customer -customer-r->server - -@enduml -``` - -## Direct Connect - -https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html - -### 単一接続:Virtual Private Gateway - -- 自社環境に専用線で1台接続できます -- あまり利用されない - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/CorporateDataCenter.puml -!include AWSPuml/Groups/Generic.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/General/Traditionalserver.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCCustomerGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnectGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnect.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - VPCGroup(vpc,VPC){ - PrivateSubnetGroup(private,"Private Subnet") { - EC2(ec21,"EC2","") - } - VPCVPNGateway(vgw,"Virtual Private Gateway","") - } -} - -DirectConnect(connection,"Direct Connect","") - -CorporateDataCenterGroup(corporate,"Corporate") { - VPCCustomerGateway(customer,"Customer Gateway","") - Traditionalserver(server,"Server","") -} - -ec21-r->vgw -vgw-r->connection:Private VIF -connection-r->customer:専用線 -customer-r->server - -@enduml -``` - -- 仮想インターフェイス:Private VIF - -### 複数接続:20以下:Virtual Private Gateway / Direct Connect Gateway - -- 自社環境に専用線で20台まで接続できます -- 単一でも次のこの構成にしておくと拡張が容易である - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/CorporateDataCenter.puml -!include AWSPuml/Groups/GenericAlt.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/Groups/Region.puml -!include AWSPuml/General/Traditionalserver.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCCustomerGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnectGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnect.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -AWSCloudGroup(cloud){ - GenericAltGroup(ga,"") { - RegionGroup(region1, "Region") { - VPCGroup(vpc1,VPC){ - PrivateSubnetGroup(private1,"Private Subnet") { - EC2(ec21,"EC2","") - } - VPCVPNGateway(vgw1,"Virtual Private Gateway","") - } - } - RegionGroup(region2, "Region") { - VPCGroup(vpc2,VPC){ - PrivateSubnetGroup(private2,"Private Subnet") { - EC2(ec22,"EC2","") - } - VPCVPNGateway(vgw2,"Virtual Private Gateway","") - } - } - } - DirectConnectGateway(dgw,"Direct Connect Gateway","") -} - -DirectConnect(connection,"Direct Connect","") - -CorporateDataCenterGroup(corporate,"Corporate") { - VPCCustomerGateway(customer,"Customer Gateway","") - Traditionalserver(server,"Server","") -} - -ec21-r->vgw1 -vgw1-r->dgw - -region1-[hidden]d-region2 - -vpc1-[hidden]d-connection - -ec22-r->vgw2 -vgw2-r->dgw - -dgw-r->connection:Private VIF -connection-r->customer:専用線 -customer-r->server - -@enduml -``` - -- 仮想インターフェイス:Private VIF -- VPC間接続:不可 -- Direct Connect Gateway: 無料 -- クォータ:[ゲートウェイあたりの仮想プライベート AWS Direct Connect ゲートウェイ:20](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/limits.html) - - クォータは拡張不可 - -### 複数接続:5000以下:Transit Gateway / Direct Connect Gateway - -- 自社環境に専用線で20台より多く接続できます - -```plantuml -@startuml -!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist -!include AWSPuml/AWSCommon.puml -!include AWSPuml/Groups/AWSCloud.puml -!include AWSPuml/Groups/CorporateDataCenter.puml -!include AWSPuml/Groups/GenericAlt.puml -!include AWSPuml/Groups/VPC.puml -!include AWSPuml/Groups/PrivateSubnet.puml -!include AWSPuml/Groups/PublicSubnet.puml -!include AWSPuml/Groups/Region.puml -!include AWSPuml/General/Traditionalserver.puml -!include AWSPuml/General/Internet.puml -!include AWSPuml/Compute/EC2.puml -!include AWSPuml/NetworkingContentDelivery/VPCVPNGateway.puml -!include AWSPuml/NetworkingContentDelivery/VPCCustomerGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnectGateway.puml -!include AWSPuml/NetworkingContentDelivery/DirectConnect.puml -!include AWSPuml/NetworkingContentDelivery/TransitGateway.puml -!include AWSPuml/AWSSimplified.puml - -top to bottom direction -skinparam linetype ortho - -GenericAltGroup(ga,"") { - AWSCloudGroup(cloud1){ - VPCGroup(vpc1,VPC){ - EC2(ec21,"EC2","") - } - } - - AWSCloudGroup(cloud2){ - VPCGroup(vpc2,VPC){ - EC2(ec22,"EC2","") - } - } -} - -AWSCloudGroup(cloud3){ - TransitGateway(tgw, "Transit Gateway", "") - DirectConnectGateway(dgw,"Direct Connect Gateway","") -} - -DirectConnect(connection,"Direct Connect","") - -CorporateDataCenterGroup(corporate,"Corporate") { - VPCCustomerGateway(customer,"Customer Gateway","") - Traditionalserver(server,"Server","") -} - -vpc1-r->tgw - - -vpc1-d[hidden]-vpc2 - -vpc2-r->tgw - -cloud1-r[hidden]->cloud2 - -tgw-r->dgw - -dgw-r->connection:Transit VIF -connection-r->customer:専用線 -customer-r->server - -@enduml -``` - -- 仮想インターフェイス:Transit VIF -- VPC間接続:可能 -- Transit Gateway:有料 -- クォータ:[Transit Gateway あたりのアタッチメント:5000](https://docs.aws.amazon.com/ja_jp/vpc/latest/tgw/transit-gateway-quotas.html) - - クォータは拡張不可 - -## 略語 - -良く出てくるGatewayの略語も記載しておきます。 - -- CGW: Customer Gateway -- D(X)GW: Direct Connect Gateway -- EIGW: Egress-only Internet Gateway -- IGW: Internet Gateway -- TGW: TransitGateway -- VGW: Virtual Private Gateway - -## さいごに - -ルートテーブルも書こうと欲を出したら半年寝かしてしまったので、諦めて公開する事にしました。 - -足りない点は多いですが、どなたかの理解の一助になれば幸いです。 - -## 参考 - -### PlantUMLでAWS構成図を描く方法の紹介サイト - -https://qiita.com/sakai00kou/items/18e389fc85a8af59d9e0 - -#### アイコン一覧 - -https://github.com/awslabs/aws-icons-for-plantuml/blob/main/AWSSymbols.md - -### 【AWS基礎】よく使うゲートウェイの特徴・違い・料金まとめ - -詳細な設定方法が紹介されている。 - -https://ops.jig-saw.com/tech-cate/aws_gateway diff --git a/public/.remote/6a02fde3de1a78a85041.md b/public/.remote/6a02fde3de1a78a85041.md deleted file mode 100644 index 5f67db0..0000000 --- a/public/.remote/6a02fde3de1a78a85041.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: JIRAでGitHub Enterpriseを連携する際の設定値の具体例 -tags: - - jira - - GithubEnterprise -private: false -updated_at: '2020-12-02T23:42:57+09:00' -id: 6a02fde3de1a78a85041 -organization_url_name: null -slide: false -ignorePublish: false ---- -# 概要 - -GitHub EnterpriseとJIRAの連携の設定で、JIRA側の設定でちょっと苦労したので、メモとして公開しておく。 -基本的な設定はネットに結構あるのだが、設定項目の具体的な値の例がなくて困ったので記載しておく。 -Enterpriseの場合、アプリではなく、DVSC accountsで連携設定をする。その際に指定する項目の例が以下になる。 - -# JIRA設定例 - -設定 > 製品 > 統合 > DVCSアカウント > GitHub エンタープライズアカウントをリンク - -## 新しい GitHub エンタープライズアカウントを追加 - -### Team or User account - -項目がTeamとか書いてるのに、これはGitHubのOrganizationを指定するらしい -``` ex) xxx-organization``` - -### Host URL - -GitHub EnterpriseのサイトURLとか説明が書いてあるのに、指定するのは普通にGitHubのURL -```ex) https://github.com/``` - -### Client ID / Client Secret - -これはGitHub側で指定した内容で、特に嵌る事はなかった。 - -### Auto Link New Repositories / Enable Smart Commits - -これは任意なので、ご都合に合わせて。特に困らなければ、そのままの方が。 - -# 最後に - -以上、本当に簡単ですが、誰かの参考になれば幸いです。 diff --git a/public/.remote/7c1f2e4cc7e2f6142642.md b/public/.remote/7c1f2e4cc7e2f6142642.md deleted file mode 100644 index 065f168..0000000 --- a/public/.remote/7c1f2e4cc7e2f6142642.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: なぜ単純な増員は生産性の改善に直結しないのか? -tags: - - 教育 - - 経営 - - 工数 -private: false -updated_at: '2022-03-05T05:37:11+09:00' -id: 7c1f2e4cc7e2f6142642 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -## はじめに - -経営層が理解し易いように、製造業を例に纏めてみました。 - -## 前提 - -課題分析として、生産としての観点から開発者を **「自動化設備」** と想定し、評価を行ってみる。 -自動化設備の評価方法としては、一般的な **「費用・便益分析法」** を利用する。 - -## システム開発における「費用・便益分析法」の解釈 - -1. **「作業時間の短縮」**・・・指示・教育時間の短縮 -1. **「段取り替え時間の短縮」**・・・調査・学習時間の短縮 -1. **「不良品の減少」**・・・開発テストでの不具合発生数の減少 -1. **「製品事故の減少」**・・・インシデント発生数の減少 -1. **「製品品質の向上」**・・・機能性の向上 - -## 評価の実施 - -「単純な増員」は **「性能の低い生産設備」** と仮定をする。 - -### (1)指示・教育時間の短縮 - -自走力が低く、上司や先輩社員の時間を多く必要とする - -### (2)調査・学習時間の短縮 - -学習度合いが低く、生産物が変わる毎に時間を多く必要とする - -### (3)開発テストでの不具合発生数の減少 - -技術力が低く、生産をする際に多くの不具合を発生させる - -### (4)インシデント発生数の減少 - -品質が低く、ユーザー利用時に頻繁に動作不具合を発生させる - -### (5)機能性の向上 - -機能性が低く、ユーザー利用時の業務遂行に問題を発生させる - -## 評価結果のまとめ - -- 多くの不具合を発生させる(Quality) -- 多くの工数を必要とする(Cost) -- 長い期間を必要とする(Delivery) - -## 評価結果の考察 - -**資材や生産物の多様化** や **品質に対する要求の高度化** に伴い「生産設備」に求められる性能が高くなった。 -その為、「単純な増員」は生産性の向上に寄与せず、**むしろ下げる傾向にあり**、生産性の向上には **「良質な人員」** が必要となる。 - -## 評価結果による対策 - -開発者は **「学習型の生産設備」** であり、学習済み設備が調達できた場合でも、**個社チューニング**が必要となり、生産開始まである程度時間を必要となってしまう為、既存の「生産設備」の**メンテナンス**が重要となる。 - -## さいごに - -思ったほど分かり易くない気がしましたが、書いてしまったので、公開しておきます。 diff --git a/public/.remote/867baf856d1647e140d6.md b/public/.remote/867baf856d1647e140d6.md deleted file mode 100644 index 345c5b6..0000000 --- a/public/.remote/867baf856d1647e140d6.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: >- - AWS CLIがMINGW64でc:\program: bad interpreter: No such file or - directoryエラーになる場合の回避方法 -tags: - - Windows - - MinGW - - aws-cli -private: false -updated_at: '2020-12-25T01:30:45+09:00' -id: 867baf856d1647e140d6 -organization_url_name: null -slide: false -ignorePublish: false ---- -## はじめに - -GitBashで入れたMINGW64をシェル実行環境として利用している人がそれなりに遭遇してそうですが、意外と記事がなかったので、記録として残しておきます。 -エラーのキーワードで検索するとbrewとか、pipの話が出てきますが、全く関係ありませんでした。 - -### 追記 - -この方法ではコマンドプロンプトでの事項ができなくなるので、結局はスペースがないフォルダに再インストールしました。 -シンボリックリンクなども試してみましたが、ダメでした。 - -## 前提条件 - -- Windows -- MINGW64 ※Cgwinでの動作は未確認ですが、同様の事が起きると思います -- AWS CLI - -## 現象 - -上記の環境にてAWS CLIを利用した際に以下のようなエラーになる。 - -``` -$ aws -bash: /c/Program Files/Python38/Scripts/aws: c:\program: bad interpreter: No such file or directory -``` -## 回避方法 - -環境変数のpathで指定しているScriptsを「'(シングルコーテーション)」で囲む。 - -これを - -``` -C:\Program Files\Python38\Scripts\ -``` - -こうする - -``` -'C:\Program Files\Python38\Scripts\' -``` - -## 補足 - -ちなみに、「"(ダブルコーテーション)」だと設定できないとエラーになります。 -ダメもとでPYTHON_HOMEとかで別で設定もしてみましたが、やはりダメでした。 - -## 最後に - -エラーの内容をよく見れば当たり前の回避方法ですが、MINGW64環境固有の問題かと勝手に思い込んで15分位無駄に時間を使ってしまったので、供養として書き残しました。誰かの役に立てば幸いです。 diff --git a/public/.remote/9ae63e8aa0b623c2e29f.md b/public/.remote/9ae63e8aa0b623c2e29f.md deleted file mode 100644 index d61d8a0..0000000 --- a/public/.remote/9ae63e8aa0b623c2e29f.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: GitLab CEでGitHubをミラーリングする -tags: - - GitHub - - GitLab - - GitLab-CI - - GitLabCE - - mirror -private: false -updated_at: '2022-05-02T08:41:16+09:00' -id: 9ae63e8aa0b623c2e29f -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# 概要 - -**GitHub** -> **GitLab CE** の同期を実現した。 - -## 課題 - -- **GitLab**の**ミラーリング機能**の**Pull**は**CE(Community Edition)** では利用できない。 - - **Pull**は**EE(Enterprise Edition)** の機能となる。 -- **GitLab CE**は**社内環境**にある為、**GitHub Action**では同期できない。 - -## 解決 - -- **GitLab**の**CI/CD**の**Schedule**を利用し、**Git**の機能のみで同期を実現した。 - -## 補足 - -- 仕組みとしてはGitLab, GitHub以外でも利用可能である。 -- 鍵はアクセスを限定かつ個人管理にしない為、プロジェクト毎に生成する。 - -# ミラー実行用レポジトリの作成 - -ミラー対象のレポジトリとは別に実行用にレポジトリを作成する。 - -- レポジトリ名 - - 任意 - - `ex) Mirror Tool` -- ファイルを作成 - - .gitlab-ci.yml - - CI/CDの実行内容 - - 下記の内容を転記する。 - - README.md - - 任意 - - `ex) 本ページへのURL` - -## .gitlab-ci.yml - -以下を転記する。 - -``` sh -# 実行用レポジトリのコードは使わないのでチェックアウトを無効化 -variables: - GIT_STRATEGY: none - GIT_CHECKOUT: "false" - -mirroring: - rules: - # 引数が未指定の場合、ジョブを実行しない - - if: $SSH_PRIVATE_KEY && $SOURCE_HOST && $SOURCE_REPOSITORY && $TARGET_HOST && $TARGET_REPOSITORY - - before_script: - # openssh-clientとgitをインストール - - apt update -y && apt install -y openssh-client git - # SSH用のディレクトリを作成 - - mkdir ~/.ssh/ && chmod 0700 ~/.ssh - # SSHで秘密鍵を使うように設定 - - echo "Host $SOURCE_HOST, $TARGET_HOST" >> ~/.ssh/config - - echo " AddKeysToAgent yes" >> ~/.ssh/config - - echo " IdentityFile ~/.ssh/id_rsa_mirror" >> ~/.ssh/config - # SSHの設定を表示 - - cat ~/.ssh/config - # 秘密鍵のファイルを生成し、権限を付与 - - echo "$SSH_PRIVATE_KEY" | tr -d "\r" > ~/.ssh/id_rsa_mirror - - chmod 600 ~/.ssh/id_rsa_mirror - # SSHエージェントを起動 - - eval $(ssh-agent -s) - # SSHエージェントに秘密鍵を追加 - - ssh-add ~/.ssh/id_rsa_mirror - # 対象のホストの公開鍵を取得し、known_hostsに追加 - - ssh-keyscan -H "$SOURCE_HOST" >> ~/.ssh/known_hosts - - ssh-keyscan -H "$TARGET_HOST" >> ~/.ssh/known_hosts - - script: - # ミラー元レポジトリを取得 - - git clone --mirror git@$SOURCE_HOST:$SOURCE_REPOSITORY.git work - - cd work - # ミラー先レポジトリへ送信 - - git push --mirror git@$TARGET_HOST:$TARGET_REPOSITORY.git -``` - -# レポジトリ毎の設定 - -ミラーしたいレポジトリ毎に以下を実行する。 - -## SSHキーを生成する - -```sh -ssh-keygen -q -t ed25519 -C '${REPOSITORY_ID}' -N '' -f ~/.ssh/id_rsa_${REPOSITORY_ID} -``` - -`ex) ssh-keygen -q -t ed25519 -C 'mirror-tool' -N '' -f ~/.ssh/id_rsa_mirror-tool` - -## ミラー元レポジトリ ex) GitHub - -### デプロイキーを追加する - -- 以下を開く。 - - `Source Repository > Settings > Security > Deploy keys > Add deploy key` -- 値を入力する。 - - Title - - Name of id_rsa_${REPOSITORY_ID}.pub - - `ex) id_rsa_mirror-tool.pub` - - Key - - Content of id_rsa_${REPOSITORY_ID}.pub - - `ex) ssh-ed25519 [...] mirror-tool` - - Allow write access - - チェックしない -- `Add key`を押す。 - -## ミラー先レポジトリ ex) GitLab - -### 新しいプロジェクトを作成する - -- 作成したいグループで`New Project`を押す。 -- `Create blank project`を選択する。 -- 値を入力する。 - - Project name - - ${REPOSITORY_NAME} Mirror - - `ex) Mirror Tool Mirror` - - Project slug - - ${REPOSITORY_ID}_mirror - - `ex) mirror_tool_mirror` - - Project description - - This repository is mirror for ${SOURCE_REPOSITORY} - - `ex) This repository is mirror for github.com:***/mirror-tool.git` - - Initialize repository with a README - - チェックしない -- `Craete project`を押す。 - -### デプロイキーを追加する - -- 以下を開く - - `ミラー先レポジトリ > Settings > Repository > Deploy keys > Collapse` -- 値を入力する。 - - Title - - id_rsa_${REPOSITORY_ID}.pubのファイル名を指定する。 - - `ex) id_rsa_mirror-tool.pub` - - Key - - id_rsa_${REPOSITORY_ID}.pubのテキストを指定する。 - - `ex) ssh-ed25519 [...] mirror-tool` - - Grant write permissions to this key - - チェックする -- `Add key`を押す。 - -## Scheduleを追加する - -- 以下を開く。 - - `ミラー実行用レポジトリ > CI/CD > Schedules > New Schedule` -- 値を入力する。 - - Description - - `${SOURCE_HOST}:${SOURCE_REPOSITORY_GROUP}/${REPOSITORY_ID} to ${TARGET_HOST}:${TARGET_REPOSITORY_GROUP}/${REPOSITORY_ID}-mirror` - - `ex) github.com:***/mirror-tool to gitlab.internal:mirror/mirror-tool-mirror` - - Interval Pattern - - 任意に設定する - - Target Branch - - `.gitlab-ci.yml`を作成したブランチを指定する。 - - `ex) Main` - - Variables - - SOURCE_HOST - - コピー元のホスト名を指定する。 - - `ex) github.com` - - SOURCE_REPOSITORY - - `${SOURCE_REPOSITORY_GROUP}/${REPOSITORY_ID}` - - `ex) ***/mirror-tool` - - TARGET_HOST - - コピー先のホスト名を指定する。 - - `ex) gitlab.internal` - - TARGET_REPOSITORY - - `${TARGET_REPOSITORY_GROUP}/${REPOSITORY_ID}-mirror` - - `ex) csr-dept/mirror-tool-mirror` - - SSH_PRIVATE_KEY - - 最初に作成したSSHキーの秘密鍵 - - `id_rsa_${REPOSITORY_ID}`のテキストを指定する。 - - ``` - ex) - -----BEGIN OPENSSH PRIVATE KEY----- - (Omitted) - -----END OPENSSH PRIVATE KEY----- - ``` - - Activated - - チェックする -- `Save pipeline schdule`を押す。 - -## Scheduleを実行する - -Scheduleの動作を確認する。 - -- 以下を開く。 - - `ミラー実行用レポジトリ > CI/CD > Schedules` -- 作成したScheduleの`Play`を押す。 -- 以下を開く。 - - `ミラー実行用レポジトリ > CI/CD > Pipelines` -- 実行されたJobの結果を確認する。 - -# 最後に - -わかり辛い所があるかもしれませんが、参考になれば幸いです。 diff --git a/public/.remote/9cd4d74412d225574779.md b/public/.remote/9cd4d74412d225574779.md deleted file mode 100644 index d61bd4f..0000000 --- a/public/.remote/9cd4d74412d225574779.md +++ /dev/null @@ -1,3429 +0,0 @@ ---- -title: JSTQB テスト自動化エンジニア v2016 要約・意訳 -tags: - - テスト自動化 - - JSTQB - - tae -private: false -updated_at: '2024-10-10T21:49:50+09:00' -id: 9cd4d74412d225574779 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -[「JSTQB Advanced Level シラバス テスト自動化エンジニア Version 2016.J01」](https://jstqb.jp/dl/JSTQB-Syllabus.Advanced_TAE_Version2016.J01.pdf) - -上記を箇条書きに整理した結果です。文章体が苦手なので。 - -## 注意 - -- 意訳や省略、誤訳(?)の修正など、原本と異なる箇所が多いので、ご注意下さい -- 学習内容以外の部分は割愛しています -- このシラバスには新しいバージョンがあります - -# 0. イントロダクション - -## 0.7 用語、定義、頭字語 - -### 一般 - -- **SUT**: System Under Test / テスト対象システム - - テスト対象も参照のこと -- **GUI**: Graphical User Interface / グラフィカルユーザーインターフェース -- **UI**: User Interface / ユーザーインターフェース - -### 固有 - -- **gTAA**: generic Test Automation Architecture / 汎用テスト自動化アーキテクチャ - - テスト自動化ソリューションの全体概要を提供する -- **TAA**: Test Automation Architecture / テスト自動化アーキテクチャ - - gTAAを具体化したもの - - TASのアーキテクチャを定義する -- **TAS**: Test Automation Solution / テスト自動化ソリューション - - TAAを具体化/実装したもの - - テストハーネスやテストライブラリなどの成果物を含む -- **TAF**: Test Automation Framework / テスト自動化フレームワーク - - テスト自動化に必要な環境 - - テストハーネスやテストライブラリなどの成果物を含む - -### 役割 - -- **TAM**: Test Automation Manager / テスト自動化マネージャー - - TASの開発と進化の計画および監督についての責任者 -- **TAE**: Test Automation Engineer / テスト自動化エンジニア - - 成果物であるTASの実装、保守、技術改善を含むTAAの設計についての責任者 - -# 1. テスト自動化の概要と目的 - -## 1.1 テスト自動化の目的 - -### テスト自動化(自動テスト実行を含む)とは - -- 専用ソフトウェアツールを使用してテストの事前条件を制御および設定する -- テストを実行する -- 実行結果と期待結果を比較する -- 異なるSUTバージョンや環境で多くのテストケースを一貫性をもって繰り返し実行することに役立つ -- 人手を介さずにテストスイートを実行するメカニズムだけにとどまらない - -### テスト対象システム(SUT)との分離 - -- TASとSUTを分離し、依存関係を最低限にとどめる - - 組込みシステムなどの場合、テストに用いるソフトウェアをSUTに導入しなければならない - -### テスト自動化が包含する設計プロセス - -- ソフトウェア -- 文書 -- テストケース -- テスト環境 -- テストデータ - -### テストウェアが必要とするテスト活動 - -- 自動テストケースの実装 -- 自動テスト実行の監視、制御 -- 自動テスト結果の解釈、報告、記録 - -### SUTへのアプローチ - -- SUTのクラス、モジュール、ライブラリの公開インターフェースを使用したテスト - - ex. APIテスト -- SUTのユーザーインターフェースを使用したテスト - - ex. GUIテスト、CLIテストなど -- サービスやプロトコルを使用したテスト - -### テスト自動化の目的 - -- テストの効率性の向上 -- 機能カバレッジの拡大 -- 総テストコストの削減 -- 手動テスト担当者が行えないテストの実施 -- テスト実行期間の短縮 -- テスト実行頻度の向上、テストサイクルに要する時間の短縮 - -### テスト自動化の利点 - -- より多くのテストのビルド毎の実行 -- 手動では行えないテストの作成・実行 - - リアルタイム、リモート、並列テスト -- 手動より複雑なテストの実行 -- テスト実行の高速化 -- オペレーターのミスによるテスト結果への影響を低減 -- より効果的・効率的にテストリソースを使用する -- ソフトウェア品質に関するフィードバックの迅速化 -- システムの信頼性向上(再現性、一貫性など) -- テストの一貫性の向上 - -### テスト自動化の欠点 - -- コスト - - 追加コストが必要 - - TASのセットアップのための初期投資 - - 継続的なTASの保守が必要 -- スキル - - 追加技術が必要 - - チームに開発と自動化のスキルが必要 -- テスト - - 目的から逸脱するリスク - - 例えば、テストの実行を犠牲にしてでも、テストケースの自動化に集中する - - 複雑になる - - 新たなエラーが引き起こされるリスク - -### テスト自動化の制限 - -- すべての手動テストを自動化できない -- チェックできるのは - - ツールが解釈できる結果のみ - - あらかじめ定義された期待結果によって検証可能な実行結果だけである -- 探索的テストは自動化できない - -## 1.2 テスト自動化の成功要因 - -(重要)プロジェクトを開始する前に、成功する可能性を分析する。 - -- 成功要因の数が多いほど、テスト自動化プロジェクトが成功する可能性も高くなる -- 要因をすべて満たさなくてよい -- 長期的なプロジェクトの成功への影響に主眼を置く - - パイロット段階の成功に影響を与える要因は考慮していない - -### テスト自動化アーキテクチャ(TAA) - -対象ソフトウェア製品のアーキテクチャと非常に密接に関連している。 - -- サポートする機能要件と非機能要件を明確にする(最重要) -- TAAは保守性、性能、習得性を考慮して設計される -- SUTのアーキテクチャを理解しているソフトウェア技術者を関与させる - -### SUTの試験性 - -#### 自動テストがしやすい設計 - -- GUIテストの場合 - - できる限り多くのGUI操作やデータをGUI画面構成から切り離す -- APIテストの場合 - - 公開されたクラス、モジュール、コマンドラインインターフェース数を増やす - -#### 自動テストの実装のしやすさ - -- テスト可能なパーツを最初のターゲットにする -- 簡単に自動テストできるモジュールまたはコンポーネントを特定する - -### テスト自動化戦略 - -現実的で一貫性のあるテスト自動化戦略では、SUTの保守性と一貫性に対応する。 - -- SUTの新規・既存部分の両方に、同じ自動化戦略を適用できない場合がある -- コードのさまざまな部分にそれを適用することのコスト、利点、リスクを考慮する -- UIとAPIテストの両方を自動化する場合、その結果の一貫性について考慮する - -### テスト自動化フレームワーク(TAF) - -使いやすく、ドキュメントが充実しており保守性の高いテスト自動化フレームワーク(TAF)を維持することにより、自動テストに対して一貫性のあるアプローチをとることができる。 - -#### レポート機能を実装する: - -- 品質情報を提供する - - 成功/失敗/エラー/未実行/異常終了、統計情報など -- 品質概要を把握する - - ステークホルダー向け - - テスト担当者、テストマ ネージャー、開発担当者、プロジェクトマネージャーなど - -#### 簡単なトラブルシューティングを可能にする: - -失敗したテストのトラブルシューティングを行う簡単な方法を提供する - -- テストが失敗する理由 - - SUTで見つかった故障 - - TASで見つかった故障 - - テスト自身またはテスト環境の問題 - -#### テスト環境に適切に対応する: - -- テストツールはテスト環境の一貫性に依存する -- 自動テストには専用 のテスト環境が必要である -- テスト環境やテストデータをまったく制御できない場合、テスト実行の要件を満たさず、誤った実行結果の生成につながる可能性がある - -#### 自動テストケースを明文化する: - -- テスト自動化の目的 -- どの部分をどの程度テストするか、どの属性(機能および非機能)をテストするか文書化する - -#### 自動テストをトレースする: - -- テスト自動化エンジニアがテストケースの個々のステップをトレースできる - -#### 簡単な保守を実現する: - -- 保守がテスト自動化作業の大部分とならないようにする -- 保守作業はSUTに対して行う変更の規模に比例させる -- ケースを簡単に分析、変更、拡張できる -- 自動化テストウェアを頻繁に再利用し、変更が必要になる項目数を最小限に抑える - -#### 自動テストを最新の状態に保つ: - -- 新しい要件や変更された要件によってテストやテストスイート全体が失敗した場合は、失敗したテストを無効にするのではなく、修正する - -#### 導入の計画を立てる: - -- テストスクリプトを簡単に導入、変更、再導入できる - -#### 必要に応じてテストを削除する: - -- 自動テストスクリプトが不要になった場合、簡単に削除できる - -#### SUTの監視と復旧を行う: - -- 継続的に実行するためには、SUTを継続的に監視する -- SUTで致命的なエラー(クラッシュなど)が発生した場合 - - エラーから回復し、問題のあるテストケースをスキップして、次のケースからテストを再開できる - -### (最重要)テスト自動化コードの保守性 - -- 煩雑になる可能性があり、テスト用のコードの量がSUTのコードと同程度の量になることも珍しくない -- 使用されるテストツール、検証の種類、保守しなければならないテストウェア成果物の違いにより変わる - - テスト入力データ、テストオラクル、テストレポートなど - -### 行うべきでない事項 - -#### インターフェースの影響を受けやすいスクリプトを作成しない - -- グラフィカルインターフェースやAPIの重要でない部分の変更による影響を受けるスクリプト - -#### データの変更による影響を受けやすい、または特定のデータ値に大きく依存するテスト自動化を行わない - -- 他のテスト出力に依存するテスト入力など - -#### コンテキストの影響を受けやすい自動化環境を作成しない - -- オペレーティングシステムの日付や時刻、言語 -- 別のアプリケーションのコンテンツなど -- 環境を制御できるように、必要に応じてテスト用のスタブを使う - -# 2. テスト自動化の準備 - -## 2.1 テスト自動化に影響するSUT要因 - -- SUTの状況や環境を評価する -- 要因を特定して適切な対応をとる - -### SUTインターフェース - -#### 自動化したテストケースは、SUTでのアクションを呼び出す - -- SUTを制御できるインターフェースをSUTが提供する -- UIコントロールで実現できる -- より低レベルなソフト ウェアインターフェースでも実現できる -- 通信レベルでのインターフェースを通したコミュニケーションも可能である - - TCP/IP、USB、独自のメッセージングプロトコルなど - -#### SUTの分割により、異なるテストレベルに対して実現可能になる - -- SUTのサポートにより、特定のレベルに対して実現可能になる - - コンポーネントレベル、システムレベルなど -- ユーザーインターフェースが存在しない場合 - - 別のソフトウェアインターフェースが利用できる必要がある - - テストフックとも呼ばれる - -独自のカスタマイズが必要になることもある - -### サードパーティ製ソフトウェア - -- サードパーティが提供するソフトウェアを含み、自動テストが必要になる場合 - - APIの使用など、別の自動化ソリューションが必要になる可能性がある - -### 干渉のレベル - -- アプローチが異なる場合、干渉のレベルも異なる -- SUTに対する変更の数が多い場合、干渉のレベルも高くなる -- 既存のUI要素を使う場合、干渉のレベルは低くなる -- 専用のソフトウェアインターフェースを使う場合、干渉のレベルが高くなる -- SUTのハードウェア要素を使う場合、干渉のレベルがさらに高くなる - - キーボード、スイッチ、タッチスクリーン、通信イン ターフェースなど - -#### 干渉のレベルが高いことによる問題は、誤警告のリスクである - -- テストの干渉のレベルが高い場合、失敗を示したとしても、稼働環境で同様の事象が発生する可能性は低い -- 高い干渉のレベルで行うテストほど、テスト自動化のアプローチとして簡単な解決策となる - -### 異なるSUTアーキテクチャ - -- 異なるテスト自動化ソリューションが必要になる場合がある - - 例 - - COMテクノロジーを使うC++で書かれたSUT - - Pythonで書かれたSUT -- 異なるアーキテクチャを同じテスト自動化戦略で扱う場合 - - 両方をサポートしたハイブリッド戦略が必要になる - -### SUTのサイズと複雑度 - -- 現在のSUTのサイズと複雑度を考慮して、今後の開発計画を立てる。\ -- 小さく単純なSUT - - 複雑で非常に柔軟度の高いテスト自動化アプローチは適さない - - 単純なアプローチの方が適している -- 大規模で複雑なSUT - - 小さく単純なアプローチを用いるのは賢明でない - - ただし、小さく単純なものから始めるのが適切な場合もある - - しかし、これは一時的なアプローチとすべきである - -- いくつかの要因は、SUTが利用で きるようになってから明らかになる - - サイズと複雑度、利用できるソフトウェアインターフェースなど - -### テスト自動化の開発はSUTが利用可能になる前に開始すべきである - -SUTがまだ存在しない場合でも、テスト自動化計画を開始することができる。 - -- 必要なソフトウェアインターフェースを指定することもできる -- 要件(機能または非機能)がわかっている場合 - - その要件とそれをテストする手段から自動化の候補を選定できる - - 自動化の計画はその候補から始まる - - 自動化要件の特定やテスト自動化戦略 の決定も含まれる -- アーキテクチャと設計が作成されている間 - - テストをサポートするソフトウェアインターフェースの設計に着手できる - -## 2.2 ツールの評価と選定 - -- テスト自動化マネージャー(TAM) - - ツールの選定・評価プロセスの責任者 -- テスト自動化エンジニア(TAE) - - TAMへの情報提供、評価・選定作業の実施 - -### TAEが中心に行う作業 - -- 目的やプロジェクトの制約に対するツール情報の分析 -- 適切なツールの推薦 -- 組織の成熟度評価・テストツールのサポート体制の評価 -- 期待するテストツールのサポートに関する適切な評価 -- 候補ツールの情報収集・選定 -- ツールとSUTコンポーネントとの互換性の判断 -- 具体的なビジネスケースに基づく費用対効果の見積り - -### ツールの問題事例 - -ツールが想定や状況のすべてを満たせるわけではない。 - -#### テスト自動化ツールのインターフェースが、既に導入されている他のツールと連携しない - -- 例 - - テストマネジメントツールがアップデートされ、接続インターフェースが変更された - - プリセールスサポートの情報が誤っており、レポートツールに転送できない情報がある -- 解決策 - - アップデートの前に注意してリリースノートを確認し、大規模な移行の場合は本番環境に移行する前にテストを行う - - 実際のSUTを使ったツールのデモをオンサイトで行わせる - - ベンダーやユーザーコミュニティフォーラムによるサポートを検討する - -#### 一部のSUTの依存性が変更され、テストツールがサポートしないものが含まれるようになった - -- 例 - - 開発部門が最新バージョンの Java にアップデートした -- 解決策 - - 開発環境/テスト環境とテスト自動化ツールでアップグレードを同期する - -#### GUIのオブジェクトがキャプチャできない - -- 例 - - オブジェクトは表示されているが、テスト自動化ツールから操作できない -- 解決策 - - 開発の際には、よく知られている技術やオブジェクトのみを使用するよう心がける - - テスト自動化ツールを購入する前にパイロットプロジェクトを行う - - 開発担当者にオブジェクトの標準を定義させる - -#### ツールが非常に複雑に見える - -- 例 - - ツールには大量のフィーチャーセットがあるが、その一部しか使う予定がない -- 解決策 - - ツールバーから不要な機能を削除してフィーチャーセットを制限する方法を探す - - ニーズを満たすライセンスを選択する - - 必要なフィーチャーに特化した別のツールを探す - -#### 他のシステムと競合する - -- 例 - - 他のソフトウェアをインストールすると、テスト自動化ツールが動作しなくなる - - またはその逆 -- 解決策 - - インストール前にリリースノートや技術要件を読む - - サプライヤーから他のツールに影響がないことを確認する - - ユーザーコミュニティフォーラムに質問する - -#### SUTへの影響 - -- 例 - - テスト自動化ツールの使用中または使用後に、SUTの反応が変わる - - 応答時間が長くなるなど -- 解決策 - - SUTを変更する必要がないツールを使用する - - ライブラリのインストールなど - -#### コードへのアクセス - -- 例 - - テスト自動化ツールがソースコードの一部を変更する -- 解決策 - - ソースコードを変更する必要がないツールを使用する - - ライブラリのインストールなど - -#### リソースの制限(主に組込み環境) - -- 例 - - テスト環境の空きリソースが限られているか、リソースが枯渇している - - メモリなど -- 解決策 - - リリースノートを読み、ツール開発元と話し合い、環境が問題につながらないことを確認する - - ユーザーコミュニティフォーラムに質問する - -#### アップデート - -- 例 - - アップデートですべてのデータが移行されない - - 既存の自動テストスクリプトやデータ、構成が破損する - - アップグレードに別の(よりよい)環境が必要 -- 解決策 - - テスト環境でアップグレードのテストを行い、開発元から移行が問題なく行えることを確認する - - アップデートの前提条件を読み、アップデートする価値があるかを判断する - - ユーザーコミュニティフォーラムによるサポートを求める - -#### セキュリティ - -- 例 - - テスト自動化ツールを使うにあたり、テスト自動化エンジニアに提供されていない情報や権限を必要とする -- 解決策 - - テスト自動化エンジニアにアクセス権を与える必要がある - -#### 異なる環境やプラットフォームでの互換性がない - -- 例 - - テスト自動化がすべての環境やプラットフォームで動作するとは限らない -- 解決策 - - ツールの独立性を最大限にするように自動テストを実装し、複数のツールを使うことによるコストを最小限に抑える - -## 2.3 試験性と自動化を考慮した設計 - -SUTの試験性は他のフィーチャーの設計や実装と並行して設計、実装すべきである。 - - SUTの制御や観測を可能にするなど、テストをサポートするソフトウェアインターフェースの可用性 -- 試験性はシステムの非機能要件の 1 つにすぎない - - 試験性の設計、実装はソフトウェアアーキテクトが行える -- TAE自身が行うか、TAEが関与して行う - -### 試験性を考慮した設計 - -優れたテスト自動化アプローチにとって最重要であり、手動テスト実行の場合にもメリットになる場合がある。 - -#### 観測性: - -- SUTは、システムの内部を把握できるインターフェースを提供する -- テストケースはそのインターフェースを使い、意図した振る舞いと実際の振る舞いが等しいかどうかなどをチェックする - -#### 制御性: - -- SUTは、SUTを操作するインターフェースを提供する - - UI要素、関数呼び出し、通信要素(TCP/IP、USBプロトコルなど)、電気信号(物理スイッチ)など - -#### 明確に定義されたアーキテクチャ - -- すべてのテストレベ ルにおいて制御と可視性を実現し、明確でわかりやすいインターフェースを提供するアーキテクチャである - -### TAEの役割 - -#### 自動テストを含めたSUTのテスト方法を検討する - -- 効果的:適切な領域をテストして重大なバグを見つける -- 効率的:大量の作業を 発生させない - -#### 特定のソフトウェアインターフェースの必要を明示する - -- 常にそれを明示し、開発担当者が実装しなければならない - - これは試験性を定義するために重要である -- 必要に応じて開発作業の予定を立てて予算を確保できるようにする - - プロジェクトの早い段階で追加のソフトウェアインターフェースを定義する際に重要になる - -### テストをサポートするソフトウェアインターフェースの例 - -- 最新のスプレッドシートによる強力なスクリプト機能 -- スタブまたはモックを適用してシミュレートすることにより、実際のインターフェースが存在しないソフトウェアのテストが可能になる - - まだ入手していないソフトウェアやハードウェア、高価すぎて購入できない ソフトウェアやハードウェア - - 電子金融取引、ソフトウェアサービス、専用サーバー、電子基板、機械部品など -- ソフトウェアインターフェース(スタブおよびドライバ)を使ってエラー条件をテストすることが可能である - - 例 - - 内部ハードディスクドライブ(HDD)を搭載したデバイスがある - - HDDを制御するソフトウェア (ドライバと呼ばれる)には、HDDの故障や摩耗に対するテストを行える必要がある - - これを行うために HDDが故障するのを待つのは、効率のよい(あるいは信頼性が高い)方法ではない - - HDDの欠陥や遅延をシミュレートするソフトウェアインターフェースを実装すれば - - ドライバソフトウェアが正常に動作 すること(エラーメッセージ、リトライなど)を検証できる -- 利用できる UIがまだ存在しない場合 - - 別のソフトウェアインターフェースを使ってSUTをテストできる - - UIを使うよりも優れたアプローチだと見なされることが多い - - 例 - - 組込みソフトウェアは、デバイスの温度を監視し、温度が一定レベルを超えたときに冷却機能を起動する必要がある - - 温度を指定するソフトウェアインターフェースを使えば、ハードウェアがなくてもテストできる -- SUTの状態の振る舞いを評価する場合 - - 状態遷移テストが使われる - - SUTが正しい状態にあるかどうかをチェックする場合 - - この目的を実現するためにカスタマイズされたソフトウェアインターフェースを経由して問い合わせる - -### 自動化の設計で考慮すべき事項 - -- テストツールとの互換性 - - 早い段階で確立すべきである - - 重大な問題である - - 重要な機能のテストの自動化可否に影響する可能性がある - - 例 - - グリッドコントロールと互換性がない場合、そのコントロールを使うすべてのテストができなくなる -- プログラムコードの開発やAPIの呼び出しが必要な解決策もある - -# 3. 汎用テスト自動化アーキテクチャ - -## 3.1 gTAAの概要 - -### テスト自動化エンジニア(TAE)の役割 - -- テスト自動化ソリューション(TAS)の設計、開発、実装、保守である - -### 汎用テスト自動化アーキテクチャ(gTAA) - -- 各ソリューションの開発にあたっては、繰り返し発生する以下のような概念、手順、アプローチが基本となる - - 同じようなタスクを行う - - 同じような質問に答える - - 同じような問題に優先順位をつけて対処する -- gTAAのレイヤー、コンポーネント、インターフェースを表す -- 特定のTAS向けのTAAとして具体化される - -これにより、構造化されたモジュール形式のアプローチを利用して、以下ので - -### テスト自動化ソリューションを構築方法 - -- 内部および外部で開発したコンポーネントによってTASを具体化できるように以下を定義する - - コンセプト - - レイヤー - - サービス - - インターフェース -- シンプルなコンポーネントを利用して効果的かつ効率的なテスト自動化を行えるようにする -- 各種ソフトウェアの製品ラインや製品ファミリー、およびソフトウェア技術やツールが異なるものを含め、 別のTASの開発やTASの改良の際 にテスト自動化コンポーネントを再利用する -- TASの保守や改良を容易にする -- TASユーザー用の基本的なフィーチャーを定義する - -### テスト自動化ソリューション(TAS)の構成 - -- テスト環境(およびその成果物) -- テストスイート(テストデータを含む一連のテストケース) - -### テスト自動化フレームワーク(TAF) - -- TASを実現するために使用でき、テスト環境の具体化の方法を提供する - - サポート - - ツール - - テストハーネス - - サポートライブラリ - -### TAAが従うことが推奨される原理 - -TASを簡単に開発、改良、保守できる。 - -#### 単一責任: - -- あらゆるTASコンポーネントは、単一の責任を持たなければならない -- また、その責任はコン ポーネント内に完全にカプセル化されなければならない -- TASのすべてのコンポーネントは厳密に以下の1つのことを担当すべきである - - キーワードやデータの生成 - - テストシナリオの作成 - - テストケースの実行 - - 結果記録 - - 実行レポートの生成 - -#### 拡張性: - -ref. B. Myerによるオープン/クローズドの原則など - -- あらゆるTASコンポーネントは、拡張に 対してオープンでなければならないが、変更に対してクローズドでなければならない -- この原則は、下位 互換性機能に影響を与えずにコンポーネントの振る舞いを変更または強化できる必要があることを意味している - -#### 置換: - -ref. B. Liskovによる置換原則など - -- あらゆるTASコンポーネントは、TASの全般的な振る舞いに影響を与えずに置換可能でなければならない -- コンポーネントは 1 つまたは複数のコンポーネントで 置き換えることができるが、外から見える振る舞いは同じでなければならない - -#### コンポーネントの分離: - -ref. R.C. Martin によるインターフェース分離の原則など - -- 汎用的で多目的な コンポーネントよりも、具体的なコンポーネントの方が望ましい -- 不要な依存性がなくなるので、置換や保守が容易になる - -#### 依存性の逆転: - -- TASのコンポーネントは、低レベルの詳細な部分に対してではなく、抽象的な部分に依存しなければならない -- コンポーネントは特定の自動テストシナリオに依存すべきではない - -### gTAAをベースとしたTAS - -- 一連のツールとそのプラグイン、およびコンポーネントにより実装される -- 特定のベンダーに依存しないことが重要である -- TASを実現するいかなる具体的な手法、技術、ツールも規定しない -- 任意のソフトウェア エンジニアリングアプローチを使って実装できる - - 構造化、オブジェクト指向、サービス指向、モデル駆動など -- 任意のソフトウェア技術やツールを使うこともできる -- TASは既製のツールを使って実装されるのが一般的である - - 通常はSUTに固有な機能や対応を追加する必要がある - -### 他のガイドラインや参照モデル - -- 指定された SDLC(Software Development LifeCycle)のソフトウェアエンジニアリング標準 -- プログラミング技術 -- フォーマット標準 - -### TASの保守性、信頼性、セキュリティの向上 - -- TAE - - ソフトウェアエンジニアリングにおけるスキル、経験、専門性を有していることが求められる - - 業界のコーディング標準やドキュメント標準、ベストプラクティスを認識する - - TASの開発に活用する必要がある - -### ドメイン特化した標準の例 - -- C または C++ 用の MISRA - - C++ 用の JSF コーディング標準 - - MathWorks Matlab/Simulink® 用の AUTOSAR ルール - -### 3.1.1 gTAAの概要 - -- 水平レイヤー構造となっている -- 各レイヤーが存在することもあれば存在しないこともある - -### テスト生成レイヤー - -テストケースの手動または自動での設計をサポートし、テストケースを設計する手段を提供する。 - -- 手動設計 -- テストモデル - -### テスト定義レイヤー - -テストスイートおよびテストケースの定義と実装をサポートする。 - -- ハイレベルおよびローレベルのテストを定義する手段が含まれている - - テスト条件 - - テストケース - - テスト手順 - - テストデータ - - テストライブラリ - - これらの組み合わせ -- SUTやテストシステムの技術およびツールからテスト定義を分離する - -### テスト実行レイヤー - -テストケースとテスト結果記録作業の実行をサポートする。 - -- テスト実行ツール - - 選択されたテストを自動的に実行する -- 記録およびレポート用のコンポーネント - -### テスト適合レイヤー - -SUTのさまざまなコンポーネントやインターフェースを自動テストに適合させるために必要なコードを提供する。 - -- SUTに接続するための各種アダプターを提供する - - GUI - - API - - プロトコル - - サービス - - データべース - - シュミレータ - - エミュレータ - など - -### 関連システムとのインターフェース - -- 対象 - - プロジェクトマネジメント - - 構成管理 - - テストマネジメント -- 例 - - テストマネジメントとテスト適合レイヤー間のインターフェースを利用すると - - 選択されたテスト構成に応じて適切なアダプターを選択し、構成することができる - -### テスト実行を自動化する場合 - -- テスト実行レイヤーとテスト適合レイヤーを利用する必要がある -- この2つを分離する必要はなく、ユニットテストフレームワークなどで同時に実現することも可能である - -### TASの実装 - -- ほとんどの場合、下から上へ向かって行われる -- 手動テスト用のテストケースを自動で生成する場合など、他のアプローチも役立つ可能性がある -- TASを段階的(スプリントなど)に実装することが推奨される - - できるだけ早くTASを使用してTASの付加価値を証明できる -- コンセプトの証明(PoC)を行うことも推奨される - -### プロジェクト - -- ソフトウェア開発プロジェクトとして認識、編成、管理する必要がある -- 専任のプロジェクトマネジメントも必要になる -- プロジェクトとして以下は分離できる - - TAF開発 - - 企業全体または製品ファミリーや製品ラインのテスト自動化サポート - - TAS - - 具体的なプロダクトのテスト自動化 - -### 3.1.2 テスト生成レイヤー - -#### 構成する支援ツール - -- テストケースの手動設計 -- テストデータの作成、キャプチャ、導出 -- SUTやその環境を定義するモデルからのテストケースの自動生成 - - 自動モデルベースドテスト - -#### 一般的なコンポーネント - -- テストスイート構造を編集またはナビゲーションする -- テストケースとテスト目的またはSUT要件を関連付ける -- テスト設計を文書化する - -##### 自動テスト生成に含まれる機能 - -- SUT、SUTの環境、テストシステムをモデル化する機能 -- テスト方針の定義およびテスト生成アルゴリズムの構成やパラメーター化を行う機能 -- 生成されたテストからモデル(要素)にさかのぼる機能 - -### 3.1.3 テスト定義レイヤー - -#### 構成する支援ツール - -- ハイレベル、ローレベルのテストケース定義 -- ローレベルテストケースのテストデータ定義 -- 単一、一連のテストケースのテスト手順の定義 -- テストケースを実行するためのテストスクリプトの定義 -- テストライブラリへのアクセスの提供 - - キーワード駆動アプローチの場合など - -#### 一般的なコンポーネント - -- テストデータを分類/制限、パラメーター化、具体化する -- テストシーケンスや一連のテストの振る舞い(制御文や式を含む)を明示する - - それらをパラメーター化およびグループ化する -- テストデータ、テストケース、テスト手順を文書化する - -### 3.1.4 テスト実行レイヤー - -#### 構成する支援ツール - -- テストケースの自動実行 -- テストケースの実行結果の記録 -- テスト結果の報告 - -#### 一般的なコンポーネント - -- テスト実行のためにSUTの前処理および後処理をする -- テストスイートの前処理および後処理をする -- テスト準備の構成および設定を行う -- テストデータとテストケースを処理して実行可能スクリプトに変換する -- テストシステムやSUTを測定し、テスト実行やフォールトインジェクション(の一部)を記録する -- テスト実行中のSUTの結果を分析し、後続のテストの進行を調整する -- 自動テストケース実行結果についてSUTのテスト結果の妥当性を確認する - - 期待結果と実行結果を比較する -- 自動テスト実行が時間内に終わるよう制御する - -### 3.1.5 テスト適合レイヤー - -#### 構成する支援ツール - -- テストハーネスの制御 -- SUTの操作 -- SUTの監視 -- SUT環境のシミュレートまたはエミュレート - -#### 提供する機能 - -- 以下の間を仲介する - - 特定の技術によらないテスト定義 - - SUTやテストデバイスに固有の技術要件 -- SUTと連携するために、さまざまな技術固有のアダプターを適用する -- テスト実行を分散する - - 複数のテストデバイスやテストインターフェースに - - またはローカルでテストを実行する - -### 3.1.6 TASの構成管理 - -さまざまなイテレーションやバージョンで開発され、SUTのイテレーションやバージョンとの互換性が必要となる。 - -#### 要件 - -- テストモデル -- テストデータ、テストケース、ライブラリを含むテストの定義や仕様 -- テストスクリプト -- テスト実行エンジンと補助ツール、補助コンポーネント -- SUT用のテストアダプター -- SUT環境のシミュレーターやエミュレーター -- テスト結果やテストレポート - -#### バージョン管理 - -- SUTのバージョンと一致した正しいバージョンでなければならない -- 状況によっては以前のTASのバージョンに戻さなければならない場合がある - - 古いバージョンのSUTで現場の問題を再現しなければならない場合など - -### 3.1.7 TASのプロジェクトマネジメント - -- テスト自動化プロジェクトはすべてソフトウェアプロジェクトである -- 他のソフトウェアプロジェクトと同じプロジェクトマネジメントが必要になる - -#### TASの開発におけるTAE - -- 確立されたSDLC手法のすべてのフェーズのタスクを行う必要がある - - Software Development LifeCycle -- 以下のようにTASの開発環境を設計しなければならない - - ステータス情報(メトリック)を容易に抽出できる - - TASのプロジェクトマネジメントに自動的に報告される - -### 3.1.8 TASのテストマネジメントサポート - -- SUTのテストマネジメントをサポートしなければならない -- テスト結果記録やテスト結果を含むテストレポートはいずれかが必要となる - - 抽出が容易である - - SUTのテストマネジメント(人またはシステム)に自動的に提供される - -## 3.2 TAAの設計 - -### 3.2.1 TAAの設計の概要 - -- 設計には多くの重要な作業が必要になる -- テスト自動化プロジェクトや組織のニーズに応じて順位付けする -- 複雑度により、必要な作業は増減する場合がある - -#### テスト自動化アプローチの要件 - -- テストプロセスのどの作業やフェーズを自動化すべきか - - テストマネジメント - - テスト設計 - - テスト生成 - - テスト実行 - など -- テスト設計とテスト実装の間にテスト生成を挿入することによって基本的なテストプロセスを洗練する -- どのテストレベルをサポートすべきか - - コンポーネントレベル - - 統合レベル - - システムレベル - など -- どのタイプのテストをサポートすべきか - - 機能テスト - - 適合テスト - - 相互運用性テスト - など -- テストに関するどの役割をサポートすべきか - - テスト実行者 - - テストアナリスト - - テストアーキテクト - - テストマネージャー - など -- どれをサポートすべきか - - 実装されるTASの寿命や存続期間などを定義する - - ソフトウェアプロダクト - - ソフトウェア製品ライン - - ソフトウェア製品ファミリー -- どの技術をサポートすべきか - - SUTに使われる技術との互換性を考慮してTASを定義する - -#### アプローチの利点と欠点 - -異なる設計やアーキテクチャを用いたアプローチと比較、対比を行う。 - -##### テスト生成レイヤーの考慮事項: - -すべての組み合わせのテストを生成するのは不可能である。\ -現実的なカバレッジ基準、 重み付け、リスクアセスメントなどを参考にする - -- テスト生成を手動にするか自動にするかの選択 -- テスト生成の選択 - - 要件ベースド - - データベースド - - シナリオベースド - - 振る舞いベースド - など -- テスト生成戦略の選択 - - データベースのアプローチのためのクラシフィケーションツリーなどのモデルカバレッジ - - シナリオベースのアプローチのためのユースケース/例外ケースカバレッジ - - 振る舞いベースのアプローチのための遷移/状態/パスカバレッジ - など -- テストの選定戦略の選択 - -##### テスト定義レイヤーの考慮事項: - -- どのテスト定義を利用するかの選択 - - データ駆動、キーワード駆動、パターンベースド、モデル駆動 -- テスト定義の表記法の選択 - - スプレッドシート - - ドメインに特化したテスト用の言語 - - Testing and Test Control Notation(TTCN-3) - - UML Testing Profile(UTP)などを使用した表 - - 状態ベースの表記法 - - 確率的表記法 - - データフロー表記法 - - ビジネスプロセス表記法 - - シナリオベースの表記法 - など -- スタイルガイドやガイドラインの選択 - - 高品質なテストを定義する -- テストケースリポジトリの選択 - - スプレッドシート - - データベース - - ファイル - など - -##### テスト実行レイヤーの考慮事項: - -- テスト実行ツールの選択 -- どのアプローチを採用するかの選択 - - テスト手順を実現する(仮想マシンの使用による) - - 選択されたテスト実行ツー ルに依存する - - アプローチ - - インタプリタ型 - - コンパイル 型 -- テスト手順を実装する技術の選択 - - 選択したテスト実行ツールに依存する - - 技術 - - C などの命令型 - - Haskell や Erlang などの関数型 - - C++、C\#、Java などのオブジェクト指向型 - - Python や Ruby などのスクリプト - - ツール固有の技術 -- ヘルパーライブラリの選択 - - テスト実行を容易にする - - ライブラリ - - テストデバイスのライブラリ - - エンコーディング/デコーディングライブラリ - など - -##### テスト適合レイヤーの考慮事項: - -- SUTとのテストインターフェースの選択 -- テストインターフェースを操作・観測するツールの選択 -- テスト実行の際にSUTを監視するツールの選択 -- テスト実行をトレースするツールの選択 - - テスト実行のタイミングを含む - -#### TAAの抽象化 - -##### メリット - -- 異なるテスト環境や対象技術で同じテストスイートを使えるようになる -- テスト成果物の移植性が向上する - - 技術への依存度を軽減できる -- TASのロックイン効果を回避できる - - ベンダーへの非依存性が保証される -- 保守性や新しいSUTに使われる技術およびその変化への環境適応性も向上する -- 技術者以外がTAA(およびそれをTASとして具体化したもの)を使いやすくすることにもつながる -- 可読性や理解性が向上する - - テストスイートを文書化(視覚的手段を含む)して高レベルで説明できる - -##### TAEが議論すべき事項 - -- TASのどの領域でどのレベルの抽象化を使用するか - - 対象 - - ソフトウェア開発 - - 品質保証 - - テスト - - インターフェース - - テスト適合レイヤー - - テスト実行レイヤー - - どれを外部化するか - - どれを形式的に定義するか - - TAAの存続期間にわたってどの安定性を確保するか -- いずれを使うか - - 抽象化したテスト定義 - - テスト実行レイヤーでテストスクリプト - -##### TAEが認識すべき事項 - -- どのアプローチを使用してテスト生成を抽象化するか - - テストモデル - - モデルベースドテスト -- 高度な実装と単純な実装との間にトレードオフがある - - 機能性 - - 保守性 - - 拡張性 - -##### 抽象化の結果 - -- 進化の余地や新しいアプローチや技術への移行に関する柔軟性が向上する - - 初期投資が増加する - - テスト自動化のアーキテクチャやツールの複雑度が増す - - スキルセット要件が高くなる - - 学習コストが大きくなる - など - - 最初の損益分岐点に到達するまでの時間が長くなる - - 長期的に見ればそれに見合うだけの成果をあげられる可能性がある -- TASのパフォーマンスが下がる場合もある - -##### ROI(投資収益率) - -- TAM の責任範囲である -- TAE は技術的評価や比較を行い、ROI分析に必要な情報を提供する - - アーキテクチャ - - アプローチ - - タイミング - - コスト - - 工数 - - 利益 - -#### SUTに使われる技術やTASとの関係 - -##### SUTのテストインターフェースへのアクセス - -- ソフトウェアレベル: - - SUTとテストソフトウェアが相互にリンクされる場合など -- APIレベル: - - (リモートの)アプリケーションプログラミングインターフェースが提供する関数/操作/メソッドをTASが呼び出す場合など -- プロトコルレベル: - - HTTP、TCPなどでTASがSUTと通信する場合など -- サービスレベル: - - Web サービスや RESTful サービスなどでTASがSUTのサービスと通信する場合など - -##### TAAの相互作用のパラダイム - -TASとSUTが API、プロトコル、サービスで分離され、連携する場合に決定する。 -SUTアーキテクチャに依存し、SUTアーキテクチャに影響する。 - -- イベント駆動パラダイム - - 交換されるイベントやイベントバスを通した相互作用を実現する -- クライアント/サーバーパラダイム - - サービス要求者がサービス提供者のサービスを呼び出すという相互作用を実現する -- ピアツーピアパラダイム - - ピア間での任意の方向のサービス呼び出しによる相互作用を実現する - -#### SUT環境 - -- スタンドアロンソフトウェア -- 他のソフトウェアとの関係でのみ動作するソフトウェア - - システムオブシステムズなど -- ハードウェア - - 組込みシステムなど -- 環境コンポーネント - - サイバーフィジカルシステムなど - -##### テスト環境の例とサンプル使用の例 - -TASは、自動テストのセットアップの一環として、SUT環境のシミュレートまたはエミュレートを行う。 - -- SUTとTASの両方の機能を備えたコンピューター - - ソフトウェアアプリケーションのテスト -- SUTやTASのそれぞれとネットワークで接続された個々のコンピューター - - サーバーソフトウェアのテスト -- SUTの技術的インターフェースを操作および観測する追加のテストデバイス - - セットトップボックスなどのソフトウェアのテスト -- SUTの操作環境をエミュレートするネットワーク接続テストデバイス - - ネットワークルーターのソフトウェアのテスト -- SUTの物理環境をシミュレートするシミュレーター - - 組込み制御ユニットのソフトウェアのテスト - -#### TASプロジェクトにかかる作業の見積り - -- TAM の責任範囲である -- TAE はTAM を支援する - - TAA設計・実装の時間と複雑度を適切に見積る - -##### 見積りの方法 - -- 類推による見積り - - ファンクションポイント - - 3点見積り - - ワイドバンドデルファイ - - 専門家による見積り - など -- ワークブレークダウンストラクチャの使用による見積り - - マネジメントソフトウェア - - プロジェクトテンプレート - など -- 係数見積り - - Constructive Cost Model(COCOMO) - など -- サイズベースの見積り - - ファンクションポイント法 - - ストーリーポイント法 - - ユースケース分析 - など -- グループ見積り - - プランニングポーカー - など - -#### TASの使用性 - -TAEには 指定されたテストウェアアーキテクチャ実装の使いやすさの問題に対処する明確な責任がある。 - -- テスト担当者指向の設計 -- 使いやすさ -- 他の役割への支援 - - ソフトウェア開発 - - 品質保証 - - プロジェクトマネジメント -- 効果的な編成、ナビゲーション、検索 -- 有用な文書化、マニュアル、ヘルプテキスト -- 実用的なレポート -- フィードバックや経験的洞察に対応するためのイテレーティブ設計 - など - -### 3.2.2 テストケース自動化へのアプローチ - -- テストケース - - SUTに対して実行される一連のアクションに変換するが必要である -- アクション - - テスト手順での文書化および/またはテストスクリプトで実装する -- 自動テストケース - - SUTを操作するためのテストデータの定義を含む - - SUTが期待結果を実現したことを検証する - -#### アプローチの種類 - -容易な選択肢はより短時間で付加価値を提供できるが、保守性の低いソリューションが生まれる。 - -1. 直接テストケースを実装する - - 抽象化が不足している - - 保守の負荷が増加する - - 最も推奨されない -2. テスト手順を設計し、それを変換する - - 抽象化されている - - テストスクリプトを生成する自動化が不足している -3. ツールを使用してテスト手順を変換する - - 抽象化されている - - 自動テストスクリプト生成も自動化されている -4. 自動テスト手順を生成するツールを使用する、モデルから変換する、また はその両方を行う - - 自動化の成熟度が最も高い - -#### アプローチ方法 - -- 種類 1 - - キャプチャ/プレイバックアプローチ -- 種類 2、3 - - 構造化スクリプティングアプローチ - - データ駆動アプローチ - - キーワード駆動アプローチ -- 種類 4 - - モデルベースドテスト - - プロセス駆動アプローチ含む - -##### キャプチャ/プレイバックアプローチ - -- **主な概念** - - ツールを使用してSUTとのやりとりをキャプチャしつつ、テスト手順で定義された一連の手順を実行する - - 入力がキャプチャされ、後ほどチェックするために出力も記録される - - 操作を再生する際には出力チェックを行う - - **手動:** - - テスト担当者がSUTの出力を監視して不正がないかを検出する必要がある - - **完全:** - - SUTはキャプチャの際に記録されたすべてのシステム出力を再現する必要がある - - **厳密:** - - 完全 + 詳細のレベルまで記録 - - **チェックポイント:** - - ある時点で選択されたシステム出力の指定された値のみがチェックされる -- **利点** - - GUIレベル、APIレベルでSUTに使用する - - 導入初期の段階では、セットアップや使用が容易である -- **欠点** - - キャプチャしたSUT操作はキャプチャ時のSUTのバージョンに強く依存する - - 保守や進化は難しい - - GUIレベルの記録は、要素の位置が変更されただけでも、テストスクリプトに影響する可能性がある - - 変更に弱い - - テストケース(スクリプト)の実装を開始できるのは、SUTが利用できるようになってからである - -##### 線形スクリプティング - -- **主な概念** - - いくつかの手動テスト手順から始まる - - これらは文書化されてない場合もある - - どのテストをどのように実行するかは「暗黙知」である場合がある - - 1 人または複数人のテストアナリスト - - テストツールが一連の手順を記録する間、各テストは手動で実行される - - 場合によってはSUTの画面出力を視覚的に記録する - - 1 つのテスト手順につき 1 つの(通常は大きな)スクリプトになる - - 記録されたスクリプトを編集して可読性を向上させられる - - 重要な場所に何が起きているかのコメント を追加するなど - - ツールのスクリプト言語を使用してさらにチェックを追加できる - - ツールで再生することができる - - 記録時にテスト担当者が行ったのと同じ手順を繰り返す - - GUIテストの自動化に使用できるが、適切な技法ではない - - ソフトウェアの多くのリリースのために大量のテストを自動化する必要があるような場合 - - SUTの変更に伴う保守コストが高くなる - - 変更が行われるたびに、記録したスクリプトで多くの部分を変更しなければならない -- **利点** - - 自動化を始めるにあたって必要になる準備作業がまったくあるいはほとんどない - - ツールの使用方法を習得すれば、手動テストを記録して再生するだけで済む - - テストツールの追加操作を行い、実行結果と期待結果を比較してソフトウェアが正常動作することを検証する - - プログラミングのスキルは必須ではないが、役立つことが多い -- **欠点** - - 多くの欠点がある - - 新しい自動テストを構築するコストを削減できる余地は多くない。 - - テスト手順を自動化するために必要な作業の量は、それを実行するために必要なサイズ(手順の数)に依存する - - 1000 個目のテスト手順を自動化する際にも、100 個目のテスト手順を自動化するのと同じ作業量が必要になる。 - - スクリプトに影響するソフトウェアの変更があった場合、それらすべてを保守する必要がある - - 入力値が異なる同じようなテストのスクリプトがあった場合、2 つのスクリプトに同じ一連の命令が含まれる - - 命令に含まれる情報(命令の引数またはパラメーターと呼ばれる)のみが異なる - - 複数のテスト(すなわち複数のスクリプト)があった場合、すべてに同じ一連の命令が含まれる - - 自然言語ではなくプログラミング言語で書かれているため、プログラマー以外が理解するのは難しい - - 独自の言語を使用するものもあり、言語の学習や習得には時間がかかる - - 記録されたスクリプトは、コメントがもしあれば、その中には通常の文章のみを含む - - 長いスクリプトでは、テストの各手順で何が起こっているのかを説明するコメントが付いていることが望ましい - - これにより、保守が容易になる - - テストに多くの手順が含まれる場合、スクリプトはすぐに肥大化する - - スクリ プトに多くの命令が含まれる - - モジュール形式ではないので、保守が難しい - - 一般的なソフトウェアの再利用性やモジュール型パラダイムに準じておらず、使用するツールと密結合である - -##### 構造化スクリプティング - -- **主な概念** - - 線形スクリプティング技法にスクリプトライブラリを導入している - - 複数のテストで共通して用いられる、一連の命令を実行する再利用可能スクリプトが含まれる - - SUTインターフェースの操作など -- **利点** - - 保守の際に必要な変更が大幅に削減される - - 新しいテストを自動化する際のコストを削減できる - - 最初からスクリプトを作成するのではなく、既存のスクリプトを使用できる - - 少ない量のスクリプトで、多くのテストを自動化することができる - - スクリプト作成と保守のコストに直接的に影響する - - 2つ目以降のテストの自動化には 1 つ目ほど手間はかからない -- **欠点** - - 共有スクリプトを作成する最初の作業は欠点に思われがち - - この初期投資を適切に行うことができれば、大きな利益となって返ってくる - - プログラミングのスキルが必要になる - - スクリプトを文書化し、必要なスクリプトを容易に見つけられるように適切に管理される必要がある - - そのため、適切な命名規約が役に立つ - -##### データ駆動テスト - -- **主な概念** - - 構造化スクリプティング技法がベースとなっている - - 違いは、テスト入力方法にある - - 入力はスクリプトから切り離され、ファイルに格納される - - 通常はデータファイルと呼ばれる - - テストスクリプトを再利用して多くのテストを実装できる - - 「再利用可能な」テストスクリプトを「制御」スクリプトと呼ぶ - - テストを実行するために必要な一連の命令が含まれる - - 入力データはデータファイルから読み取られる - - 1つの制御スクリプトを多くのテストで使用することも可能である - - 幅広いテストを自動化するには不十分であることが多い - ‐ 多数の制御スクリプトが必要になる - - 自動化するテストの数全体に比べればわずかな数にすぎない -- **利点** - - 新しい自動テストを追加するコストを大幅に削減できる - - テストカバレッジの増加につながる - - 有用なテストを数多く自動化できる - - 特定の領域を深くテストすることができる - - テストがデータファイルで「記述」される - - データファイルを投入するだけで「自動」テストを指定できる - - テストアナリストが自動テストを指定する自由度が増す - - テクニカルテストアナリストへの依存度を低くできる - - 希少なリソースである可能性がある -- **短所** - - データファイルを管理し、TASが読み取れるようにしなければならない - - これには適切なアプローチをとることができる - - 否定テストケースが見逃される - - テスト手順とテストデータの組み合わせである - - テストデータを対象としたアプローチでは、「否定テスト手順」が見逃される - -##### キーワード駆動テスト - -- **主な概念** - - データ駆動スクリプティング技法がベースとなっている - - データファイルは「テスト定義」ファイルと呼ばれる - - アクションワードファイルなど - - 制御スクリプトは 1 つしかない - - テスト定義ファイルには同じ内容のデータファイルより簡単に理解できる方法で表現されたテストが含まれる - - データファイルと同じようなデータが含まれるが、キーワードファイルには高レベルな命令も含まれる - - キーワードまたは「アクションワード」 - - キーワードは意味があるものを選択する - - テストアナリスト、記述されるテスト、テストされるアプリケーションにとって - - キーワード - - テスト対象システムとのさまざまな相互作用を表す - - ビジネスとシステムの高位レベルの相互作用を表すために使用する - - たとえば、注文の実行 - - 配列は、テストケースを指定する - - 関連するテストデータを含む - - 検証ステップに特殊なキーワードを使うこともできる - - 操作ステップと検証ステップの両方を含めることもできる - - テストアナリストの責任範囲には、キーワードファイルの作成と保守が含まれる - - 補助スクリプトが一度実装されれば、キーワードファイルに記述するだけで「自動」テストを追加できる -- **利点** - - 制御スクリプトとキーワード用の補助スクリプトを記述できれば、新しい自動テストを追加するコストを大きく削減できる - - テストがキーワードファイルで「記述」される - - テストアナリストはキーワードと関連するデータを使用してテストを記述するだけで「自動」テストを作成できる - - テストアナリストが自動テストを作成する自由度が増す - - (希少なリソースである可能性がある)テクニカルテストアナリストへの依存度を低くできる - - キーワードは、意味のある結果を生成する詳細な一連のアクションを表すものにする - - 複数の詳細な手順が含まれている - - 例:オンラインショッピングアプリケーションでのアクション - - 「アカウントの作成」、「注文の実行」、「注文ステータスのチェック」 - - 高レベルのアクションだけでテストを定義できるようにする - - 高レベルのアクションを実現し、詳細な手順について言及しない - - テストアナリストがシステムテストについて説明する場合、高レベルのアクションについて述べることが多い - - 複雑さがキーワードで隠蔽される - - 保守性が高く、読み取り/書き込みも容易になる - - SUT のインターフェースの複雑度を抽象化することができる -- **短所** - - 実装はテスト自動化エンジニアにとって大きな負担である - - サポートしないツールを使用する場合は、特にそれが当てはまる - - 小規模なシステムには実装のオーバーヘッドが大きすぎる - - コストが利点を上回る可能性がある - - 正しいキーワードが実装されるように十分注意を払う必要がある - - 優れたキーワードは数多くのテストで使用される - - 適切でないキーワードは 1 度または数回しか使われない - -##### プロセス駆動スクリプティング - -- **主な概念** - - キーワード駆動スクリプティング技法がベースとなっている - - シナリオがスクリプトで構成される点にある - - パラメーターとしてテストデータを受け取るか、ハイレベルのテスト定義と組み合わされている - - アクション間の論理関係として扱いやすい - - フィーチャーテストで「注文の実行」 の後に「注文ステータスのチェック」を行う - - ロバストネステストで「注文の実行」を行わずに 「注文ステータスのチェック」を行う -- **利点** - - プロセス的でシナリオベースのテストケース定義を使用する - - ワークフローからテスト手順を定義することができる - - 詳細なテスト手順を表すテストライブラリを使用して高レベルワークフローを実現する -- **短所** - - テクニカルテストアナリストがSUTのプロセスを理解するのは容易ではない - - プロセス指向スクリプトの実装も同様である - - ツールがビジネスプロセスのロジックをサポートしていない場合、特にそれが当てはまる - - 正しいキーワードを使って正しいプロセスが実装されるように十分注意を払う - - 優れたプロセスは他のプロセスから参照され、多くの関連テストで活用される - - 適切でないプロセスは妥当性やエラー検知能力などの点で労力に見合わない - -##### モデルベースドテスト - -- **主な概念** - - テストケースを自動生成することを指し、テストケースを自動実行することとは異なる - - TAAのスクリプティング技法を抽象化した(準)形式モデルを使用する - - 任意のスクリプティングフレームワーク用のテストを導出するために、異なるテスト生成手法を使用できる -- **利点** - - 抽象化によりテストの本質に集中できる - - テスト対象のビジネスロジック、データ、シナリオ、構成などに関すること - - 異なる対象システムや対象技術のテストを生成できる - - テスト生成に使用するモデルが将来を見据えたテストウェアを表現できる - - 技術の進化に合わせて再利用したり保守できる - - 要件が変更された場合でも、テストモデルを対応させるだけで済む - - すべてのテストケースは自動的に生成される - - テストケース設計技法は、テストケースジェネレータに組み込まれる -- **短所** - - 効果的に実行するには、モデルに関する専門知識が必要になる - - 抽象化してモデリングを行うタスクは困難な場合もある - - モデリングやモデルベースドテストのツールはまだ主流ではなく、成長途中にある - - テストプロセスの調整が必要になる - - テスト設計者の役割を確立する - - モデルがSUTの品質保証の主な成果物となるため、品質保証や保守を行う - -### 3.2.3 SUTの技術的考慮事項 - -TAAの設計にあたっては、SUTの技術的側面を考慮すべきである - -#### SUTのインターフェース - -- 内部インターフェース - - システムの内部 -- 外部インターフェース - - システム環境やユーザーに対するもの - - コンポーネントによって外部に公開されているもの -- テスト手順による影響を受ける - - インターフェースの制御・観測を行える必要がある - - インターフェースはテスト可能でなければならない -- 詳細レベルで記録しなければならない場合がある - - TASとの相互作用 - - タイムスタンプが含まれる -- 個々のテストにスコープを当てる - - プロジェクト開始時のアーキテクチャ定義の際 - - アジャイル環境の場合は継続的 - - SUTがテスト可能であるために必要なテストインターフェースやテスト設備の可用性を検証する - - 試験性を考慮した設計 - -#### SUTのデータ - -- 構成データを使って具現化、構成、管理などを制御する -- ユーザーデータの処理も行う -- 他のシステムからの外部データを使用してタスクを完了させることもある -- 定義可能かつ構成可能であり、TAAから具現化する -- 具体的な方法は、TAAの設計で決定する -- 扱い方 - - パラメーター - - テストデータシート - - テストデータベース - - 実データ - -#### SUTの構成 - -- さまざまな構成で導入される - - 異なるオペレーティングシステム - - 異なる対象デバイス - - 異なる言語設定 - など -- TAAが複数のSUT構成に対処しなければならない -- 異なるTAAのテスト設定(ラボ内)や仮想テスト設定(クラウド内)が必要になる -- コンポーネントのシミュレーター・エミュレーターの追加が求められる - -#### SUTの標準と法的設定 - -- 互換性のある方法でTAAを設計する -- 法律や標準に関する要件を考慮する - - テストデータのプライバシー要件 - - TAAの記録およびレポート機能に影響する機密性要件 - -#### SUTの開発に使用されるツールおよびツール環境 - -- さまざまな目的の為、さまざまなツールが使われる - - SUTの要件エンジニアリング - - 設計 - - モデリング - - コーディング - - 統合 - - 導入 -- 独自のツールは以下を考慮する - - ツールの互換性 - - トレーサビリティ - - 成果物の再利用 - -#### ソフトウェアプロダクトのテストインターフェース - -- プロダクトリリースの前にすべてのテストインターフェースの削除を行わない -- 最終的なプロダクトに影響を与えることなく、これらのインターフェースをSUTに残しておく -- 問題の診断や保守リリースのテストにこれらのインターフェースを使用することができる -- インターフェースがセキュリティリスクとならないことを検証する -- テストインターフェースを使うことができないように無効化できる - -### 3.2.4 開発/QA プロセスの考慮事項 - -TAAの設計には、SUTの開発および品質保証のプロセスについて考慮する - -#### テスト実行制御要件 - -TAAで必要とされる自動化のレベルによっては、以下をサポートする - -- 対話的テスト実行 -- バッチモードテスト実行 -- 完全自動テスト実行 - -#### レポート要件 - -- 形式やレイアウトが異なる固定のテストレポート -- パラメーター化されたテストレポート -- 定義済みのテストレポート - -#### 役割とアクセス権 - -- セキュリティ要件によっては、TAAが役割やアクセス権のシステムを提供する - -#### 確立されたツール群 - -- SUTプロジェクトマネジメント -- テストマネジメント -- コードおよびテストのリポジトリ -- 欠陥追跡 -- インシデントマネジメント -- リスク分析 -- バージョン管理 - - テストスクリプトは、SUTのコードと同じプロセスに従って改訂されるようにする -- 他のツールとシームレスに統合されているツール・ツールセット - など - -## 3.3 TASの開発 - -### 3.3.1 TASの開発の概要 - -- 他のソフトウェア開発プロジェクトに類似する -- 同じ手順やプロセスに従うことができる - - 開発担当者とテスト担当者によるピアレビューなど -- TASに固有な点は、SUTとの互換性と同期である - - TAAの設計およびTASの開発で検討する - - SUTはテスト戦略の影響を受ける - - TASがテストインターフェースを利用できるようにしなければならない -- TASのための基本的なSDLC - - 分析 - - TASの一連の要件を分析および収集する - - 設計 - - TAAで定義されているように、 この要件はTASの設計の指針となる - - 開発 - - ソフトウェアエンジニアリングのアプローチにより、この設計がソフトウェアになる - - TASは専用のテストデバイスハードウェアも使用する場合がある - - テスト - - 他のソフトウェアと同じように、TASはテストする必要がある - - これはTASの基本的な機能をテストすることによって行われる - - 導入 - - TASとSUTは相互に影響する - - 改善 - - TASを改修する必要が生じる - - テスト機能の拡張をする - - テストを変更する - - SUTの変更に合わせてTASを更新する - - SDLC に基づく新たな TA 開発が必要になる - - TASのバックアップ、アーカイブ、廃棄は示されていない - - 組織で確立された手法に従うべきである - -### 3.3.2 TASとSUTの親和性 - -#### プロセスの親和性 - -- SUTのテストはSUTの開発と同期すべきである -- テスト自動化を行う場合は、TASの開発とも同期させる -- 以下の整合性をとる - - SUTの開発プロセス - - TASの開発プロセス - - テストプロセス -- 以下の面でSUTとTASの開発に親和性があると良い - - プロセス構造 - - プロセスマネジメント - - 支援ツール - -#### チームの親和性 - -- 開発間の親和性のもう1つの側面である -- アプローチやマネジメントに親和性を取り入れると、両方のチームにメリットがある - - 要件 - - 設計 - - 開発の成果物のレビュー - - 問題についての議論 - - 互換性のあるソリューションの発見 -- お互いのコミュニケーションや対話の際にも役立つ - -#### 技術の親和性 - -- 技術の親和性も考慮すべきである -- シームレスな相互作用を設計および実装する -- アダプターやラッパーなど何らかの仲介するものを使用することで実現できる - - 技術的ソリューションが利用できないなどの理由で不可能な場合でも - -#### ツールの親和性 - -- ツールの親和性を考慮する - - マネジメント - - 開発 - - 品質保証 -- 同じツールを使用している場合、情報交換や調整が容易になる - - 要件マネジメント - - 課題マネジメント - -### 3.3.3 TASとSUTの同期 - -#### 要件の同期 - -- 要件を明確にすることが、SUTとTASの両方の要件の開発につながる -- TASの要件 - 1. ソフトウェアベースのシステムとしてTASの開発に対処する要件 - - TASのフィーチャー要件が含まれる - - テスト設計 - - テスト仕様 - - テスト結果分析 - など - 1. TASを用いてSUTのテストに対処する要件 - - テスト要件と呼ばれる - - SUTの要件に対応する -- TASがテストするすべてのSUTのフィーチャーや特性を反映する -- SUTやTASの要件が更新されるときは、必ず両者の一貫性を検証する - - TASによってテストされるすべてのSUT要件がテスト要件で定義されていることを確認する - -#### 開発フェーズの同期 - -- SUTのテストが必要になるときにTASの準備が完了しているよう、開発フェーズを調整する -- 最も効率がよいのは、SUTとTASの要件、設計、仕様、実装が同期していることである - -#### 欠陥追跡の同期 - -- 欠陥は以下の可能性がある - - SUTに関連するもの - - TASに関連するもの - - 要件/設計/仕様に関連するもの -- 片方で欠陥を修正するともう片方に影響が及ぶ可能性がある - - 2つのプロジェクトには関連性がある -- 欠陥追跡 と確認テストは、TASとSUTの両方に対処しなければならない - -#### SUTとTASの改善の同期 - -- SUTとTASはどちらも改善できる - - 新規フィーチャーの組込み - - フィーチャーの無効化 - - 欠陥の修正 - - 環境の変更 - - 片方がもう片方のコンポーネントとなっているので、それぞれの変更も含まれる -- SUTとTASのどちらかに変更が適用されると、もう一方が影響を受ける - - 変更のマネジメントはSUTとTASの両方に対処すべきである - -#### SUTとTASの開発プロセス間を同期させる - -##### 2つのフェーズで同期されるアプローチ - -1. SUTの設計 - - TASの分析に使用される -1. SUTのテスト - - 導入済みのTASを使用する - -##### 手動および自動の両方のテストを使用したハイブリッドアプローチ - -1. SUTの設計 - - 手動テストの分析に使用される - - TASの分析に使用される -1. SUTのテスト - - 手動テストを使用する - - 導入済みのTASを使用する - -### 3.3.4 TASの再利用性の構築 - -#### TASを再利用するレベル - -- 製品ライン -- 製品フレームワーク -- 製品ドメイン -- プロジェクトファミリー - -#### 再利用の要件 - -- TAS成果物に関連性がある対象 - - 他のプロダクトバリエーション - - プロダクト - - プロジェクト - -#### 再利用可能なTAS成果物 - -- モデル化されたテストの目標 -- テストシナリオ -- テストコンポーネント -- テストケース -- テストデータ -- テスト手順 -- テストライブラリ自身(の一部) -- テストエンジン -- テストレポートフレームワーク -- SUTのコンポーネント -- インターフェースのアダプター - -#### 再利用性を高める - -- TAAに従う - - 必要に応じて改訂・更新する -- TAS成果物を文書化する - - わかりやすくする - - 新しい状況に組み込めるようにする -- すべてのTAS成果物の正確性を保証しする - - 品質の高さによって新しい状況での使用が促進されるようにする - -### 3.3.5 さまざまな対象システムのサポート - -TASがさまざまな構成のソフトウェアプロダクトをテストできる。 - -- TASの変動性の設計は主にTAAに関することである -- ライフサイクル全般にわたって考慮すべきである -- 変動性の選択肢や形態を改訂、追加、削除する -- 継続的な検討と作業が必要である - -#### SUTコンポーネントの構成 - -TASは技術的な相違に対応する機能を実装する - -- TAAの定義の際に決定される -- 全てのテスト - - 数や相互連携 - - 実行される環境 - - ソフトウェア - - ハードウェア - - 実装するために使われる技術 - - プログラミング言語 - - オペレーティングシステム - - 使用するライブラリやパッケージ -- コンポーネント、統合レベル・テスト - - 実装するために使用するツール - -#### TASの多様性への対処方法 - -- TASやSUTのバージョン管理/構成管理を使用する - - お互いに適合するTASとSUTのバージョンや構成を提供する -- TASのパラメーター化を使用する - - TASがSUT構成に一致するように調整する - -# 4 導入のリスクとリスクヘッジ計画 - -## 4.1 テスト自動化アプローチの選択と導入/展開の計画 - -- パイロット - - 適切なプロジェクトの選定 - - パイロットの計画 - - パイロットの実行 - - パイロットの評価 -- 導入 - - 最初の対象プロジェクトの選定 - - 選択したプロジェクトへのTASの導入 - - 計画した期間の後のプロジェクトのTASを監視および評価 - - 他の組織/プロジェクトに展開 - -### 4.1.1 パイロットプロジェクト - -ツールの実装はパイロットプロジェクトから始まる - -#### 目的 - -TASを使用して意図したメリットを実現できることを確認する - -- TASに関する理解を深める -- TASが既存のプロセス、手順、ツールにどのように適合するかを確認する - - 変更が必要になる点を特定する - - 既存のプロセス/手順に適合するようにTASを変更することが優先される - - 既存のプロセス/手順をTASをサポートするように変更する - - プロセス自体を改善するべきである -- 自動化のためのインターフェースを設計する - - テスト担当者のニーズに一致させる -- 構成管理や変更管理との統合を含むTASやテストのアセットの使用、管理、格納、保守の標準的な方法を決める - - ファイルやテスト成果物の命名規約の決定 - - テストスイートのライブラリの作成と部品の定義 - など -- テスト自動化を監視するためのメトリクスや測定手法を選定する - - 使用性、保守性、拡張性など -- 期待するメリットが妥当なコストで実現可能かどうか - - TASを使ってみた後で期待を見直すこともある -- どのスキルが必要か、充足・不足しているのか - -#### プロジェクトの選定 - -- 重要なプロジェクトを選ばない - - TASの導入遅延が大きな影響を与える - - TASの初期導入には時間がかかる -- 単純なプロジェクトを選ばない - - 単純でないプロジェクトで成功するとは限らない - - 導入に必要な情報もあまり得られない -- 選定プロセスに必要なステークホルダーを関与させる - - 組織の他のプロジェクトの適切な基準となるべきである - - SUTには自動化の必要がある代表的なGUIコンポーネントを含むべきである - -#### 計画 - -- 通常の開発プロジェクトとして扱う - - 計画の作成 - - 予算・リソースの確保 - - 進捗の報告 - - マイルストーンの定義 - など -- 導入に携わる人員が導入作業を十分に行えるようにする - - 他のプロジェクトで作業のリソースが求められる - - 共有リソースに関するマネジメント層の関与は重要である - - すべての時間を導入に充てられないことが多い -- 社内開発のTASの場合 - - その開発担当者を導入作業に関与させる必要がある - -#### 実行 - -- TASが期待どおりの機能を提供したか - - ベンダーが述べたとおりであったか - - 異なる場合 - - できる限り早く対処する必要がある -- 社内開発のTASの場合 - - その開発担当者が不足している機能を提供し、導入を支援する -- TASと既存のプロセスはうまく連携できているか - - 異なる場合 - - 連携させる必要がある - -#### 評価 - -- 評価にはすべてのステークホルダーを関与させる - -### 4.1.2 導入 - -パイロットが成功した場合、他の部署/組織に導入する。 - -#### 段階的に展開する - -- 新規ユーザーのサポートは一斉にではなく波状的に発生する - - TASの使用を段階的に増やすことができる -- ボトルネックの可能性を特定し、実際の問題が生じる前に対処できる -- ライセンスは必要に応じて追加できる - -#### TASの使用に適したプロセスの適合と改善を行う - -- 異なるユーザーがTASを使用する場合、異なるプロセスがTASに関与する -- プロセスをTASに合わせて調整したり、TASをプロセスに合わせて変更したりする - -#### 新規ユーザーに対し、トレーニングやコーチング/メンタリングを行う - -- 新しいTASを使用するためのトレーニングやコーチングが必要になる -- これらは確実に行われるようにする -- トレーニング/ワークショップは、ユーザーが実際にTASを使用する前に提供する - -#### 利用ガイドラインを定義する - -- TASの使用に関する、ガイドライン/チェックリスト/FAQ を作成する -- サポートにあたっての質問を大幅に減らすことができる - -#### 実際の使用状況に関する情報収集の方法を実装する - -- TASの使用状況について自動的に収集する方法を確立する - - TASのどの部分(特定の機能)が使用されているか -- TASの使用状況が監視しやすくなる - -#### TASの使用、メリット、コストを監視する - -- 一定期間TASの使用状況を監視することで、TASが実際に使用されているかどうかがわかる -- ビジネスケースの再計算にも使用できる - - どのくらいの時間を節約できたか - - どのくらいの問題を防げたか - など -- TASのテストチームと開発チームを支援する - -#### すべてのチームから、得られた教訓を集める - -- TASを使用した各チームと評価/振り返りミーティングを行う - - 得られた教訓を特定できる -- TASの使用法を改善するために、情報提供が重要であり、その必要性を理解できる - -#### 改善点を特定し、実装する - -- フィードバックとTASの監視に基づき、改善のステップを特定して実装する - - ステークホルダーに明確に伝達する - -### 4.1.3 ソフトウェアライフサイクル内でのTASの導入 - -- SUTの開発フェーズに大きく依存する - - プロジェクトの開始時 - - コードフリーズやスプリント終了時などのマイルストーン到達時 -- テストや修正を伴う導入作業には時間と労力がかかるためである -- TASが動作しないために事によるリスクを軽減する -- 以下の場合、SUTの開発フェーズとは別に導入を行うことになる - - TASに修正が必要な重要な問題がある - - TASが実行されている環境のコンポーネントを置き換える必要がある - -## 4.2 リスクアセスメントと軽減戦略 - -### 一般的に見られる技術的な問題 - -- 過度な抽象化 - - 実際に何が起きているのかがわかりにくくなる - - キーワード駆動など -- データ駆動 - - データテーブルが大きすぎる - - 複雑すぎる - - 扱いにくい -- TASが依存しているコンポーネントがSUTのすべての対象環境で利用できるとは限らない - - オペレーティングシステムライブラリなどの - -### 一般的に見られる導入プロジェクトのリスク - -- 要員の問題 - - コードベースを保守する適切な人員を確保するのが難しい -- 新たな SU 機能によってTASが正常に動作しなくなる -- 自動化の実現に遅れが生じる -- SUTの変更によってTASのアップデートに遅れが生じる -- TASで追跡が必要なオブジェクトをキャプチャできない - -### TASプロジェクトで考えられる失敗する場面 - -- 異なる環境への移行 -- 対象環境への導入 -- 開発からの新しいデリバリー - -### リスク軽減戦略 - -- 前提 - - TASにはソフトウェアライフサイクルがある -- 留意すべき点 - - バージョンコントロールを行う - - フィーチャーを文書化する - - 文書化された明確で使いやすい導入手順が必要である - - バージョンに依存する - -#### 初期導入 - -- 確認すべき点 - - 環境でTASが動作する - - 予期せぬ変更の影響を受けない - - テストケースを更新・管理できる -- TASとそのインフラストラクチャの両方を保守する - -##### 基本ステップ - -- TAS用のインフラストラクチャの定義 -- TAS用のインフラストラクチャの構築 -- TASおよびインフラストラクチャの保守手順の作成 -- TASが実行するテストスイートの保守手順の作成 - -##### リスク - -- テストスイートの合計実行時間がテストサイクルで計画した実行時間よりも長い - - テストスイートを実行する十分な時間を確保する -- テスト環境のインストールや構成に関する問題が存在する - - 必要な事前条件を設定する効率的な方法が必要である - - データベースのセットアップ - - 初回ロード - - サービスの起動/停止 - など - -#### 保守 - -- 変更点を評価する - - 新しいバージョン - - 古いバージョン -- TASをテストする - - 新機能 - - 回帰 - - 更新したTASでテストスイートが実行できる - - レポートが送信できる -- テストスイートを適合させる必要性を確認する - - 新しいバージョンのTAS -- 更新を環境に適用する - -##### リスクと対応する軽減活動 - -- テストスイートの変更が必要 - - テストスイートに必要な変更を行う - - TASに導入する前にテストする -- テストで使われているスタブ、ドライバ、インターフェースに変更が必要: - - テストハーネスに必要な変更を行い、TASに導入する前にテストする -- インフラストラクチャに変更が必要 - - 変更が必要なインフラストラクチャコ ンポーネントを評価し、変更を行い、更新したTASを使用してテストする -- 欠陥や性能の問題がある - - リスクとメリットの分析を行う - - TASの更新が不可能になる場合は、更新を行わない - - 次のバージョンのTASまで待機する - - 無視できる程度なら、TASを更新してもよい - - 既知の問題を記載したリリースノートを作成する - - テスト自動化エンジニアおよびステークホルダーに通知する - - いつ問題が修正されるか見積るようにする - -## 4.3 テスト自動化の保守 - -- 保守は重要である -- 単純なことではない -- 要件 - - 部品化が可能である - - 拡張性がある - - わかりやすい - - 信頼性が高い - - テスト可能である - - 改善し続ける -- 動作の信頼性と安全性を高める - - テスト対象となる新しいタイプのシステムに適応させる - - 新しいソフトウェア環境をサポートする - - 新しい法律や規制に準拠させる -- 寿命や性能も最適化する - -### 4.3.1 保守の種類 - -運用中に、システムの変更、移行、廃止によって発生する。 - -#### カテゴリ - -- 予防保守 - - TASにより多くのテストタイプをサポートする - - 複数のインターフェースでのテストをサポートする - - 複数のバージョンのSUTでのテストをサポートする - - 新しいSUTでテスト自動化をサポートする -- 修正保守 - - TASの故障を修正する - - 定期的な保守テストを行う - - リスクを軽減する -- 完成度を高めるための保守 - - 最適化される - - 非機能的な問題が修正される - - 性能、使用性、 堅牢性、信頼性について対処する -- 適応保守 - - 市場に新しいソフトウェアシステムを投入する - - オペレーティングシステム - - データベースマネージャー - - Webブラウザ - など - - 準拠しなければならない - - 新しい法律 - - 規制 - - 業界固有の要件 - - 監査要件 - - 統合ツールが更新されて新しいバージョンが作成される - - ツールの統合エンドポイントを保守して機能を保つ - -### 4.3.2 スコープとアプローチ - -TASのすべてのレイヤーおよびコンポーネントに影響を及ぼす可能性のあるプロセスである - -- 範囲の決定要因 - - TASの規模と複雑度 - - 変更の規模 - - 変更のリスク -- 影響度分析が必須である - - 変更によってシステムにどのような影響が及ぶか -- 機能を確実に継続させる - - 段階的に変更を導入する - - 各段階でテストする - - 仕様や文書が古いと、TASの保守が困難になる - -#### 保守の手法 - -成功要因は時間効率である。 - -- 文書化する - - 導入手順 - - 使用方法 - - サードパーティへの依存性、欠点、既知の問題 -- 部品化する - - コンポーネントを簡単に交換できる -- 移行可能な環境で実行する - - TAS、コンポーネント -- TAF自体からテストスクリプトを分離する -- 開発環境から分離した状態でTASを実行する - - 変更によってテスト環境が悪影響を受けないようにする -- 構成管理の対象とする - - 環境、テストスイート、テストウェア - -##### サードパーティコンポーネントやその他のライブラリの保守 - -- コンポーネントを使用することは非常に多い - - ライブラリ(UI自動化ライブラリなど)に依存している場合もある - - コンポーネントは、すべて文書化し、構成管理の対象とする -- 外部コンポーネントの変更や修正が必要になった場合の計画が必要である - - TASの保守責任者は、連絡先や問題の報告先を知っておく -- コンポーネントを使用するライセンスについては文書化する - - 変更可能か、どの程度変更できるか -- コンポーネントの更新や新バージョンについての情報を取得する - - 最新の状態に保つことは、長期的な投資に見合った予防措置である - -##### 命名規約やその他の規約 - -- 命名規約やその他の規約を導入するメリットは単純である - - 読みやすく、わかりやすく、変更や保守を簡単にする - - 保守プロセスにかかる時間を短縮できる - - 回帰や誤った修正が発生するリスクも最低限にとどめられる - - 発生した場合は容易に取り除くことができる -- 新しい人員がテスト自動化プロジェクトに参画しやすくなる - - 命名規約は名前を定義する - - 変数 - - ファイル - - テストシナリオ - - キーワード - - キーワードパラメーター - - その他の規約 - - テスト実行の前提条件や事後処理 - - テストデータの内容 - - テスト環境 - - テスト実行のステータス - - 実行結果記録 - - レポート -- 開始時にすべて同意され、文書化する - -##### 文書化 - -- 十分な最新の文書が必要となる - - 2つの問題がある - - 文書を作成する - - 文書を保守する -- 自動または半自動で文書化することができる - - テストツールのコード設計書 -- 誰かが文書化する必要がある - - 設計、コンポーネント、サードパーティ製のコンポーネント - - 統合、依存性、導入手順 -- 開発プロセスの一部に文書化を含める - - 文書化されるまでは、タスクが完了しない - -##### トレーニング教材 - -- 文書が十分記述されている場合、ベースとして使用できる -- 内容 - - 機能仕様 - - 設計 - - アーキテクチャ - - 導入および保守 - - TASの使用方法(ユーザーマニュアル) - - 実例や練習問題 - - 使い方に関するヒント -- 見直し - - TASの講師となるチームメンバーが担当する - - SUTのイテレーションの終盤(スプリントの終了時など)で行われる - -# 5 テスト自動化のレポートとメトリクス - -## 5.1 TASメトリクスの選択 - -- テストマネージャーが選択する - -### TASメトリクスの分類 - -- 外部メトリクス - - 他の作業に対するTASの影響を測定する - - とりわけテスト活動 -- 内部メトリクス - - 目的達成におけるTASの有効性および効率性を測定する - - 変更の影響を監視する - -### 測定後のTASメトリクス - -- 外部メトリクス - - 自動化のメリット - - 工数 - - 自動テストを構築する工数 - - 自動テストで検出された故障を分析する工数 - - 自動テストを保守する工数 - - テスト - - 故障と欠陥の比 - - 自動テストの実行時間 - - 自動テストケースの数 - - 成功結果および失敗結果の数 - - 誤った失敗結果および誤った成功結果の数 - - コードカバレッジ -- 内部メトリクス - - ツールスクリプトのメトリクス - - 自動テストコードの欠陥密度 - - TASコンポーネントのスピードと効率性 - -#### 自動化のメリット - -- メリットを測定し記録することはとりわけ重要である - - コストは目に見えやすいからである - - 一定期間に関与した人員の数 - - 達成できたメリットはイメージできない -- メリットの測定 - - TASの目的によって異なる -- メリットの例 - - 時間や工数の節約 - - 実行するテストの数の増加 - - カバレッジの広さや深さ - - 実行の頻度 - - 再実行性の増加 - - リソースの効率的な活用 - - ヒューマンエラーの削減 - -##### メリットの測定項目 - -- 手動テスト工数を節約できた時間 -- 回帰テストの実行時間の削減 -- 実現できたテスト実行の追加サイクル数 -- 実行された追加テストの数や割合 -- テストケース全体に対する自動テストケースの比率 - - 自動テストケースと手動テストケースの比較は容易ではない -- カバレッジの増加 - - 要件 - - 機能 - - 構造 -- TASによって早期に発見できた欠陥の数 - - 欠陥の早期発見による平均的な利益がわかる場合 - - これを「計算」して予防されたコストの合計を導き出すことができる -- TASによって発見できた欠陥のうち、手動テストでは見つからなかったと思われるものの数 - - 信頼性の欠陥など - -##### 間接的なメリット - -- 手動テストの工数が節約できる -- その他の種類のテストに充てることができる - - 探索的テストなど -- 追加テストで欠陥が見つかる -- TASのメリットと見なす - -#### 自動テストを構築する工数 - -- 主なコストの1つである -- 手動で実行するコストよりも高くなる -- 利用を拡大する上で障害となる -- 実装コストはテストの内容に依存する -- その他の要素にも左右される - - スクリプティングアプローチ - - テストツールの習熟度 - - 環境 - - テスト自動化エンジニアのスキルレベル -- 構築コストの計算 - - 平均構築時間が使われる - - 特定のテストセットの平均コストを考慮することにより、さらに精度を上げられる - - 同じ機能を対象としたテスト - - あるテストレベルのテスト - など - - 手動実行に必要な工数の係数 - - 同等の手動テスト工数 - - EMTE(Equivalent Manual Test Effort) - -#### SUTの故障を分析する工数 - -- 手動実行時より自動テスト実行で検出された故障の分析は大幅に複雑になる - - 手動実行時は故障に至るまでの事象を分析者が認識しているためである - - レポートレベルによって緩和できる -- 失敗したテストケースあたりの平均、EMTEの係数として表現できる - - EMTEの係数は、自動テストの複雑度や実行時間が大きく異なる場合に特に適している -- 記録 - - 故障の分析において重要な役割を果たす - - 十分な情報を提供すべきである - -##### 重要な記録機能 - -- SUTの記録とTASの記録は同期しているべきである -- TASは期待される振る舞いと実際の振る舞いを記録すべきである -- TASは実行されるアクションを記録すべきである -- SUTは実行されるすべてのアクションを記録すべきである - - アクションが手動テスト結果でも、自動テスト結果でも構わない - - 内部エラーはすべて記録する - - クラッシュダンプやスタックトレースも利用できるようにする - -#### 自動テストを保守する工数 - -- 非常に大きくなる可能性がある - - TASによって実現できるメリットを上回ってしまうことがある -- 多くの自動化作業が失敗する原因となる - - 保守工数を削減する必要がある - - 保守工数の監視が重要になる -- 保守工数の測定値 - - 新しいリリースごとに保守が必要になる自動テストの合計 - - 更新された自動テストごとの平均または EMTE の係数 -- 関連メトリクス - - 保守作業が必要なテストの数や比率 -- 保守工数がわかる場合 - - 機能の実装や欠陥の修正の是非を判断する際に重要なメトリクスとなる - - SUTの変更と合わせて考慮する - -#### 故障と欠陥の比 - -- 多くの自動テストがソフトウェアの1つの欠陥のために失敗する -- 同じ欠陥を複数のテストで検出しても無駄になる -- 失敗した各テストを分析する工数が多くなる -- ある欠陥が原因で失敗した自動テストの数を測定することで、問題の発生箇所を明らかにできる -- 自動テストの設計と実行する自動テストの選択によって解決できる - -#### 自動テストの実行時間 - -- 判断しやすいメトリクスの1つである -- 最初の段階では重要でないこともある -- 数が増えるにつれて重要なメトリクスになる - -#### 自動テストケースの数 - -- 進捗を示すために使用できる -- 数だけでは多くの情報を明らかにできない - - テストのカバレッジが増加したことを示さない - -#### 成功結果および失敗結果の数 - -- 一般的なメトリクスである -- 失敗を分析する - - SUTの欠陥 - - 環境やTAS自体の問題などの外部の問題 - -#### 誤った失敗結果および誤った成功結果の数 - -- 失敗の分析にはかなりの時間がかかる -- 時間がかかるのは、問題がSUTではなく TASまたはテストケースにある場合である。\ - -##### 誤った失敗 - -- 誤警告の数を低く抑える - - TASの信頼性が低下する -- 発生要因 - - テストコードの欠陥 - - SUTが不安定で予想できない振る舞い - - タイムアウトなど - - テストフックの干渉 - -##### 誤った成功 - -- さらに危険になる -- 故障を特定できず、成功という結果になる -- 欠陥候補を検知できなかった -- 発生要因 - - 結果の検証が適切に行われなかった場合 - - 無効なテストオラクルが使用された場合 - - テストケースが誤った結果を期待していた場合 - -#### コードカバレッジ - -- 有用な情報を得ることができる -- ハイレベルでも測定できる - - 回帰テストスイートのコードカバレッジなど -- 十分であることを示す絶対的な比率は存在しない -- 100% になることはほぼない -- 十分であるほどリスクを軽減できる - - 大きいほどよいというのは一般的な共通認識である -- SUTの活動を示す可能性もある - - 低下した場合、SUTへの機能時に対応するテストケースが追加されていない - -#### ツールスクリプトのメトリクス - -- 使用できるメトリクスは多数ある -- SUTのメトリクスと同様である - - コードの行数(LOC)やサイクロマティック複雑度 - - 肥大したスクリプトや複雑なスクリプトを検知する - - 再設計が必要な可能性を示す - - コメントと実行ステートメントの比 - - スクリプトの文書化や注釈の程度を示す - - スクリプト標準への準拠違反の数 - - どの程度標準に準拠しているかを示す - -#### 自動テストコードの欠陥密度 - -- ソフトウェアであり欠陥を含む -- SUTのコードより重要度が低いとは限らない -- 優れたコーディング慣習やコーディング標準を適用する -- コードの欠陥密度などのメトリクスで監視する - - 構成管理システムのサポートにより収集は容易になる - -#### TASコンポーネントのスピードと効率性 - -- SUT が同じ経過時間で同じ機能を実行できない場合、調査が必要である -- 許容範囲外のシステムの性能のばらつきを示している - - 負荷が増加するとさらに悪化する可能性がある -- 性能が重要な場合は、性能を妨げないようTASを設計する - -#### 傾向メトリクス - -- 傾向(測定値の経時変化)が重要である - - 特定の時間の測定値よりも重要になりえる -- 例 - - 平均保守コストが増加している場合、原因を判断し、改善できる -- 測定コストはできる限り低く抑える - - 収集とレポートを自動化する - -## 5.2 測定の実施 - -- 使用状況に関する情報を記録する -- 抽象化と構造化されたテストウェアを組み合せている場合 - - 基になるテストウェアに対して行われた拡張をすべてのテストスクリプトで活用できる -- 例 - - テスト実行の開始時間と終了時間を記録する拡張を、すべてのテストに適切に適用できる - -### 測定とレポート生成をサポートする自動化の機能 - -多くのテストツールのスクリプト言語は、個々のテストや一連のテスト、テストスイート全体の実行前、実行中、実 行後に情報を記録する機能によって、測定とレポートをサポートしている。 - -傾向(テスト成功率の変化など)を明らかにできるように、一連のテスト実行のそれぞれに対するレポートは、前の テスト実行結果を考慮した分析機能を備える必要がある。 - -- テストを自動化するには、テスト実行とテスト検証の両方を自動化する -- テスト検証は、テスト結果の特定の要素と事前に定義された期待結果を比べる - - 比較はテストツールで行う - - 比較の結果としてレポートされる情報のレベルを考慮する - - テストのステータスを正確に判断する - - 成功、失敗など - - ステータスが失敗の場合 - - 原因についての詳しい情報が必要になる - - スクリーンショットなど -- テストの実行結果と期待結果で予測される違いが簡単に判別されるとは限らない - - 予測される違い(日付や時 間など)を無視しする - - 予測されない違いを定義するには、ツールのサポートが大いに役立つ - -### サードパーティツールとの統合 - -- 例 - - スプレッドシート - - XML - - 文書 - - データベース - - レポートツール - など -- サードパーティツールに適切な形式で情報を提供する - - トレーサビリティマトリクス更新などの追跡やレポート -- 既存のテストツールの機能によって実現できる - - レポート用にフォーマットをエクスポート -- 他のプログラムと互換性のある形式で出力できるようにレポートをカスタマイズする - - Excel の「.xls」 - - Word の「.doc」 - - Web の「.html」 - など - -### 結果の視覚化 - -- 図を使って視覚化する - - ダッシュボード、図、グラフなど -- 色を使って問題を示す - - 信号機の色で進捗を示す -- マネジメントには、テスト結果を一目で確認できることが求められる - - 情報が必要な場合は、詳細を確認できる - -## 5.3 TASおよびSUTの結果記録 - -- 問題候補を分析する際に使われる - -### TASの結果記録作業 - -- 現在実行中のテストケース -- 開始時間および終了時間 -- テストケース実行のステータス - - 失敗はログファイルで容易に特定できる - - フレームワーク自体にもこの情報がある - - ダッシュボードを通して報告される - - 成功、失敗、TAS エラーのいずれか - - TASエラーは、問題がSUTではない場合に使用される -- テスト結果記録のハイレベルな詳細 - - タイミング情報 - - 重要な手順の結果記録 - など - - SUTについての動的な情報 - - メモリリークなど - - 実行結果や動的測定の失敗は、インシデントが検知された際に実行されていたテストケースととも に記録する。 -- テストケースの実行回数 - - 信頼性テスト/ストレステストで、多数のサイクルが実施される場合 -- 乱数/選択値 - - テストケースにランダムな部分がある場合 - - ランダムパラメーター - - ステートマシンテストのランダムステップ - など -- すべてのアクション - - テストの同じステップを同じタイミングで正確に再現する - - 追加情報を得る際に便利である - - SUT自体に記録することもできる - - 顧客がシナリオを実行する - - 開発チームがトラブルシューティングを行う際に再生する -- 視覚情報のキャプチャ - - 故障の解析の際に使用できる - - テスト実行の際のスクリーンショットなど -- 問題の分析に必要なすべての情報 -- テストの継続に関連する情報 -- 安全な場所に保存する - - クラッシュダンプ - - スタックトレース - - ログファイル -- 記録された情報の種類を区別する - - 色分けする - - エラーは赤 - - 進捗情報は緑 - など - -### SUTの結果記録作業 - -- 問題の分析に必要なすべての情報 - - 日付とタイムスタンプ - - 問題の発生元の位置 - - エラーメッセージ - など -- すべてのユーザー操作を記録する - - ユーザーインターフェース - - ネットワークインターフェース - など - - 顧客が特定した問題を適切に分析できる - - 開発側で問題の再現ができる -- 構成情報を記録する - - 各ソフトウェア/ファームウェアのバージョン - - SUTの構成 - - オペレーティングシステムの構成 - など -- すべて簡単に検索できる -- TAS・SUTのログファイルで特定した問題を他方のログファイルで簡単に特定できる -- タイムスタンプで記録を同期させる - - エラー報告時に関連付けやすい - -## 5.4 テスト自動化のレポート - -- 結果記録だけで全体像を適切に把握することはできない -- 実行されるたびに、簡潔なレポートを作成して公開する - - 再利用可能なレポートジェネレータコンポーネントを使用できる - -### レポートの内容 - -- サマリー - - 実行結果の概要 - - テスト対象のシステム - - テストを実行した環境 - - 各ステークホルダーに提供する -- 各テストの失敗理由 -- テストの実行履歴 - - 責任者 - - テストの作成者または最終更新者 -- 責任者 - - 失敗の原因を調査する - - 関連する問題を報告する - - 問題の修正をフォローアップする - - 正しく修正されたことを確認する --TAFコンポーネントの故障を診断する - -### レポートの公開 - -- 実行結果に興味を持つ者全員に公開される -- 別のツールへのアップロード - - Webサイト - - メーリングリストへの送信 - - テストマネジメントツール - など -- レポートの履歴を保管する - - 統計を集計する - - 頻繁に起こる回帰 - - SUTの問題がある部分を特定する - -# 6 手動テストから自動化環境への移行 - -## 6.1 自動化の移行条件 - -- 手動テストを実施してきた -- 移行の決断 - - 手動テストの状況を評価する - - 効果的なアプローチを判断する -- 既存の手動テストの構造の適合性 - - 適している場合 - - 自動化への移行が容易である - - 適さない場合 - - すべてのテストの再作成が必要になることもある - - 関連する内容を抽出し、再利用してもよい - - 入力値、期待結果、ナビゲーションパス -- 自動化の対象 - - すべてを自動化できるとは限らない - - すべてを自動化するべきでもない -- 最初のテストのイテレーションは手動となりえる - - 既存の手動テストを自動化する初回の変換 - - 新しい手動テストを自動化するために行う移行 -- 効果的に実行できるテスト - - 信頼性テスト - - ストレステスト - - 性能テスト -- ユーザーインターフェースのないアプリケーションやシステムのテスト - - ソフトウェアのインターフェースを通して統合レベルでテストを行える - - 例:システムのメッセージキューにメッセージを直接挿入できる - - 手動でコマンドを実行できるが、現実的ではない - - 早い段階でテストを開始できる - - 欠陥を早期に検出できる - -### 合目的性(適応性と実現性)の条件 - -自動テストと手動テストのどちらを作成するか。 - -- 使用頻度 -- 自動化の複雑度 -- ツールの適合性とサポート -- テストプロセスの成熟性 -- ソフトウェアプロダクトライフサイクルの段階における自動化の合目的性 -- 自動化環境の持続可能性 -- SUTの操作特性 - -#### 使用頻度 - -- どの程度の頻度で実行するか -- アプリケーションのリリースが頻繁である - - 対応するテストサイクルが多い - - メジャー・マイナーリリースサイクルの一部として定期的に実行されるテスト -- 機能テスト - - 以降のリリースで回帰テストの一部として使用できる -- 回帰テスト - - 投資収益率(ROI)は高い - - 既存のコードベースのリスク軽減になる -- 1年に1度実行され、1年以内にSUTが変更される場合 - - 効果的ではない - - 手動でテストを行う方が望ましい - -#### 自動化の複雑度 - -‐ 複雑なシステム - - メリットが非常に大きくなりやすい - - 複雑な手順を繰り返すタスクを行わずに済む - - 手間や時間がかかり、エラーも起きやすい - - 自動化が困難だったり、自動化のコスト効率がよくない -- 既存の自動テストと互換性のないSUT -- 大量のプログラムコードとAPI呼び出しを開発する -- 外部インターフェース・独自システムとの連携 -- 使用性テスト - -#### ツールの適合性とサポート - -- さまざまな開発プラットフォーム - - どのテストツールが利用できるか - - どの程度サポートされているか -- テストツールの提供種類 - - 商用ベンダー - - 有償サポートを提供する - - 実装を支援できる専門家のサポート環境が存在する - - オープンソースツール - - オンラインフォーラムなどのサポートを提供している - - そこから情報を得たり、そこに質問を投稿したりする - - 社内で開発されたテストツール - - 既存のスタッフがサポートを提供する -- 適合性の問題を過小評価すべきではない - - 壊滅的な結果となることがある - - 大半が自動化できても、重要なテストが自動化できない場合も - -#### テストプロセスの成熟性 - -- 自動化の効果的な実装プロセス - - 構造化する - - 統制する - - 繰り返し可能にする -- 既存のテストプロセス - - 自動化コードや関連するコンポーネントの管理が必要となる - - 開発プロセス全体へと影響を及ぼす - -#### ソフトウェアプロダクトライフサイクルの段階における自動化の合目的性 - -- SUTにはソフトウェア開発ライフサイクルが存在する - - 数年から数十年に及ぶ可能性がある -- システム開発が始まると、エンドユーザーのニーズを満たすために欠陥への対処や機能の追加が行われ、システムは変化し拡張される -- 初期段階 - - 変更が早すぎて実装が追いつかない - - 作業のやり直しが継続的に必要になる - - 効率的、効果的ではない -- シーケンシャル開発 - - コア機能を組み込んだタイミングで自動テストの実装を始める -- 最終段階 - - システムは廃棄される - - 新しく効率的な技術を使用して再設計される - - 終了が近いシステムの自動化は推奨しない -- 再設計 - - データ要素を定義した自動テスト環境は、新しいシステムでも有用である - - テストデータの再利用が可能である - - 自動化環境の記録に新しいアーキテクチャとの互換性を持たせる - -#### 環境の持続可能性 - -- 時間の経過とともにSUTに起こる変化へ柔軟に対応する - - 自動化の問題をすばやく診断して修正できる - - 自動化コンポーネントを容易に保守できる - - 自動化環境に簡単に新規のフィーチャーやサポートを追加できる -- gTAAの全般的な設計や実装として不可欠な部分である - -### SUTの操作特性(事前条件、セットアップ、安定性) - -- SUTの操作特性や視覚特性を識別する - - 効果的な自動テストを作成する際に役立つ -- 識別できない場合 - - UI操作にのみ依存する - - 保守性が低下する - -### ROI分析を支援する技術計画 - -- テストチームが得られるメリットの程度はさまざまである -- 効果的な自動テストの実装は多大な作業とコストを伴う -- 目的やメリット、成果について評価をする -- 計画を実現するため必要な作業を定義しする -- コストを判断する -- ROIを計算する - -#### 移行準備 - -- テスト自動化のテスト環境で利用できるツール -- テストデータとテストケースの正確性 -- テスト自動化作業の範囲 -- パラダイムシフトを起こすためのテストチームの教育 -- 役割と責任 -- 開発担当者とテスト自動化エンジニアの連携 -- 並行作業 -- テスト自動化のレポート - -#### テスト自動化のテスト環境で利用できるツール - -- 先行検証環境にインストールする -- 機能することを確認する - - サービスパックやリリースアップデートのダウンロード - - SUTをサポートするために必要かつ適切なインストール構成の選択(アドインを含む) - - 検証環境と自動化の開発環境でTASが正しく機能することの確認 - -#### テストデータとテストケースの正確性 - -- 確実に予測できる結果を出す - - 手動テストデータとテストケースが正確かつ完全である -- 自動テスト実行には以下が必要である - - 明示的な入力データ - - ナビゲーション - - 同期化 - - 検証 - -#### テスト自動化作業の範囲 - -- 自動化を早期に成功させる -- 限定された範囲から始める - - 技術的問題のフィードバックを得る - - その後の自動化タスクを容易にする -- パイロットロジェクト - - システム全体の相互運用性を代表するシステムの機能の 1 つの領域を対象とする - - 今後の時間の見積り - - スケジュールの調整 - - 特殊な技術を持つリソースが求められる領域の特定 -- 成功によりマネジメントからの支持も集まる -- 自動化するテストケースを適切に選択する - - 手間がかからず、高い付加価値を提供する - - 回帰テストやスモークテスト - - 頻度が高い - - 毎日実行されたりする - - 信頼性テスト - - 複数のステップで構成される - - 何度も繰り返し実行される - - 手動では明らかにしにくい - - 実装に手間がかかりづらい -- 自動化に注目を集める - - 手動テストの工数を節約する - - 重大な問題を特定する - - 今後の拡張への道を開く - - 工数や予算など -- 重要なテスト - - 最初から最大の価値が明らかである - - 優先度を高くする -- 技術的に難易度が高すぎるテスト - - 避けることが重要である - - 多大な工数がかかる割に、示すべき結果がほとんどない -- アプリケーションの大部分に見られる特徴を共有するテストを特定する - - 自動化の作業存続に必要となる - -#### パラダイムシフトを起こすためのテストチームの教育 - -- さまざまな背景を持つ人員を混在させる - - 特定のドメインの専門家である - - エンドユーザーコミュニティに所属している - - ビジネスアナリストとして関与している - - システムアーキテクチャを深く理解できる - - 優れたな技術スキルを持つ -- テストチームの構成を変える - - シフトするにつれ、役割は特化される - - 自動化の成功にとって不可欠である -- 早くからチームを教育する - - 不安や不必要な考えが生じる可能性を軽減する - - 自動化へのシフトに期待する - - 組織や技術の変化に参画する準備が整う - -#### 役割と責任 - -- 全員が参画できる -- 全員が同じ役割ではない -- ドメインの専門家 - - ドメインの専門性とテストスキルを持つ人員 - - 自動化環境を推進する - - 目標のテストカバレッジを実現する - - 適切なテストスクリプト - - 対応するテストデータを含む - - テストケースの実装 - - アプリケーションの機能を確認する - - レポートをレビューする - - テスト担当者 -- 技術的な専門家 - - プログラミングのスキルに強く、技術的背景を持つ人員 - - 設計や実装 - - 技術的な作業 - - 保守性の高いソフトウェアの設計 - - テスト自動化フレームワークやテストライブラリ - - 自動テスト環境の保守 - - 技術者・非技術者でも同様に使用できる環境とする - - 正常かつ効率的に運用されることを保証する - - 開発担当者の場合もある - -#### 開発担当者とテスト自動化エンジニアの連携 - -- 成功にはソフトウェア開発チームの関与も必要である -- 開発担当者とテスト担当者がより密接に連携して作業する - - 支援要員や技術情報を提供する - - 開発の手法やツールについて -- システム設計や開発コードの試験性 - - テスト自動化エンジニアが懸念を示す場合がある - - 設計やコードが標準に従っていない - - 見慣れないライブラリやオブジェクト、内製のものや極端に新しいものを使用している - - 例:開発担当者が選定された自動化ツールと適合性のないサードパーティ製 GUIコントロールを選ぶ -- プロジェクトマネジメントチームが必要な役割の種類と責任を明確に理解する - -#### 移行作業 - -- 移行前 - - 手動スクリプトの評価を行う - - 効率的、効果的なアプローチのため、再構築するか -- 移行時 - - 移行チームを編成する - - 既存の手動テストスクリプトを自動化する - - 手動スクリプトと同じことを検証する - - 自動化されたスクリプトが組み込まれる - - 手動スクリプトに代わる - -#### テスト自動化のレポート - -- TASの正しい運用を可視化する - - 報告されるアプリケーション固有の結果が正確かつ完全であると見なされるように -- レポート内容 - - 個々のスクリプトやスクリプト内の手順の合格/失敗のステータス - - テスト実行全体の統計 - - TASの全般的な性能 - など - -## 6.2 回帰を自動化する際に必要な手順の特定 - -- 自動化を使用する絶好の機会である -- 今日の機能テストが翌日の回帰テストになる -- 回帰テストのテストベッドは増加し続ける -- 従来の手動テストチームが利用できる時間とリソースを超えるのは時間の問題である - -### 準備する段階 - -- どのくらいの頻度でテストを実行するのか -- 個々のテストの実行時間、回帰テストスイートの実行時間はどのくらいか -- テスト間で機能の重複はないか -- テストでデータが共有されているか -- テストはお互いに依存しているか -- テスト実行の前にどのような事前条件が必要になるか -- テストのSUTのカバレッジは何 % か -- 現在のテストは失敗なく実行されるか -- 回帰テストに時間がかかりすぎた場合、何が起きるか - -#### テスト実行の頻度 - -- 頻繁に実行されるテストは、候補として最も適している -- 既に開発されており、SUTの既知の機能性をテストする -- 自動化によって実行時間を大幅に減らせる - -#### テスト実行の時間 - -- 実装する価値を評価する上で重要である -- 時間のかかるテストから自動化の実装を始める場合 - - 毎回のテストの実行が速く効率的になる - - 実行サイクルを増やせる - - SUTの品質に関するフィードバックの数と頻度が増加する - - 展開時のリスクが減る - -#### 機能の重複 - -- テストケース間に存在する機能の重複を見つけ、減らす - - 実行時間の効率が上がる - - 増えるにつれ、重要性が増す -- 自動化テストは新しい構造になる - - 再利用可能なコンポーネントと共有データリポジトリに依存する - - 既存の手動テストを分解して複数の小さな自動テストにする - - 手動テストを統合して大きな自動テストにする -- 手動テストには個々の評価とグループとしての評価が必要になる - - 効果的な変換の戦略を実現する - -#### データ共有 - -- 頻繁にデータが共有される - - テストが同じレコードのデータを使用して別のSUT機能を実行する - - 例: - - 社員が利用できる休暇時間を検証するテストケース「A」 - - 社員がキャリアアップのために受講できるコースを検証するテストケース「B」 - - 同じ社員を使用する -- 手動テスト - - 社員データは手動テストケースごとに複数回コピーされる - - その社員を使用して社員データを検証する -- 自動テスト - - 共有するデータを1 つのソースに格納し、そこからアクセスする - - 重複やエラーを防ぐ - -#### テストの相互依存性 - -- 1つのテストが他のテストに依存する場合がある -- 発生頻度が高い -- 例 - - 「注文ID」が作成される - - 以下を検証する - - 新しい注文がシステムに正しく表示される - - 注文の変更が可能である - - 注文の削除が成功する -- 「注文ID」の値をキャプチャし、 以降のテストで再利用する -- 設計により対処する - -#### テストの事前条件 - -- 条件 - - テストを行う正しいデータベースやテストデータセットの選択 - - パラメーターの初期値の設定 -- 設定せずに実行できない -- 設定は自動化できる -- ステップの漏れを防ぐ -- 信頼性があがる - - #### SUTのカバレッジ - -- SUTの機能が実行される -- カバレッジを広く、深く、テストを設計する -- コードカバレッジツールを使用して自動テストの実行を監視する - - テストの有効性の定量化を進める -- 時間経過によりテストが追加され、カバレッジが高まる -- テスト自体の価値を定量化する有効な手段である - -#### 実行可能なテスト - -- 変換前に、手動テストが正しく動作することを検証する - - テストの記述が適切でない - - 無効なデータを使用している - - 期限切れ・現在のSUTと同期していない - - SUTに欠陥がある -- 機能しない自動テストが作成された場合 - - 非生産的である - -#### 大規模な回帰テストセット - -- 巨大になりがち -- 夜間・週末で実行できないほどになる -- 同時実行 - - PCアプリケーションなど -- 部分実行 - - SUTが高価で入手しにくい - - 航空機や宇宙ロケットのシステム - - 並列化できない - - リスク分析によって決める - - 最近変更した部分 -- 長期実行 - - たとえば数週間 - - 最終的にセット全体が実行される - -## 6.3 新規のフィーチャーのテストを自動化する際に考慮する要素 - -- 新しい機能のテストケースが自動化しやすい -- 実装が完了・開始していない - - テスト実装に何が必要か説明できる -- 新規のフィーチャー導入 - - 対応するテストを開発する - - ドメインの専門知識を持つテスト設計者によるフィードバックを求める - - TASがフィーチャーのニーズを満たすかどうかを判断する -- TASの変更や追加 - - 既存部分を評価し、完全に文書化する - - 振る舞い(または性能)や既存のTASの機能に影響させない -- 別のクラスやオブジェクトなどで実装される - - テストウェアコンポーネントの更新や追加が必要になる -- 互換性を評価する - - 必要な場合、代替ソリューションを特定する - - 例:キーワード駆動アプローチを使用している場合 - - 追加キーワードの開発や既存のキーワードの変更・拡張が必要になる -- 新しい環境をサポートする - - 追加テストツールを評価する - - 例:既存のテストツールが HTML しかサポートしない -- 新しいテストの要件 - - 既存に影響を与える可能性がある - - 変更する前に自動テストを実行する - - 動作が変更されないか記録する -- 他のテストとの相互依存性のマッピングも含まれる -- 技術面での新しい変更点 - - 現在のテストウェアコンポーネントと既存のTASとの互換性を評価する - - テストツール、機能 ライブラリ、APIなど -- 既存の要件が変更された - - 検証するテストケースの更新作業をスケジュールに含める - - テストケースまでのトレーサビリティがある場合 - - どのテストケースを更新する必要があるかがわかる - - 全体計画の一部に含める -- TASがSUTのニーズを満たし続けるか - - 実装技術はまだ有効か - - 新しいアーキテクチャが必要か - - 現在の機能を拡張して行えるか -- 新機能が導入されるタイミング - - 新しく定義された機能がテスト可能であることを確認する機会 - - 設計フェーズの間にテストについても考慮する - - スクリプト言語やテスト自動化ツールで新機能を検証できる - - テストインターフェースの提供を計画する - -## 6.4 確認テストを自動化する際に考慮する要素 - -- コードを修正した後に実行される -- 再現するステップを実行し、欠陥がなくなっていることを検証する -- 以降のリリースで再発する可能性がある - - 構成管理に問題がある可能性を示す - - 自動化の候補となる -- 実行時間を削減できる -- 自動回帰テストベッドに追加、補完できる -- 機能スコープは狭い -- 実装はいつでも行える -- 自動欠陥確認テストの価値を保持される - - 標準の自動回帰スイートに組み込む - - 既存の自動テストに取り入れる -- 自動確認テストの追跡 - - 欠陥の解決に費やされたサイクルの時間や回数を追加報告できる -- 欠陥の修正の副作用として新しい欠陥が増えていないことを確認する - - 確認テストに加えて回帰テストも必要になる -- 回帰テストの適切なスコープを決定する - - 影響度分析が必要になる - -# 7 TASの検証 - -## 7.1 自動テスト環境のコンポーネントの検証 - -- 期待通りに動作していることを検証する - - 自動化を始める前などに行う -- 検証ステップは複数存在する - -### テストツールのインストール、セットアップ、設定およびカスタマイズ - -- 多数のコンポーネントで構成される -- それぞれが信頼性と再現性のある性能を確保する -- 中核 - - 実行可能なコンポーネント - - 対応する機能ライブラリ - - サポートデータ - - 設定ファイル -- 構成プロセス - - 自動インストールスクリプトを使用する - - 対応するフォルダに手動でファイルを配置する - など -- サービスパックやオプションのアドイン - - SUT環境との互換性を確保する -- セントラルリポジトリ - - 自動インストール・コピー - - 異なるSUTのテストを同じバージョンのTASや同じ構成のTASで実行できる - - TASのアップグレードを行える -- アップグレードするプロセス - - 標準開発ツールと同じにすべき - -### 合格と失敗が既知であるテストスクリプト - -- 合格するテストケースが失敗した場合 - - 早急に修正する必要がある -- 失敗するテストケースが合格した場合 - - 正しく機能していないコンポーネントを特定する -- 検証する - - ログファイル - - 性能メトリクス - - 検証するとともに、 - - 自動セットアップ - - 終了処理 -- タイプやレベルが異なるテストを実行する - - 機能テスト - - 性能テスト - - コンポーネントテスト - など -- フレーム ワークのレベルでも実行すべき - -### テスト環境のセットアップ / 終了処理における再実行性 - -- さまざまなシステムおよびサーバーで実装される -- 任意の環境からTASをロードおよびアンロードする -- 目に見える差異が発生しない場合、これがうまく実現できている -- コンポーネントの構成管理 - - 信頼できる形で構成を作成できるようになる - -### テスト環境およびコンポーネントの構成 - -- 文書化する -- SUT環境が変更された場合 - - 影響を受けたり、変更が必要になるか、知識を得られる - -### 内部および外部のシステム / インターフェースに対する接続性 - -- SUT環境にTASをインストールした場合 - - 一連のチェックや事前条件を管理する - - 内部・外部のシステムやインターフェースに接続する -- 自動化のための事前条件を確立する - - TASを正しくインストールおよび構成できる - -### 自動テストツールの干渉関係 - -- TASはSUTと密接に結合している - - 設計的に高いレベルの互換性を実現する - - GUIレベルの操作が関係する -- マイナスの効果がある - - 例 - - TASがSUT環境の中にある場合とない場合でSUTの動作が異なる - - 手動で使用する場合、SUTが異なる振る舞いを見せる - - 環境内のTASによって、またはSUTに対してTASを実行するときに、SUTの性能が影響を受ける - など - -#### 干渉のレベル・関係 - -- 外部インターフェースからSUTに接続する場合 - - 干渉のレベルは非常に低くなる - - 外部インターフェース - - 電気信号(物理スイッチの場合) - - USB信号(キーボードなど) - - 最も適切な形でエンドユーザーをシミュレートできる - - SUTのソフトウェアをテストの目的によって変更しない - - SUTの振る舞いやタイミングが影響を受けない - - 非常に複雑になりえる - - 例 - - 専用ハードウェアが必要になる - - ハードウェア記述言語が必要になる - - ソフトウェアのみ - - 典型的なアプローチではない - - 組込みソフトウェア製品 - - よく使われる -- GUIレベルでSUTと接続する場合 - - UIコマンドをインジェクションしてテストケースが必要とする情報を抽出できるように、SUT環境を変更する - - SUTの振る舞いは直接的に変更されない - - タイミングには影響がありる - - 結果的に振る舞いに影響しえる - - 干渉のレベルは前項目より高い - - 複雑さは低くなる - - 市販ソフトウェアツールを使える -- インターフェース(API)でSUTと接続する場合 - - ソフトウェアのテストインターフェース - - 既にソフトウェアが提供している既存のインターフェース - - 可用性が重要な部分である - - 干渉のレベルは非常に高くなる - - エンドユーザーに使用されないインターフェースを使用する場合がある - - 実際とは異なる状況でインターフェースが使われる場合がある - - 非常に簡単で安価である - - 潜在的なリスクを理解している限りにおいては、確実である -- 干渉のレベルが高い場合 - - 実世界では起こりえない故障がテストで起こる - - 信頼性が大幅に低下する - - 特定された故障を手動で再現させる - -### フレームワークコンポーネントテスト - -- 個々にテストし、検証する - - 機能テスト - - 非機能テスト - - 性能:フレームワークの性能低下の把握 - - 資源効率性:メモリリークなどの問題を示す可能性があるシステムリソースの使用状況 - - 使用性:フレームワークの内外のコンポーネントの相互運用性 - など -- 例 - - GUIシステムでオブジェクト検証を行うコンポーネント - - 幅広いオブジェクトのクラスに対してテストを行う必要がある。\ -- エラーログおよびレポート - - 自動化の状況とSUTの振る舞いについて正確な情報を提供する - -## 7.2 自動テストスイートの検証 - -- 完全性、一貫性、正しい振る舞いを確認する -- 常に自動テストスイートが動作していることを確認する - -### 検証手順 - -- 既知の合格と失敗があるテストスクリプトの実行 -- テストスイートの確認 -- フレームワークの新フィーチャーに着目した新しいテストの検証 -- テストの再実行性の考慮 -- 自動テストスイートに十分な検証ポイントが存在あることの確認 - -#### 既知の合格と失敗があるテストスクリプトの実行 - -- 合格するテストケースが失敗した場合 - - できる限り早急に修正する -- 失敗するテストスイートが合格した場合 - - テストケースを特定する - - ログファイルと性能データを正しく生成する - - セットアップ・終了処理を検証する -- タイプやレベルが異なるテストを実行する - - 機能テスト - - 性能テスト - - コンポーネントテスト - など - -#### テストスイートの確認 - -- 完全性 - - すべてのテストケースに期待結果、テストデータが存在する - - 正しいバージョンのフレームワークとSUTがある - -#### フレームワークの新フィーチャーに着目した新しいテストの検証 - -- TASの新フィーチャーを使用する場合 - - 細かく検証および監視を行う - - フィーチャーが正しく動作することを確認する - -#### テストの再実行性の考慮 - -- テストを繰り返して実行する場合 - - テストの結果/判定は常に同じになる -- 信頼性がない場合 - - アクティブな自動テストスイートから移動させる - - 個別に分析する - - 根本原因を調査する -- 何度も分析することになる -- 断続的な失敗 - - 問題を分析する - - テストケースの中にある場合 - - フレームワークにある場合 - - SUTの問題である場合 - - ログファイルを分析する - - テストケース、フレームワーク、SUTのもの - - 問題の根本原因を特定する - - デバッグをする -- 根本原因を見つけるため、支援が必要になる - - テストアナリスト - - ソフトウェア開発担当者 - - ドメインの専門家 - -#### 自動テストスイートやテストケースに十分な検証ポイントが存在することの確認 - -- 期待結果を実現していることを検証する -- 証拠を提供する - - 各テストケースの開始時・終了時の記録 - - 完了したテストケースのテスト実行ステータスの記録 - - 事後条件が実現されているかの検証 - など - -# 8 継続的な改善 - -## 8.1 テスト自動化の改善オプション - -- TASを改善する -- 継続的な保守作業以外にも多く存在する -- 効率性の向上 - - 手動による介入を削減する - - 使いやすさの向上 - - 機能の追加 - - テスト活動のサポートの向上 - など -- 最大の価値をどのようにもたらすか - -### 改善領域 - -- スクリプティング -- 検証 -- アーキテクチャ -- 事前および事後処理 -- 文書化 -- 支援ツール - -#### スクリプティング - -- スクリプティングアプローチ - - 単純な構造化アプローチ - - データ駆動アプローチ - - キーワード駆動アプローチ -- 新しい自動テストのために、現在のTASのスクリプティングアプローチを変更・向上させる -- 既存の自動テストがすべて更新される場合もある - - かなりの量の保守作業が発生する -- スクリプトの実装に着目する - -##### 自動テストを統合する作業の中で、自動テストケース/ステップ/手順の重複を評価する - -- 保守性を向上する - - 同じ操作手順を複数回実装しない - - 再利用できるように関数化し、ライブラリに追加する - - ライブラリ関数は、異なるテストケースで使用できるようにする - - 同一でなく似ている場合 - - パラメーター化が必要になる - -##### TASとSUTのエラー回復プロセスを確立する - -- TASでエラーが発生した場合 - - エラーから回復し、テストケースを継続する -- SUTでエラーが発生した場合 - - 必要な回復操作をする - - 再起動など - -##### スクリプト実行の待機(Wait)のメカニズムを評価し、最適なタイプが使用されるようにする - -1. ハードコードによる待機 - - 一定のミリ秒だけ待機する - - さまざまなテスト自動化の根本な問題となる -2. ポーリングによる動的な待機 - - 所定の状態変化や行われる操作を確認する - - より柔軟で効率的である - - 必要な時間だけ待機する - - テスト時間が無駄にならない - - プロセスに長い時間がかかる場合 - - ポーリング条件が true になるまで待機を続ける - - タイムアウトのメカニズムを含める - - 永久に待機を続ける -3. SUTのイベントメカニズムを監視する - - 他の2つよりも信頼性が高い - - テストスクリプトの言語でイベントの監視がサポートされている - - SUTからテストアプリケーションに対してイベントが発行される - - タイムアウトのメカ ニズムを含める - - 永久に待機を続ける - - ##### テストウェアをソフトウェアとして扱う - -- テストウェアの開発と保守 - - ソフトウェア開発の1形態である - - 優れたコーディング慣習を適用する - - コーディングガイドラインの使用 - - 静的解析 - - コードレビュー - など -- テストウェアの特定部分の開発を、ソフトウェア開発担当者が行う - -##### 既存のスクリプトの改訂/削除について評価する - -- よく失敗する、保守コストが高いなど、問題を起こす - - 再設計する -- 付加価値がなくなった - - 削除する - -#### テスト実行 - -- 夜間に終わらないことは例外的ではない -- 時間がかかる場合 - - 並行 - - 常に可能とは限らない - - 高価なシステムが使われている - - 分割 - - 定義した時間に実行する -- カバレッジを分析する - - 重複が明らかにする - - 重複を削除する - - 実行時間を削減できる - - 効率性が上昇する - -#### 検証 - -- 新しい検証機能を作成する前に、すべての自動テストで使用でき一連の検証ができる標準的な手法を採用する -- 複数のテストをまたいだ検証アクションの再実装を避けることができる -- 検証手法が同一でなく似て いる場合は、パラメーター化することで複数の種類のオブジェクトで機能を使用できる - -#### アーキテクチャ - -- SUTの試験性を向上させる -- アーキテクチャを変更する - - SUTのアーキテクチャ - - 自動化のアーキテクチャ -- 大きな改善となる - - 大幅な投資が必要になる -- 例 - - テスト用のAPIを提供するためにSUTを変更する場合、TASも適切にリファクタリングされる -- 初期段階で考慮する - - 後工程で追加すると高価になる - -#### 事前および事後処理 - -- 標準のセットアップおよび削除タスクを提供する -- 事前処理(セットアップ)および事後処理(削除)と呼ばれる -- 自動テストごとにタスクを繰り返し実装する手間を省く -- 工数を削減できる - - 保守 - - 実装 - -#### 文書化 - -- スクリプトが何をするか -- どのように使うべきかなど -- あらゆる形態の文書が対象 - - TASのユーザー文書 - - TASが生成するレポートやログ - など - -#### TASのフィーチャー - -- フィーチャー - - 詳細レポート - - ログ - - 他のシステムとの統合 - など -- 使用される場合 - - 追加する -- 使用しない場合 - - 複雑さを増す - - 信頼性と保守性が低下する - - #### TASの更新とアップグレード - -- テストケースで使用できる新機能が提供される -- 故障が修正される -- リスク - - 既存のテストケースに悪影響が生じる -- 展開する前 - - 新しいバージョンのテストツールをテストする - - 代表的なサンプルのテストを実行する - - 異なるアプリケーション - - 異なるテストタイプ - - 異なる環境 - -## 8.2 テスト自動化改善の実装計画 - -- 変更には慎重な計画と調査が要求される -- 堅牢なTASの作成には多大な作業が必要となる -- 変更は信頼性や性能に幅広く影響する - -### テスト環境のコンポーネントの変更点を特定する - -- どのような変更や改善を行う必要があるか - - テストソフトウェア - - カスタマイズした機能ライブラリ - - OS -- TASの動作方法に影響する -- 確実・効率的に動作し続けることを目標とする -- 変更は段階的に行う - - 限定的に実行する - - TASへの影響を計測する - - 悪影響がないことを確認する - - 変更を完全に実装する -- 完全な回帰実行 - - 最終段階となる - - エラーが発見される - - 根本原因を特定する - -### TASのコア機能ライブラリの効率性と有効性を改善する - -- 新しい技法が発見される - - 機能のコードの最適化 - - 新しいオペレーティングシステムライブラリの使用 - など -- コア機能ライブラリに組み込む - -### 同じ制御タイプで動作する複数の機能を統合の対象にする - -- GUIコントロールに関する情報 - - 表示/非表示 - - 有効/無効 - - サイズ - - データ - など -- 情報を利用する - - ドロップダウンリストから項目を選択する - - フィールドにデータを入力する - - フィールドから値を読み取る -- コントロールに対して操作を行い、この情報を取り出す -- 極端に細分化されたものも、本質的に汎用的なものもある -- 例 - - ドロップダウンリストに対してのみ動作する - - 細分化された機能である - - パラメーターの1つとして関数を指定する - - いくつかの機能と連動して動作する - - 統合によって削減できる - - 同じ結果を実現しつつ、保守要件を最小化する - -### TAAをリファクタリングしてSUTの変更に対応する - -- SUTの変更に対応するための変更が必要になる -- SUTを支える機能を提供する -- フィーチャーを拡張する場合 - - アーキテクチャレベルで分析および変更を行う -- 追加スクリプトが必要になる場合 - - 互換コンポーネントによって新しい自動テストに対応する - -### 命名規約と標準化 - -- 変更が行われる場合 - - 以前に定義された標準と一貫性を持たせる - -### SUTの改訂 / 削除のための既存のスクリプトの評価 - -- 変更や改善のプロセス - - 既存のスクリプトの使用方法、継続的な価値の評価も含む -- 例 - - 複雑で実行に時間がかかる場合 - - それを複数の小さなテストに分割する -- 実行されないテストを削除対象とする - - 複雑度を低減させる - - 保守が必要なものを明らかにする - -# おわりに - -誰かの参考になれば幸いです。 - -## 所要時間 - -内容を理解しながら整理したので、体感4ページ/時間くらいのペースでした。 -正味66ページだったので、20時間弱だったかな。 -各章に書かれた目安時間合計してみたら、19.5時間で、想定された通りだったようです。 - -## ぼやき - -まあまあページ数があったので、疲れました。 -試験の受付が急に開始され、2か月限定で、FL必須なので、FLとってから、こちらを読み始めたので、忙しなかったなぁ。 diff --git a/public/.remote/a7a00da37b072186702f.md b/public/.remote/a7a00da37b072186702f.md deleted file mode 100644 index 9e6f028..0000000 --- a/public/.remote/a7a00da37b072186702f.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: 'AWS CDKで「Error: ARNs must have at least 6 components: undefined」になる時の解決策' -tags: - - AWS - - TypeScript - - CDK -private: false -updated_at: '2020-12-24T23:58:49+09:00' -id: a7a00da37b072186702f -organization_url_name: null -slide: false -ignorePublish: false ---- -## エラー - -AWS CDKで以下のようなエラーが出る事があります。 - -``` -Error: ARNs must have at least 6 components: undefined -``` - -意味としては、`lambdaVersionArn`が`undefined`で、少なくとも6つのブロックをもつARNの形式が必要だと言っています。 - -## 発生個所 - -ここではARNでバージョン指定のLambdaを取得しています。 - -``` sample-stack.ts -const lambdaVersionArn = props.lambdaVersionArn; -const lambdaVersion = lambda.Version.fromVersionArn(this, 'LambdaFunc', lambdaVersionArn); -``` - -ARNを外部から受け取っているStackで、Bootstrapや該当Stackではない処理を実行する時に、`lambdaVersionArn`を指定しないので`undefined`になってしまいます。 - -## 対応方法 - -`lambdaVersionArn`の値は実際には実行時にしか使われないのでダミーを指定する事で回避ができます。 - -``` -arn:aws:lambda:dummyAccount:function:dummyFunc:dummyVersion -``` - -ARNのフォーマットでダミーの値を作成します。 - -### 指定方法1:引数 - -``` shell -cdk bootstrap -c lambda-version-arn=arn:aws:lambda:dummyAccount:function:dummyFunc:dummyVersion -``` - -`-c`をつけて指定する方法は簡単ですが、bootstrapに関係ない引数が必要になるので、避けたい所です。 - -### 指定方法2:Stack内 - -``` sample-stack.ts -const lambdaVersionArn = props.lambdaVersionArn ?? 'arn:aws:lambda:dummyAccount:function:dummyFunc:dummyVersion'; -const lambdaVersion = lambda.Version.fromVersionArn(this, 'LambdaFunc', lambdaVersionArn); -``` - -分かりやすくはありますが、環境要因をStack内に書きたくないですね。 - -### 指定方法3:Stack呼び出し - -``` sample.ts -const lambdaVersionArn = app.node.tryGetContext('lambda-version-arn') ?? 'arn:aws:lambda:dummyAccount:function:dummyFunc:dummyVersion'; -new SampleStack(app, `sample-stack`, { - lambdaVersionArn : lambdaVersionArn, -}); -``` - -引数を取る部分と近くなり、環境要因が纏まって、スッキリしました。 - -## 余談 - -CDKは非常に便利ですが、結構癖があるので、対応方法を考える時に悩む事が多い気がします。 diff --git a/public/.remote/ae1959c29036dc4929fe.md b/public/.remote/ae1959c29036dc4929fe.md deleted file mode 100644 index 53078b2..0000000 --- a/public/.remote/ae1959c29036dc4929fe.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: 理解しやすいコードの書き方~理解容易性の7つの観点~ -tags: - - プログラミング - - 初心者 - - コードレビュー - - 保守性 - - 理解容易性 -private: false -updated_at: '2025-03-14T12:04:14+09:00' -id: ae1959c29036dc4929fe -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -「**理解容易性**」は「**保守性**」の観点の1つとして重視され、多くの**原則**や**技法**が紹介されているが、**断片的**かつ**多様**であり、**全体像**を理解することは難しい。 - -**抽象度は高い**が、**体系的**に観点を整理する事で、その理解の助けとなれば幸いである。 - -# 定義 - -「**理解容易性**」を簡単に言えば、「**理解のしやすさ**」であるが、その意味から掘り下げると、「**思考する量**」と言い換えることができる。 - -本記事では理解容易性を「**思考量の少なさ**」と定義し、7つの観点に整理した。 - -先に**要約**および**チェックリスト**を記載し、概略を記載した。 -後に**詳細**で理解のため、各観点毎の**説明**と個別の**原則**や**技法**へのリンクを記載した。 - -# 要約 - -7つの観点の要約を先に示す。 - -1. (変数や関数の)名称は**分かりやすく**する -1. (変数や関数の)役割は**1つ**にする -1. (変数や関数の)参照は**狭く**する -1. (変数や関数の)状態は**変えられなく**する -1. (関数やクラスの)面積は**小さく**する -1. (関数やクラスの)階層は**浅く**する -1. (関数やクラスの)秩序は**整え**る - -# チェックリスト - -質問の形に変え、一部を詳細化した。 - -1. (変数や関数の)名称は**分かりやすいか?** -1. (変数や関数の)役割は**複数ないか?** -1. (変数や関数の)参照は**広くないか?** - 1. 色々な所**から**参照されてないか? - 1. 色々な所**を**参照してないか? -1. (変数や関数の)状態は**変えられないか?** -1. (関数やクラスの)面積は**大きくないか?** - 1. 縦の**行数**は長くないか? - 1. 横の**文字数**は多くないか? -1. (関数やクラスの)階層は**深くないか?** -1. (関数やクラスの)秩序は**整っているか?** - -実装を終えたタイミングで確認してみて下さい。 - -# 詳細 - -## 前提 - -整理の為、観点を2つに大分した。 - -- **識別子(Identifier)** - - 変数や関数などを他と区別するための名称や記号 -- **区画(Block)** - - 関数やクラスなど、コードのまとまり - -## 識別子(Identifier) - -### 名称:曖昧 -> 明瞭 - -識別子の名称は、曖昧ではなく、明瞭とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/768f14fd-e369-3818-1871-2af61ecce420.png) - -曖昧である場合、確認範囲が広くなるため、思考量が増えてしまう。 - -- **命名規則の準拠** - - リポジトリで採用された命名規則に準拠する - - 規則に準拠しない場合、規則の理解に時間を要する - ref. [命名規則について](https://qiita.com/elu_jaune/items/aa429a210310d3a0c952) -- **適切な英語の使用** - - プログラムで一般的に使われる英語を使用する - - 独自な英語表現の場合、意図の理解に時間を要する - ref. [Qiita: プログラミングでよく使う英単語のまとめ](https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923) -- **省略名の不使用** - - 名称は省略せず記載する - - 経験や文化に依存した名称の場合、意図の理解に時間を要する - ref. [Qiita: 変数名を冗長にしたら変数名で悩まなくなった](https://qiita.com/ikuo0/items/891bef2220c4a92def50) -- **マジックナンバーの不使用** - - 意味を持った値には適切な名称をつける - - 無名である場合、その値の理解に時間を要する - ref. [Wikipedia: マジックナンバー (プログラム)](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B8%E3%83%83%E3%82%AF%E3%83%8A%E3%83%B3%E3%83%90%E3%83%BC_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)) -- **説明変数/関数の利用** - - 自明ではない値の場合、変数や関数を定義し、名称を付ける - - 無名である場合、その値の理解に時間を要する - ref. [Qiita: 説明変数(要約変数)のメリット・デメリットと、発展例(メソッドの抽出)](https://qiita.com/tooda/items/4e740295a82b626d6cd3) -- **列挙型の利用** - - 定数をグループ化し、用途を明確にする - - グループ化しない場合、用途の確認に時間を要する - ref. [Qiita: 列挙型(enum)の基本的な使い方とコード例](https://qiita.com/igm50/items/8c9788d4ba5868642c69) -- **驚き最小の原則に準拠** - - 名称と内容を一致させる - - 不一致である場合には、内容を読むことを強制する - ref. [Wikipedia: 驚き最小の原則](https://ja.wikipedia.org/wiki/%E9%A9%9A%E3%81%8D%E6%9C%80%E5%B0%8F%E3%81%AE%E5%8E%9F%E5%89%87) -- **アノテーションコメントの利用** - - 意図を表現しきれない時はコメントで残すが、コメントの意味も明示する - - コメントがない場合、その意図の理解に時間を要する - ref. [Qiita: アノテーションコメント](https://qiita.com/its532/items/fd82d19bb0ecf1d5a454) - -### 役割:複数 -> 単一 - -識別子の役割は、複数ではなく、単一とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/6db03fbd-4a04-7147-1b43-accd30701ca3.png) - -複数である場合、複雑性への対処のため、思考量が増えてしまう。 - -- **単一責任の原則に準拠(SOLIDの1つ)** - - 識別子が持つ責務は1つにする - - 複数ある場合、意図の理解に時間を要する - ref. [Wikipedia: SOLID.単一責任の原則](https://ja.wikipedia.org/wiki/SOLID#%E5%8D%98%E4%B8%80%E8%B2%AC%E4%BB%BB%E3%81%AE%E5%8E%9F%E5%89%87_(single-responsibility_principle)) -- **モジュール分割** - - 責務が複数ある場合、分割をする - - 分割をしない場合、責務の理解に時間を要する - ref. [Qiita:モジュールの分割](https://qiita.com/masatom86650860/items/d942aaf0d6a0411e7d05) -- **関心の分離** - - 関心(役割)により、分割をする - - 分割しない場合、複雑さへの対処に時間を要する - ref. [Wikipedia: 関心の分離](https://ja.wikipedia.org/wiki/%E9%96%A2%E5%BF%83%E3%81%AE%E5%88%86%E9%9B%A2) - ref. [Qiita: 関心の分離を意識した名前設計で巨大クラスを爆殺する](https://qiita.com/MinoDriven/items/37599172b2cd27c38a33) -- **値オブジェクトの利用** - - 役割の分離方法として、値の特性ごとに分割する - - 分割しない場合、複雑さへの対処に時間を要する - ref. [Zenn:【DDD入門】TypeScript × ドメイン駆動設計ハンズオン ‐ Chapter 08 値オブジェクト (Value Object)](https://zenn.dev/yamachan0625/books/ddd-hands-on/viewer/chapter8_value_object) -- **モジュールの凝集度** - - 同じ役割で纏まるように、分割する - - 纏まっていない場合、影響範囲の調査に時間を要する - ref. [Qiita: 凝集度について](https://qiita.com/uesho/items/59845b4891e12dfb3def) -- **インターフェース分離の原則(SOLIDの1つ)** - - 同じ役割ではないインタフェースは分割する - - 分割しない場合、不要な部分が増え、理解に時間を要する - ref. [Qiita: 【SOLID】インターフェース分離の原則を完全に理解したい](https://qiita.com/k2491p/items/7b4e56789964ac6328b3) -- **コマンド・クエリ分離の原則** - - コマンドとクエリは別の関数に分割する - - 分割しない場合、複雑性の理解に時間を要する - ref. [コマンド・クエリという考え方](https://qiita.com/pakkun/items/7dc5a9b6bc57225a3673) - -### 状態:可変 -> 不変 - -識別子の状態は、可変ではなく、不変とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/5e30271f-9f94-84b6-4613-459da851ad01.png) - -可変である場合、確認範囲が広くなるため、思考量が増えてしまう。 - -- **定数の利用** - - 変更されない値は変更できないようにする - - 変更できる場合、変更された可能性の確認に時間を要する - - 言語によっては`const`だけでなく、`readonly`なども利用可能である - ref. [Wikipedia: 定数 (プログラミング)](https://ja.wikipedia.org/wiki/%E5%AE%9A%E6%95%B0_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)) -- **不変オブジェクトの利用** - - オブジェクトが持つ値を変更できないようする - - 変更できる場合、変更された可能性の確認に時間を要する - ref. [Qiita: 不変オブジェクトって何?【作り方も解説】](https://qiita.com/abcaaa/items/d2222e4a9afee554a2c7) -- **値オブジェクトの利用** - - 不変オブジェクト化する際に関連する機能群を集約する - - 集約しない場合、不変オブジェクトの扱いに多くの時間を要する - ref. [Zenn:【DDD入門】TypeScript × ドメイン駆動設計ハンズオン ‐ Chapter 08 値オブジェクト (Value Object)](https://zenn.dev/yamachan0625/books/ddd-hands-on/viewer/chapter8_value_object) -- **継承の禁止** - - 必要のないクラスの継承を禁止する - - 禁止しない場合、変更時の影響確認に時間を要する - ref. [Qiita: 【Java】final修飾子 ( 定数化・継承禁止、オーバーライド禁止 )-クラスにつける](https://qiita.com/takahirocook/items/5e0916d9bf28bcf68d0c#%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%91%E3%82%8B) -- **オーバーライドの禁止** - - 必要のないオーバーライドを禁止する - - 禁止しない場合、呼び出し内容の確認に時間を要する - ref. [Qiita: 【Java】final修飾子 ( 定数化・継承禁止、オーバーライド禁止 )-メソッドにつける-オーバーライド](https://qiita.com/takahirocook/items/5e0916d9bf28bcf68d0c#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AB%E3%81%A4%E3%81%91%E3%82%8B-%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89) - -### 参照:広域 -> 局所 - -識別子の参照は、広域ではなく、局所とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/f0a8ab71-bdb3-b485-fb1e-6553a1a8e72a.png) - -広域である場合、確認範囲が広くなるため、思考量が増えてしまう。 - -- **モジュールの疎結度** - - モジュール間の結合度は低くする - - 低くない場合、影響範囲の確認に時間を要する - ref. [Qiita: 結合度について](https://qiita.com/uesho/items/59c99ccd712a591883d2) -- **値のスコープを狭くする** - - グローバル、フィールド、ローカルとできるだけ狭くする - - 狭くない場合、影響範囲の確認に時間を要する - ref. [Qiita: 良いコードの書き方-変数のスコープを小さくする](https://qiita.com/alt_yamamoto/items/25eda376e6b947208996#star5%E5%A4%89%E6%95%B0%E3%81%AE%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92%E5%B0%8F%E3%81%95%E3%81%8F%E3%81%99%E3%82%8B) - -#### 参照 - -- **純粋関数への転換** - - 外部との副作用を持たない関数やクラスに転換する - - ex. グローバルや環境変数を直接参照せず、引数として受け取る - - 転換しない場合、参照先の確認に時間を要する - ref. [Qiita: 純粋関数](https://qiita.com/oedkty/items/f5fb807390a87359da0f) - -#### 被参照 - -- **データ隠蔽** - - クラスが持つフィールドなどを直接参照させない - - 参照できる場合、影響範囲の確認に時間を要する - ref. [Qiita:データ隠蔽・情報隠蔽とは-データ隠蔽](https://qiita.com/fukuYm/items/bf13a26a68a938267463#%E3%83%87%E3%83%BC%E3%82%BF%E9%9A%A0%E8%94%BD) -- **情報隠蔽** - - 値を公開せず、必要な処理のみを公開する - - 値を公開した場合、影響範囲の確認に時間を要する - ref. [Zenn:ドメイン知識が漏れるとは何なのか](https://zenn.dev/praha/articles/92c6494570a4dc) - -## 区画(Block) - -### 面積:広大 -> 狭小 - -区画の面積は、広大ではなく、狭小とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/6a1df0fc-9734-946e-f836-768767c5866f.png) - -広大である場合、確認範囲が広くなるため、思考量が増えてしまう。 - -- **重複の除去(DRY原則)** - - 同じ意味で重複したものは1つにする - - 重複した場合、変更時の対応に時間を要する - ref. [Wikipedia: Don't repeat yourself](https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself) -- **関数の抽出** - - まとまりごとに関数として抽出する - - 抽出しない場合、確認する量の多さに時間を要する - ref. [Qiita: リファクタリング入門-関数の抽出](https://qiita.com/Jazuma/items/f6a134f964747399d864#%E9%96%A2%E6%95%B0%E3%81%AE%E6%8A%BD%E5%87%BA) - -#### 縦:行数 - -主処理部分の行数は5~10行程度、全体としても20行程度に収める。 - -- **デッドコードの除去** - - 利用されることのなくなった、できないコードは削除する - - 削除しない場合、別の人も同じ確認に時間を要する - ref. [Qiita: CleanCode読書メモ-デッドコード](https://qiita.com/opengl-8080/items/c44814564cd216e50656#g9%E3%83%87%E3%83%83%E3%83%89%E3%82%B3%E3%83%BC%E3%83%89-p379) -- **不使用コードの除去(YAGNI)** - - 現時点で使わないコードは記述しない - - 記述した場合、意味のないコードの確認に時間を要する - ref. [Wikipedia: YAGNI(You ain't gonna need it)](https://ja.wikipedia.org/wiki/YAGNI) -- **nullの不使用** - - 必要な時以外はnullを利用しない - - 利用した場合、nullを考慮した実装の冗長さにより多くの時間を要する - ref. [Javaでnullを安全に扱う − Optionalの使い方](https://blog.isystk.com/system_develop/backend/java/706/) -- **値オブジェクトの利用** - - 直接値を利用せず、値オブジェクトにする - - 値オブジェクトにしない場合、値の判定や関連処理の冗長さにより多くの時間を要する - ref. [Zenn:【DDD入門】TypeScript × ドメイン駆動設計ハンズオン ‐ Chapter 08 値オブジェクト (Value Object)](https://zenn.dev/yamachan0625/books/ddd-hands-on/viewer/chapter8_value_object) -- **3項演算子の利用** - - 複雑ではない場合、3項演算子を利用する - - 利用しない場合、記述の冗長さにより多くの時間を要する - ref. [Qiita: 三項演算子の適切な使い方(条件演算子)](https://qiita.com/smicle/items/7d3b9881834dc0142fb7) - -##### コメント - -- **退化コメントの除去** - - 古くなったと分かったコメントは除外する - - 除外しない場合、別の人も同様の確認に時間を要する - ref. [Qiita: CleanCode読書メモ-退化コメント](https://qiita.com/opengl-8080/items/c44814564cd216e50656#c2%E9%80%80%E5%8C%96%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88-p372) -- **冗長コメントの除去** - - 翻訳コメントなど意味のないコメントは除外する - - 除外しない場合、情報密度が低くなり、把握に多くの時間を要する - ref. [Qiita: CleanCode読書メモ-冗長コメント](https://qiita.com/opengl-8080/items/c44814564cd216e50656#c2%E9%80%80%E5%8C%96%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88-p372) -- **コメントアウトの除去** - - バージョン管理で確認できる内容を残さない - - 残した場合、情報密度が低くなり、把握に多くの時間を要する - ref. [Qiita: CleanCode読書メモ-コメントアウトされたコード](https://qiita.com/opengl-8080/items/c44814564cd216e50656#c5%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%A2%E3%82%A6%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89-p373) - -#### 横:字数 - -単純な行ではなく、一文として80字程度に収める。 - -- **パラメーターオブジェクトの利用** - - 引数の数が多い場合、専用のオブジェクトを作成する - - 作成しない場合、宣言部および利用箇所の記述の冗長さにより、把握に多くの時間を要する - ref. [Hatena: パラメータオブジェクトの導入【リファクタリング】](https://tech-up.hatenablog.com/entry/2018/12/21/112407) -- **説明変数/関数の利用** - - 冗長な条件判定は別途変数や関数に分割する - - 分割しない場合、記述の冗長さにより、把握に多くの時間を要する - ref. [Qiita: 説明変数(要約変数)のメリット・デメリットと、発展例(メソッドの抽出)](https://qiita.com/tooda/items/4e740295a82b626d6cd3) - -### 階層:多層 -> 単層 - -区画の階層は、多層ではなく、単層とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/c3720162-6632-b8f5-31a8-3eeb5d299fd5.png) - -多層である場合、複雑性への対処のため、思考量が増えてしまう。 - -- **早期リターン** - - 主処理の必要性ない条件は先に`return`や`exit`させてしまう - - させない場合、ネストの深さの理解に時間を要する - - ガード節・アーリーリターンとも呼ばれる - - 類型として、アーリー・コンティニュー もある - ref. [Zenn: 早期リターンを書こう](https://zenn.dev/media_engine/articles/early_return) -- **関数の抽出** - - ネスト内の処理が多く、更にネストしている場合、別関数に分割する - - 分解しない場合、冗長さや複雑さの理解に時間を要する - ref. [Qiita: 良いコードの書き方 > ロジックの切り出し](https://qiita.com/alt_yamamoto/items/25eda376e6b947208996#%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%81%AE%E5%88%87%E3%82%8A%E5%87%BA%E3%81%97) -- **配列・リスト操作関数への転換** - - ネスト自体を必要としない記述方式に転換する - - 転換しない場合、複雑さの理解に時間を要する - ref.[Qiita: 深いネストを減らすには?-LINQ を使う](https://qiita.com/nskydiving/items/1076c411b002b0a3aec9#linq-%E3%82%92%E4%BD%BF%E3%81%86) - -### 秩序:雑然 -> 整然 - -区画の秩序は、雑然ではなく、整然とする。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/fb567352-2b6e-d265-8ab2-a61544996fc4.png) - -雑然としている場合、複雑性への対処のため、思考量が増えてしまう。 - -- **簡潔に単純にする(KISS)** - - おおよそ簡潔かつ単純にする - - 簡潔かつ単純ではない場合、理解に時間を要する - ref. [Wikipedia: KISS(Keep it simple stupid)の原則](https://ja.wikipedia.org/wiki/KISS%E3%81%AE%E5%8E%9F%E5%89%87) -- **コーディングスタイルの準拠** - - リポジトリルールがある場合はそれに準拠する - - 準拠しない場合、ルールの理解に時間を要する - ref. [Google Style Guides](https://google.github.io/styleguide/) -- **段落分け** - - 意図の纏まりごとに段落を分ける - - 分けない場合、意図の理解に時間を要する - ref. [【リーダブルコード】良いコードを書くための原則【入門編】 > 5コードを段落に分ける](https://zenn.dev/hinoshin/articles/80391c94a0b1a7#5%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%AE%B5%E8%90%BD%E3%81%AB%E5%88%86%E3%81%91%E3%82%8B) -- **関数の抽出** - - 意図の纏まりの数が多い場合、それぞれを別の関数に分割する - - 分割しない場合、内容の理解に時間を要する - ref. [Qiita: 良いコードの書き方 > ロジックの切り出し](https://qiita.com/alt_yamamoto/items/25eda376e6b947208996#%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%81%AE%E5%88%87%E3%82%8A%E5%87%BA%E3%81%97) -- **高凝集化** - - 意図が同じ内容を同じところに纏める - - 纏めない場合、関連する箇所の把握に時間を要する - ref. [Qiita: 凝集度について](https://qiita.com/uesho/items/59845b4891e12dfb3def) -- **カプセル化** - - データとロジックを同じところに纏める - - 纏めない場合、関連する箇所の把握に時間を要する - ref. [Wikipedia: カプセル化](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96) -- **対称性** - - 大きな意図が同じ名称やブロックでは、対称性や相似性を高くする - - 低い場合、大きな意図が同じである事の理解に時間を要する - ref. [Qiita: コードレビューに使える「7つの設計原則」 > 3. 対称原理](https://qiita.com/tkparasol/items/e57065d04b2a236a3b49#3-%E5%AF%BE%E7%A7%B0%E5%8E%9F%E7%90%86) -- **インフラ・ドメインの分離** - - ドメインとインフラ層のコードを混ぜない - - 混ぜた場合、複雑さの理解に時間を要する - ref. [HP: 私がコピペしたいからドメイン層とインフラストラクチャ層を分離してくれ](https://blog.rhyztech.net/separate_domain_and_infrastructure_layer/) -- **粒度の統一** - - ロジック内の粒度は統一して記載する - - バラバラの場合、複雑さの理解に時間を要する - ref. [Hatena: 脱・読みづらいコード!今日から一段上のプログラマーになる方法 5 選 > 2. 粒度を揃える](https://xin9le.hatenablog.jp/entry/2016/02/26/043557) - -# 終わりに - -分かり辛い点が多いですが、良いコーディングの参考になれば幸いです。 - -# 参考 - -## 書籍 - -- [Tidy First?](https://www.oreilly.co.jp/books/9784814400911/) -- [リーダブルコード](https://www.oreilly.co.jp/books/9784873115658/) -- [リファクタリング 既存のコードを安全に改善する(第2版)](https://amzn.asia/d/0i5mCDRK) -- [良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方](https://amzn.asia/d/0abFsGMC) -- [Clean Architecture 達人に学ぶソフトウェアの構造と設計 (アスキードワンゴ)](https://amzn.asia/d/0dvxNtcV) -- [エリック・エヴァンスのドメイン駆動設計](https://amzn.asia/d/048OK6GM) -- [脳に収まるコードの書き方 ―複雑さを避け持続可能にするための経験則とテクニック](https://www.oreilly.co.jp/books/9784814400799/) - - ## 記事 - -- [Qiita: 良いコードの書き方](https://qiita.com/alt_yamamoto/items/25eda376e6b947208996) -- [Qiita: コードレビューに使える「7つの設計原則」](https://qiita.com/tkparasol/items/e57065d04b2a236a3b49) -- [Qiita: 新人プログラマ アンチパターン:原理原則多すぎて脳みそOOMエラー](https://qiita.com/_mi/items/d008267d2e181bc7ba25) diff --git a/public/.remote/d910871db4b53d77bffe.md b/public/.remote/d910871db4b53d77bffe.md deleted file mode 100644 index 108530c..0000000 --- a/public/.remote/d910871db4b53d77bffe.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: たまに使うGitコマンド集 -tags: - - Git - - GitHub - - GitLab - - 初心者 -private: false -updated_at: '2022-09-16T19:02:16+09:00' -id: d910871db4b53d77bffe -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -便利だが、たまにしか使わないコマンドをメモとして残します。 - -## 基本方針 - -- main へのマージは squash する - - squash するので rebase は使わない - - squash するので feature の commit は自由にする - - main からの merge commit も気にせず入れる - -## 基本的なコマンド - -https://qiita.com/shimotaroo/items/b73d896ace10894fd290 - -## 見つからないコマンド - -### エディターをVimに変更したい - -``` shell -git config --global core.editor vim -``` - -### リモートの状態に戻したい - -``` shell -git switch feature -git fetch origin # ローカルを最新にする -git reset --hard origin/feature # 強制的に戻す -``` -[gitでリモートのブランチにローカルを強制一致させたい時](https://qiita.com/ms2sato/items/72b48c1b1923beb1e186) - -### 一時的に変更を退避したい - -``` shell -git stash -u # 退避する -git stash pop # 退避内容を戻して消す apply & drop -``` -[【git stash】コミットはせずに変更を退避したいとき](https://qiita.com/chihiro/items/f373873d5c2dfbd03250) - -### マージ先の変更を取り込む - -``` shell -git switch develop -git pull origin develop # ローカルを最新にする -git switch feature -git merge develop # developの変更をfeatureに取り込む -# コンフリクトする場合は解消する -git push -``` - -[pull requestでCan't automatically merge発生の場合の対応](https://qiita.com/hibriiiiidge/items/7fee5035a48dbb73aa51) - -### リモートの直前のコミットを取り消したい - -``` shell -git switch feature -git reset --hard HEAD^ # 1つ前の状態に戻す -git push origin feature -``` - -[困ったときの git reset コマンド集](https://qiita.com/ChaaaBooo/items/459d5417ff4cf815abce) - -### リモートのコミットのコメントを修正したい - -forceが利用できる環境のみ可能 - -``` shell -git switch feature -git rebase -i HEAD~1 -# 一覧の変更したいコミットの pick を reword に変更し、保存する -git push --force origin feature -``` - -[GitHub Docs - 古いまたは複数のコミットメッセージの修正](https://docs.github.com/ja/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message#amending-older-or-multiple-commit-messages) - -### 空のブランチを作成したい - -``` shell -git checkout --orphan doc -``` - -[gitの空ブランチを作る](https://qiita.com/akiko-pusu/items/7c0a99b8cb37882d2cfe) - -## 参考 - -https://git-scm.com/book/ja/v2 - -- 本家 - -https://k.swd.cc/learnGitBranching-ja/ - -- 練習用サイト diff --git a/public/.remote/de69639aaef6bc2a31fc.md b/public/.remote/de69639aaef6bc2a31fc.md deleted file mode 100644 index 0e961bf..0000000 --- a/public/.remote/de69639aaef6bc2a31fc.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: 最近良く見る「アウトプット」「アウトカム」「インパクト」とは何か? -tags: - - アジャイル - - スクラム - - ユーザーストーリー - - ユーザーストーリーマッピング - - インパクト評価 -private: false -updated_at: '2025-03-17T13:13:59+09:00' -id: de69639aaef6bc2a31fc -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# はじめに - -最近、開発をしているとこれらの言葉を耳にすることが大分増えました。 - -- **Output(アウトプット)** -- **Outcome(アウトカム)** -- **Impact(インパクト)** - -当たり前のように使い始めていましたが、気になったので、どのようなに経緯で広まったのか調べてみました。 - -簡単な言葉の解説と共に紹介します。 - -# 解説 - -大まかな関係を図示しました。 - -```mermaid - flowchart LR - Activities(プロジェクト
活動)-->**Output**-->**Outcome**-->**Impact** - style Activities stroke-dasharray: 5 5 -``` - -## Output(アウトプット) - -- プロジェクトや活動の**直接的な成果物や結果**を指す -- **具体的**で**測定可能**なものである -- プロジェクトの**完了時点で得る**ことができる - -**例** - -- リリースされた機能 -- 公開されたマニュアル - -## Outcome(アウトカム) - -- Outputがもたらす**短期的な効果**を指す -- プロジェクトや活動が終了した後に**観察される変化や影響**である -- Outcomeを**複数に分けて**いるケースもある ex. 短期・中期・長期 - -**例** - -- 機能の利用による顧客満足度の向上 -- マニュアル記載による問い合わせ工数の削減 - -## Impact(インパクト) - -- Outcomeがさらに広範囲に及ぼす**長期的な影響**を指す -- 社会全体や特定のコミュニティに対する**最終的な効果**を意味する -- **Impactがない**ケースもある(複数Outcomeのケース) - -**例** - -- 問い合わせ工数の削減による業務効率の向上(コスト) -- 顧客満足度の向上による契約継続率の上昇(品質) - -# 経緯 - -どのようなに広まったのか調べた結果です。 - -**※個人的な調査なので、間違っている可能性があるのでご注意ください。** - -## User Story Mapping(ユーザー・ストーリー・マッピング) - -ソフトウェア界隈で良く使われるようになったのは、**Jeff Patton**さんの影響が強いようです。 - -https://vimeo.com/206617354 - -ご本人のサイトがあり色々と紹介されています。 - -https://jpattonassociates.com/story-mapping/ - -## Logic Model(ロジック・モデル) - -上記でソフトウェア界隈と書いたのは、**政府系の政策評価**にも良く利用されているからです。 -こちらは**プロジェクトの計画、実行、評価を体系的に行うための手法**のようです。 - -https://en.wikipedia.org/wiki/Logic_model - -**構成** - -このモデルだと前ステップが明示的に定義されています。 - -```mermaid - flowchart LR - **Input**:::bold-->**Activities**:::bold-->Output-->Outcome-->Impact - - classDef bold stroke-width:3px; -``` - -- **Input(インプット)**: プロジェクトや活動のために投入されるリソース -- **Activities(アクティビティ)**: インプットを使用して行われる具体的な活動 - -**利用例** - -内閣府ホームページを始め、多くの行政の政策評価で利用されています。 - -[[PDF] 社会的インパクト評価の普及促進に係る調査 最終報告書](https://www.cao.go.jp/others/kichou/ebpm/h28_si_chousa_11.pdf) - -## Results Chain(リザルツ・チェーン) - -日本語だと「**結果・成果の連鎖**」と言うようですが、記事は英語でも少なく、日本語は僅かでした。 - -以下のような使い分けのようです。 - -- ロジック・モデル:チェーン部分も含めた**因果関係の理論** -- リザルツ・チェーン:チェーン部分にフォーカスした**表現ツール** - -# おわりに - -メモ書きのような内容ですが、参考になれば幸いです。 - -# おまけ - -話題のDeep Researchで調べてみたのですが、良く利用される単語の組み合わせだと、私の力量では期待する結果を得られなかったので、結局は自分で調べて書くことになりました。 diff --git a/public/.remote/e91b4b77838f171c16eb.md b/public/.remote/e91b4b77838f171c16eb.md deleted file mode 100644 index 1554abb..0000000 --- a/public/.remote/e91b4b77838f171c16eb.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: やりたくない仕事をやらずに済む方法 -tags: - - ポエム -private: false -updated_at: '2023-12-11T07:01:38+09:00' -id: e91b4b77838f171c16eb -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# 結論 - -「やりたい仕事」をやりましょう。 - -## 正確には・・・ - -(やりたくない仕事よりも)**価値がある**「やりたい仕事」をやりましょう。 - -# 補足 - -## そもそも仕事をしたくない。 - -本記事の対象外ですが、不労収入を構築しましょう。 - -## やりたい仕事がない。 - -探してもないなら、異動もしくは転職しましょう。 - -## やりたい仕事はあるが・・・ - -### 時間がない。 - -交渉して、人員を確保しましょう。 - -## やらせてもらえない。 - -### 価値がないなら・・・ - -見切りをつけて、他の仕事を探しましょう。 - -### 価値があるなら・・・ - -諦めずに、上長と話しましょう。 - -#### 上長と折り合わないないなら・・・ - -深追いし過ぎず、異動もしくは転職しましょう。 - -# まとめ - -「やりたい仕事」をするのも大変・・・。 - -## 最後に - -最後まで読んで頂きありがとうございます。 - -ポエムを書いてみたかった気持ちが昇華できました。 diff --git a/public/.remote/f35423265630ed68d3d2.md b/public/.remote/f35423265630ed68d3d2.md deleted file mode 100644 index 2d01c43..0000000 --- a/public/.remote/f35423265630ed68d3d2.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -title: 開発に便利なユニットテストの使い方 -tags: - - Java - - JUnit - - ユニットテスト - - junit5 - - whi-advent -private: false -updated_at: '2023-01-13T14:37:21+09:00' -id: f35423265630ed68d3d2 -organization_url_name: works-hi -slide: false -ignorePublish: false ---- -# 始めに - -ユニットテストを品質の向上の為ではなく、**開発する際に便利なツールである**、と言う観点で紹介をします。 - -# 利用例 - -まずは、**どんな時に便利か**、と言う話です。 - -## 1) コードを修正したら、サーバーを再起動して、動作確認している。 - -コードを変更するたびにTomcatの起動を待っているような場合、ユニットテストを利用する事で、動作確認の為の起動が早くなり、**待ち時間を短縮する**事ができます。 - -## 2) パターンテストを設定変更で、動作確認している。 - -設定により変わる動作の確認をする際に、パターンを繰り返し実行している場合、ユニットテストを利用する事で、**複数のパターンを同時に確認する**事ができます。 - -## 3) 実装を変更する度に、動作確認している。 - -動作確認をした後に不具合やリファクタリングにより実装変更した際に、もう一度動作確認をする場合、ユニットテストを利用する事で、**楽に動作確認を繰り返す**事ができます。 - -## 4) 例外ケースの確認の為の再現に苦労している、もしくは、確認を諦めている。 - -通常発生しないケースの確認としてログを出力したり、例外をスローするケースの再現に苦労している場合、ユニットテストを利用する事で、**例外ケースを簡単に再現する**事ができます。 - -## 5) ドキュメントを書いても、修正によりに実装とズレていく。 - -JavaDocやJSDocを書いた後に実装の変更した際に、修正を忘れてしまうような場合、ユニットテストを利用する事で、**動作確認すると同時に仕様を残す**事ができます。 - -# 実装例 - -例として休日を判定するロジックを作成する場合の流れを紹介します。 - -## 前提 - -コード記述は以下の利用を前提としています。 - -- [Java](https://www.java.com/ja/) -- [JUnit5](https://junit.org/junit5/) -- [Hamcrest](http://hamcrest.org/JavaHamcrest/) - -※途中で出てくる`// ~~~`は行の省略を意味します。 - -## 対象の関数を決める - -ここでは対象日付が休日かどうかを判定する関数を対象にします。 - -```java:CalendarUtils.java -package com.example; - -import java.util.Calendar; - -public class CalendarUtils { - - /** - * 休日であるか判定する。 - * - * 対象日(targetDate)が休日の場合、trueを返す。 - * 休日は土曜日、日曜日を対象とする。 - * - * @param targetDate 対象日 - * @return booleanを返す - * @throws IllegalArgumentException 対象日(targetDate)がnullの場合 - */ - public static boolean isHoliday(Calendar targetDate) throws IllegalArgumentException { - if (targetDate == null) { - throw new IllegalArgumentException("TargetDate is null."); - } - - int dayOfWeek = targetDate.get(Calendar.DAY_OF_WEEK); - - if (dayOfWeek == Calendar.SUNDAY) return true; - if (dayOfWeek == Calendar.SATURDAY) return true; - - return false; - } - -} -``` - -ユニットテストを使わずにこの関数の動作確認をする場合、サーバーを起動し、該当部分が実行される操作をします。 - -### ユニットテストで実行する。 - -テストクラスを作成し、以下のように記述します。※通常、テストクラスはIDEで簡単に作成できます。 - -```java:CalendarUtilsTest.java -package com.example; - -import java.util.Calendar; - -import static org.hamcrest.MatcherAssert.*; -import static org.hamcrest.Matchers.*; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.DisplayName; - -public class CalendarUtilsTest { - - @Test - @DisplayName("isHolidayは、対象日が休日の場合、trueを返す。") - void testIsHoliday() throws IllegalArgumentException { - // Given - Calendar targetDate = Calendar.getInstance(); - targetDate.set(2022, Calendar.AUGUST, 14); - - // When - boolean actual = isHoliday(targetDate); - - // Then - assertThat(actual, is(Boolean.TRUE)); - } - -} -``` - -これだけで実行が可能です。長い起動時間を待つ事無く、動作を確認する事ができます。 - -### パターンテストを実行する - -先ほどの関数を複数パターンに対応した記述に書き換えます。直接記述した値を引数で受けるようにします。 - -```java:CalendarUtilsTest.java -package com.example; - -import java.util.Calendar; -import java.util.stream.Stream; // <-- 追加 - -import static org.hamcrest.MatcherAssert.*; -import static org.hamcrest.Matchers.*; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; // <-- importを追加 -import org.junit.jupiter.params.provider.Arguments; // <-- importを追加 -import org.junit.jupiter.params.provider.MethodSource; // <-- importを追加 -import org.junit.jupiter.api.DisplayName; - -public class CalendarUtilsTest { - - // @Test <-- ParameterizedTestに変更 - @ParameterizedTest - @MethodSource("sourceIsHoliday") // <-- データを作成する関数を指定 - @DisplayName("isHolidayは休日であるかを返す。") - void testIsHoliday(String description, Calendar targetDate, boolean expected) throws Exception { - // Given by parameter - // Calendar targetDate = Calendar.getInstance(); <-- 引数に変更 - // targetDate.set(2022, Calendar.AUGUST, 14); - - // When - boolean actual = isHoliday(targetDate); - - // Then - assertThat(actual, is(expected)); - } - - static Stream sourceIsHoliday() { // <-- データを作成する関数 - // targetDate のパターンを指定 - Calendar weekday = Calendar.getInstance(); // 平日 - weekday.set(2022, Calendar.AUGUST, 1); - Calendar saturday = Calendar.getInstance(); // 土曜 - saturday.set(2022, Calendar.AUGUST, 6); - Calendar sunday = Calendar.getInstance(); // 日曜 - sunday.set(2022, Calendar.AUGUST, 7); - - return Stream.of(// <-- testIsHolidayに渡すデータ - Arguments.of("対象日が平日の場合、falseを返す。", weekday, false), - Arguments.of("対象日が土曜の場合、trueを返す。", saturday, true), - Arguments.of("対象日が日曜の場合、trueを返す。", sunday, true) - ); - } - -} -``` -設定を変えてテストしていたら時間がかかる内容も、組み合わせを簡単に作成して、同時に動作確認をする事ができます。 - -### 仕様変更に対応する - -土曜日を含むかどうか指定できるように仕様変更したケースに対応してみます。containSaturdayを引数に追加して動作を合わせて変えます。 - -```java:CalendarUtils.java - -package com.example; - -import java.util.Calendar; - -public class CalendarUtils { - - /** - * 休日であるか判定する - * - * 対象日(targetDate)が休日の場合、trueを返す。 - * 休日は土曜日、日曜日を対象とする。 - * - * @param targetDate 対象日 - * @param containSaturday 休日に土曜を含むか // <-- 引数を追加 - * @return booleanを返す - * @throws IllegalArgumentException 対象日(targetDate)がnullの場合 - */ - public static boolean isHoliday(Calendar targetDate, boolean containSaturday) throws IllegalArgumentException { // <-- 引数を追加 - if (targetDate == null) { - throw new IllegalArgumentException("TargetDate is null."); - } - - int dayOfWeek = targetDate.get(Calendar.DAY_OF_WEEK); - - if (dayOfWeek == Calendar.SUNDAY) return true; - if (containSaturday && dayOfWeek == Calendar.SATURDAY) return true; // <-- 条件を追加 - - return false; - } - -} -``` - -組み合わせにも追加します。 - -```java - static Stream sourceIsHoliday() { - // targetDate - Calendar weekday = Calendar.getInstance(); // 平日 - weekday.set(2022, Calendar.AUGUST, 1); - Calendar saturday = Calendar.getInstance(); // 土曜 - saturday.set(2022, Calendar.AUGUST, 6); - Calendar sunday = Calendar.getInstance(); // 日曜 - sunday.set(2022, Calendar.AUGUST, 7); - - // containSaturday <-- 追加した引数のパターンを追加 - boolean contain = true; // 含む - boolean notContain = false; // 含まない - - return Stream.of(// <-- testIsHolidayに渡すデータを変更 - Arguments.of("対象日が平日で、土曜を含む場合、falseを返す。", weekday, contain, false), - Arguments.of("対象日が平日で、土曜を含まない場合、falseを返す。", weekday, notContain, false), - Arguments.of("対象日が土曜で、土曜を含む場合、trueを返す。", saturday, contain, true), - Arguments.of("対象日が土曜で、土曜を含まない場合、falseを返す。", saturday, notContain, false), - Arguments.of("対象日が日曜で、土曜を含む場合、trueを返す。", sunday, contain, true), - Arguments.of("対象日が日曜で、土曜を含まない場合、trueを返す。", sunday, notContain, true) - ); - } -``` - -ケースが2倍になり、複雑になりましたが、変更前の部分も合わせ同時に動作確認をする事ができます。 - -### 例外系を書いてみる - -今度は例外を取るケースもテストをしてみます。先ほどとは検証内容が異なるので、別の関数にします。 - -```java -// ~~~ -import static org.junit.jupiter.api.Assertions.assertThrows; // <-- importを追加 -// ~~~ -public class CalendarUtilsTest { -// ~~~ - @Test - @DisplayName("isHolidayは対象日がnullである場合、例外が発生する。") - void testIsHolidayWhenTargetDateIsNull() { // <-- 関数を追加 - // Given - Calendar targetDate = null; - - // When - IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> isHoliday(targetDate, true)); // <-- 発生したExceptionを取得 - - // Then - assertThat(e.getMessage(), is("TargetDate is null.")); // <-- メッセージを検証 - } -``` - -設定では再現しづらく、諦めがちなテストも動作確認をする事ができます。 - -### テストケースをグループに纏める - -関数に対するテストケースが分かれて見づらいので纏めます。ケースに合わせ関数名も変更します。 - -```java -// ~~~ -import org.junit.jupiter.api.TestInstance; // <-- importを追加 -import org.junit.jupiter.api.TestInstance.Lifecycle; // <-- importを追加 -// ~~~ -import org.junit.jupiter.api.Nested; // <-- importを追加 -// ~~~ -public class CalendarUtilsTest { - - @Nested - @DisplayName("isHolidayは休日であるかを判定する。") // <-- 関数の説明を記載 - @TestInstance(TestInstance.Lifecycle.PER_CLASS) // <-- class内にsourceを配置する為に指定 - class IsHolidayTest { // <-- グルーピング用を追加 - - @ParameterizedTest - @MethodSource("sourceWhenTargetDateIsNotNull") // <-- 合わせて変更 - @DisplayName("対象日付がnullではない場合") // <-- 場合分けに変更 - void testWhenTargetDateIsNotNull(String description, Calendar targetDate, boolean containSaturday, boolean expected) throws Exception { // <-- 場合分けに変更 - // ~~~ - } - - Stream sourceWhenTargetDateIsNotNull() { // <-- 名称変更、staticを除外 - // ~~~ - } - - @Test - @DisplayName("対象日がnullである場合、IllegalArgumentExceptionが発生する。") // <-- 関数名を除外 - void testWhenTargetDateIsNull() { // <-- 関数名を除外 - // ~~~ - } - } -``` - -このように整理する事で纏まりが分かりやすくなり、パターンの漏れがないか確認しやすくなります。 - -## 詳細な仕様はテストケースに任せる - -上記での仕様変更のドキュメントへの反映が漏れています。組み合わせも多く、該当ケースが分かりづらいので、テストケースを参照するように促す。 - -```java:CalendarUtils.java - * 休日であるかを返す。 - * - * 対象日(targetDate)が休日の場合、trueを返す。 - * 休日は土曜日、日曜日を対象とする。// <-- 仕様変更が反映されづらいので削除 - * - * @param targetDate 対象日 - * @param containSaturday 休日に土曜を含むか - * @return booleanを返す - * @throws IllegalArgumentException 対象日(targetDate)がnullの場合 - * @see "Test: com.example.CalendarUtils.IsHolidayTest" // <-- テストケースをみるように追加 - */ - public static boolean isHoliday(Calendar targetDate, boolean containSaturday) throws IllegalArgumentException { - // ~~~ - } -``` - -テストケースに詳細仕様を任せる事で、更新漏れによる仕様の不一致を防ぐことができます。 - -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/55729614-5052-1516-fa85-b3594c027172.png) - -こんな感じで表示されるようになります。社内で利用するだけであれば十分です。 - -## 実行結果 - -VSCodeで実行した結果を参照して、出力のされ方を確認します。 -![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58677/0161ff58-8429-2ec0-9dd4-172a7774cfa6.png) -実行した結果を分かりやすいようにしておく事で、他の人が仕様を把握するのが楽になります。 - -## サンプルコード - -実行できるコードは以下から取得可能です。動かしてみたい方はご利用下さい。 - -https://github.com/GOAMI-Takaaki/unittest-for-developer - -# おまけ - -もっと色々とやってみたい方はmoromi25さんの記事が初心者向けに詳しいので、こちらも見てみて下さい。 - -https://qiita.com/moromi25/items/9358c716cb7d70fde31a - -# 参考資料 - -MockやHelper関数など他の方法も活用すると多くのケースに対応できます。 - -- [リーダブルテストコード](https://qiita.com/yonetty/items/7787a539d77396a3807e) -- [mockを使おう!](https://qiita.com/Fudeko/items/301f8a80963dfcaafb80) -- [mockitoでstaticなメソッドをMock化する](https://qiita.com/morinco/items/a41cc7685be75a2f6e08)