ContractS開発者ブログ

契約マネジメントシステム「ContractS CLM」の開発者ブログです。株式会社HolmesはContractS株式会社に社名変更しました。

TestCafeにGaugeを組み合わせてBDDできないか試してみた

社内でE2Eテストツールとして、TestCafeの話題が出たため、前回の記事で試したGaugeとの組み合わせでBDDのようにテストを実行できないか、検証してみました。

実行環境

名前 バージョン
OS Windows 10 Pro 64bit バージョン2004
Node.js 14.15.2
Yarn 1.22.5
TestCafe 1.10.0
Gauge 1.1.6

なぜTestCafe単体ではなく、Gaugeと組み合わせようと思ったのか

TestCafe単体ではテストは簡潔に記述できるものの、実際の運用に乗せることを考えると、ログインや特定の状態への遷移といった、よくある処理の共通化は必要であると思います。

TestCafeはメソッドチェーンでテストを簡潔に記述できますが、共通で前処理を行おうと思うと、ツールのサポートとしてはFixtureのbeforeEachメソッドによるフィクスチャ単位の共通化しか見つけられませんでした。

Page Object Patternでも記述できるため、共通処理はPage Objectとして切り出し、フィクスチャやテストから実行することはできそうですが、BDDのように明示的に前処理を記述することは、TestCafe単体ではできないようなので、GaugeないしはCucumber.jsといったツールと組み合わせることで、明示的な処理の共通化ができるか確認できればと考えました。

また、前回はGaugeとJavaの組み合わせを試したため、今回はGaugeとJavaScriptの組み合わせで、使用感に違いがないかも確認できればと思い、Gauge+TestCafeで試してみることとします。

環境構築

TestCafeのインストール

devexpress.github.io

npmまたはYarnでインストールします。*1

インストールが完了したら、 testcafe -v でバージョンが確認可能です。記事作成時のバージョンは、1.10.0でした。

また、 testcafe -b で、利用可能なブラウザ一覧を確認できます。

# npm
$ npm install -g testcafe

# Yarn
$ yarn global add testcafe

# バージョン確認
$ testcafe -v
1.10.0

# 利用可能なブラウザ確認
# Firefox, Google Chrome, Microsoft Edge(Chromiumベース)、およびInternet Explorer 11と旧Microsoft EdgeがインストールされたWindows 10では、以下のように表示されました
$ testcafe -b
firefox
chrome
ie
edge
edge-legacy

Gaugeのインストール

前回の記事 と同様の手順で、Windowsインストーラーをダウンロードし、Gaugeをインストールします。

記事作成時のバージョンは、1.1.6でした。

Gauge+TestCafeのサンプルプロジェクトのダウンロード

getgauge-examples/gauge-testcafe にサンプルとなるGitプロジェクトがあったため、ZIPダウンロードおよび展開します。

npmまたはYarnで、依存モジュールのインストール後、テストを実行します。

# npm
$ npm install && npm test

# Yarn
$ yarn install && yarn test

TestCafeが起動し、Google Chromeのウィンドウが開きます。

起動時の画面

...が、以下のエラーで失敗しました。

Failed Step: Search for "github TestCafe"
Specification: specs\example.spec:6
Error Message: Error: Timed out
Stacktrace:
Error: Timed out
サンプルテストの修正

specs/example.spec がテスト仕様、 tests/step_implementation.js がテスト実装になります。

テスト内容を確認してみると、以下のようになっていました。

  1. Googleを開く
  2. 「github TestCafe」で検索
  3. 検索結果の最初のリンクのテキストに「GitHub - DevExpress/testcafe:」が含まれるか検証

まず、検索する文字列の入力欄を input[title="Search"] で取得しようとしているものの、日本語環境ではtitleが「検索」になっているようです。

また、GitHubの検索結果のリンクテキストが、記事作成時点では「DevExpress/testcafe: A Node.js tool to automate end ... - GitHub」となっているため、検証も失敗します。

それぞれ以下のように変更し、テストを再実行すると成功しました。

  1. 検索文字列の入力欄取得を input[title="検索"] で行うよう step_implementation.js を変更
  2. example.spec から渡される検証用の文字列を "GitHub - DevExpress/testcafe:" から "DevExpress/testcafe:" に変更

前回と同様、 reports/html-report/index.html にレポートが出力されます。

f:id:h-yamamoto_holmescloud:20201225124621p:plain
Gaugeのテストレポート

実装

いきなり躓きましたが、気を取り直して実装していきます。

テストするブラウザの変更

初期状態では、Google Chromeでのテストのみ実行されました。

コマンドからTestCafeを実行する場合、 testcafe ブラウザ名,ブラウザ名,... JavaScriptテストファイル でテストするブラウザを追加できるため、それっぽい設定はないかと確認したところ、 tests/testcafe_init.jsbrowsers('chrome') という設定がありました。調べてみると、APIを使ってJavaScriptから実行できるようです。

browsers(['chrome', 'ie', 'edge']) のように記述すると、各ブラウザのウィンドウは最初に開きますが、先頭のブラウザにのみテストが実行され、それが終わった段階でテスト終了と判断されます。

おそらく、オーケストレーションを行うGaugeと、テストを実行するTestCafeのライフサイクルの違いが原因かと思います。

ひとまず、Google Chrome以外にも、 browsers('ie')Internet Explorerbrowsers('edge')ChromiumMicrosoft Edgeでテストを実行できることは確認できました。

テスト仕様の追加

前回と同じMarkdownを、 specs/search.spec に保存しました。

テスト実装の記述

当初は tests/search_steps.js を追加して検証しようとしたのですが、GaugeではJavaScriptでテストを実装する場合、 tests/step_implementation.js にしかステップを記述できないようです。

ステップ内で実行する関数の内容を別ファイルに書いてimportしたりはできそうですが、ひとまず tests/step_implementation.js に以下を追記します。

なお、変数 _Selector は、それぞれTestCafeのTestController、およびSelectorになります。

step('検索エンジンのURL <url> を開く', async (url) => {
  await _.navigateTo(url);
});

step('検索文字列入力欄 <inputSelector> を取得する', async (inputSelector) => {
  const searchTextInput = Selector(inputSelector).with({ boundTestRun: _ });
  gauge.dataStore.scenarioStore.put('searchTextInput', searchTextInput);
});

step('<searchText> で検索する', async (searchText) => {
  const searchTextInput = gauge.dataStore.scenarioStore.get('searchTextInput');
  await _.typeText(searchTextInput, searchText);
  await _.pressKey('enter');
});

step('検索結果ページのタイトルが <title> であることを確認する', async (title) => {
  const titleElement = Selector('title').with({ boundTestRun: _ });
  const pageTitle = await titleElement.innerText;
  gauge.message(`検索結果ページのタイトル: ${pageTitle}`);
  await _.expect(pageTitle).eql(title);
});

TestCafeでは通常 fixturetest で記述していきますが、Gauge+TestCafeでは、実行時にGaugeのシナリオがTestCafeのfixtureに変換されるようです。

前回Javaで記述した部分をそのままJavaScriptに置き換えただけなので、TestCafeの記述としては洗練されていないですが、この状態で yarn test でテストの実行ができました。

感想

GaugeとTestCafeの組み合わせは、あまり良くはない印象です。

感じたデメリット

GaugeのJavaScriptによるテスト実装では、ステップを step_implementation.js にしか記述できないようです。私の調査不足かもしれませんが、ドキュメントをざっと読んだ限り、変更方法などは見つけられませんでした。

Gauge+TestCafeのサンプルプロジェクトでも、 step_implementation.js から test_controller_holder.js をimportしているため、実装を分割することは可能ですが、テストのステップをすべて単一ファイルに記述することになると、管理が煩雑になりそうです。

また、TestCafeの複数ブラウザによるテストや、並列テスト実行が活かせなくなりました。こちらはTestCafeのメリットを打ち消してしまっています。

TestCafe単体でできたことが、Gaugeと組み合わせたことでできなくなるのであれば、相性が悪いと言って差し支えないかと思います。

Gauge+Javaとの使用感の違い

Gauge+Javaでは複数ファイルにステップ記述が可能なため、そちらと比較するとGauge+JavaScriptは使い勝手が悪く感じました。

GaugeのData Storeに相当するctxがTestControllerに用意されていたりと、TestCafe自体が高機能ということもあり、Javaと組み合わせたときほど利便性の向上も感じませんでした。

TestCafeでBDDするための代替手段

TestCafeをGaugeと組み合わせるのは難しそうなので、Cucumberなど他のツールとの組み合わせが可能か調べてみました。

3年ほどOpenされているTestCafeのissueで、CucumberとTestCafeの統合についての要望が上がっており、そこからたどったissueの Cucumber Integration with Testcafe removed from roadmap? にて、Cucumber Integration がロードマップから削除されたこと、および gherkin-testcafe の使用が推奨されていました。

gherkin-testcafe を用いれば、Gherkin構文でTestCafeのテスト記述および実行ができるため、現時点ではこれを使うのがTestCafe+BDDには最適なようです。

実運用ではPage Objectとしてテスト対象のページをクラス化し、それをGherkinで記述したテスト仕様クラスから操作するのがいいかと思います。

総括

Gauge+Javaではかなりのメリットを感じられたのですが、Gauge+TestCafeではデメリットが目立つ結果となりました。

TestCafe自体の有用性は確認でき、またPage Object Patternによる記述ができることも確認できたため、今後はPage Object Patternによる実装や、 gherkin-testcafe との組み合わせの検証を行いたいと思います。

最後に

Holmesではエンジニア・デザイナーを募集しております。ご興味がある方はこちらからご連絡ください。

lab.holmescloud.com

lab.holmescloud.com

*1:Node.js、およびYarnのインストールについては割愛します

デザインのデイリー壁打ち

こんにちは。Holmesでデザイナーをしています古谷です。

今回は、プロダクトのイメージを固めていくアプローチについて書いてみたいと思います。

デザインをするにあたって、大まかな流れとしては、英デザイン・カウンシルの発表しているダブルダイヤモンドプロセスや、デザインスプリント等の手法でも用いられている通り、前提となるのは定性、定量データを元にしたアイデアの発散です。

発散する前提となる課題の発見や顧客の現状についての理解はまた別の機会で整理したいとおもいますが、では最初の仮設からどのようにして課題の特定と解決方法を検討していったら良いでしょう?

デザインをもとにした壁打ち

f:id:nfur:20201220144518p:plain

方法としては色々あるのですが、今年の夏前からの新プロダクトの構想を検討するに当たって、かなり泥臭いアプローチを実施してみました。

何を実施したか?

やったことはシンプルに「デイリー壁打ち」です。 新しい機能を構築する際に、CTOの花井と1時間のデイリー壁打ち、それをひたすら続けることでデザインを含めた新機能のイメージ、仕様を固めていきました。

というのも、大まかに「こんな感じの機能」というイメージというのは共通認識は取れているのですが、それが具体的にいうとどんな形で、どんな機能で、どんな機能なのかはお互いの頭の中にのみある状態だったのでそれを確かめる必要があったのです。

何を議論したか?

実現したいことが明確になる一歩手前の状態だったので、プロトタイプを作って、それが実現したいイメージとあっているかどうか?を検証していきました。プロトタイプを作ってそれが正しいかどうかを検証するというよりは、プロトタイプを作って、自分たちが作ろうとしているものが本当に有効な状態になるかどうか?が一番の大きな課題でした。

議論する内容としては、もちろん、仕様やインタラクションといったデザインの要素も含まれていますが、これって自分たちが自身をもって提供したいものだっけ?という批評をひたすら繰り返していきました。

新しい価値の提供を考えたときに、社内への共有や、社外の顧客への共有も含めて、実現したいことを簡潔に言語化できる状態にまで持っていく必要があります。

何十回ものデイリーでの壁打ちを繰り返す中で、できること、やらなくても良いことが明確になってきました。

壁打ちの進め方

まずはプロトタイプをざっくりと作ります。 途中でも中途半端でも、レイアウトが定まっていなくてもとにかくそれを共有します。 途中でも悩んでいるところでも良いので共有して、それをみながら議論するをします。 仕様や機能としてのあるべき姿、そして既存の要望を可能な限り巻き取って、プロダクトの方向性を定めていきました。

毎日1時間のミーティングですが、終わった後はクタクタになるくらい、ミーティング中はあらゆる可能性と指向を巡らせて、議論を繰り返します。

プロトタイプをそれなりに見える状態にまとめあげると共に、CTOは機能要件をドキュメントとして整理していく、というの平行して進めていきました。

プロトタイプのレベル

ワイヤーフレームだけで壁打ちの場に出すこともありますが、その場合、想像力で良い方に解釈してしまうこともあって、中途半端な議論になりがちです。 壁打ちの1時間を価値のある時間にするには、ある程度のレベルまで(顧客に見せてヒアリングしても良いレベルまで)一気に作り込んでしまうのが良いと思います。

ユーザーテストや顧客へ聞いた方が良いのでは?

ユーザーテストや、顧客に聴く、という行為もとても重要ですが、自分たちが提供したいこと、強み、弱点がクリアになっていないと芯のないフワフワとした検証になってしまいます。 中途半端なものを見せて、「いいんじゃないですか?」くらいの反応を収集しても、こちらが検証したいことは検証できないものです。

もちろん、プロダクトのフェーズによっては、顧客にまず聞け、というのはそのとおりだと思います。

細かいインタラクションは別途リファインメントでカバー

できる限り細かい部分も整合性がとれる状態でプロトタイプを作成しますが、 細いインタラクションなどはスクラムのプロセスの中でリファインメント時に再検討されます。

毎日の壁打ちで作成したプロトタイプから、MVPの状態にまで機能を絞り込むので、検討した内容がゴッソリと削られる部分も沢山あります。 それでも、将来的に有りたい姿を描いておくことで、何を削って何を入れるべきか?という判断が容易になって来るので、時間の許す限りプロトタイプは作り込むことをオススメします。

※もちろん、フィードバックを得るためのプロトタイプとして作り込む!というのが大前提です!

壁打ち相手

社内にかなり強力な壁打ち相手がいるおかげで、より良い形にすることができました。

  • ドメインに対する理解が深いCTO

  • エンジニアリングのプロセスを理解してくれるドメインエキスパート

  • 一般的な有るべき論を正してくれるプロダクトオーナー

得に、自分はまだまだドメイン知識が足りておらず、これらのエキスパートと議論することでより深い議論がでました。

見える化することによる議論の深化

形にすることで気づく細い違和感や、理想の状態との差分に気づくことが容易になるので、深い議論ができるようになります。 反面、これは見た目を決める議論ではない、という前提でいないと、枝葉の部分のツッコミが入るので注意は必要です。

議論の空中戦を防ぐことで課題を明確にできる

空中戦で抽象的な議題をまとめ上げるのは(個人的には)好きですが、結局どうするんだっけ?というフェーズになったときにもう一度同じ議論を繰り返しがちになります。貴重な時間の短縮という意味でも、可視化しながら議論を進めていくことは効果的です。

デザイナーのアウトプットについて

一人より、チームで課題に取り組んだほうがより顧客やビジネス、エンジニアリングの課題を反映した状態にできます。

厳しい壁打ちを繰り返して、打たれても負けない状態でリングに上がったほうがより良いものを作れると思うので、正しい批評を行って、正しい改善をできるだけ早く繰り返すにはデイリー壁打ちはとても良い方法だと思います。

また、プロトタイプはあくまでもフィードバックを引き出すための材料、という認識があるので、素早く、小さく、細かく試行錯誤を繰り返すには、長くても1日位の期間で新しいフィードバックをどんどん引き出せる状態にするのが効果的です。

株式会社Holmesでは、豊富な知識と経験をもつドメインエキスパートやエンジニアリングのスペシャリストと 壁打ちを繰り返して、より良いプロダクトを作っていきたいデザイナーを大募集しています。 また、壁打ち相手をしてくれるエンジニア(バックエンド、フロントエンド問わず)も大募集です。

lab.holmescloud.com

lab.holmescloud.com

参考書籍

デザイナーのためのプロトタイピング入門

https://www.amazon.co.jp/dp/B07VYPY7BF/

突破するデザイン

https://www.amazon.co.jp/dp/B073VDYX9J


ディーター・ラムスの「グッド・デザインに必要な10の原則」について改めて考えてみる

こんにちは、Holmesでデザイナーをしています竹内です。
この記事は Holmes Advent Calendar 2020 - Qiita 22 日目の記事です。

今回は、私がデザインをする上で、思考の基準となっている、ディーター・ラムスの「グッド・デザインに必要な10の原則」について、自分の考えを交えながら語っていきたいと思います。

f:id:t-takeuchi-holmes:20201221214553j:plain

ディーター・ラムスとは

ディーター・ラムスは、1950年代ごろから活躍されている、ドイツ出身のインダストリアルデザイナーです。

巨匠です(BraunやVitsœのデザイナーとして有名な方です)。

「グッド・デザインに必要な10の原則」とは、ディーター・ラムスが70年代ごろに定義したデザインの原則です。

グッド・デザインに必要な10の原則

  1. Good Design is innovative. (革新的である。)
  2. Good Design makes a product useful.(良いデザインは製品を便利にする。)
  3. Good Desgin is aesthetic. (良いデザインは美しい。)
  4. Good Desgin makes a product understandable.(良いデザインは製品を分かりやすくする。)
  5. Good Desgin is unobtrusive.(良いデザインは慎み深い。)
  6. Good Desgin is honest. (良いデザインは、誠実である。)
  7. Good Desgin is long-lasting. (良いデザインは恒久的だ。)
  8. Good Desgin is thorough down to the last detail.(良いデザインは首尾一貫している。)
  9. Good Design is environmentally.(良いデザインは環境に配慮する。)
  10. Good Desgin is as little design as possible. (良いデザインは可能な限りデザインをしない。)

語ってみる

「グッド・デザインに必要な10の原則」を自分の考えなりに語ってみます。
私の主観がかなり入ってますのでそこはご容赦ください。

1. Good Design is innovative.

良いデザインは革新的である。

デザインが革新的というのではなく、進んだ技術と常に協力関係にあるデザインということ。 既製品をなぞるではなく、またあえて新奇性があるように見せたものではなく、 発展いく技術とともに進化してくデザインと解釈しています。

革新的ということは、ユーザーを感動させ、そして愛され、それが普遍なものになり、良いデザインへの認識へと発展していくものと思います。(ほんとうは、登場したその時から良いデザインということだとは思いますが、万人へと考えたときに皆がその革新的なものに触れられる機会やタイミングも要素としてあるのではないかと思います。)

この言葉を知る前でしたが、心に残った言葉があります。
すこし昔、NHKのプロフェッショナルという番組で工業デザイナーの吉岡徳仁さんが吉岡徳仁さんが言っていた言葉です。

木の時代に作られた鉄のパイプのイスは、今から見れば普通だが、当時は革新的だったはず。自分も、これから未来では『普通』になるような新しいデザインをしたい

まさにこういうことではないかと思います。 未来では普通になる(定着すること)デザインが、その時点での革新的で良いデザインだと思います。

2. Good Design makes a product useful.

良いデザインは製品を便利にする。

これは読んで字の如しですね。
製品は使われるためにあるもの、実用性がなければ良いデザインとは言えません。

私たちデザイナーの力の発揮どころで、機能を最大化させるのもデザイン次第と言っても過言ではないかと思います。

3. Good Desgin is aesthetic.

良いデザインは美しい。

美しさは製品には必要不可欠。
とくに日常的に使われるものは、心理的な面でも美しくないと長く愛されるプロダクトにはなりません。 古来より美しいものは心を豊かにし、感動を与えるものと考えられているからでしょうか。

美しさとは何かというと、 私は、この10の原則にある以下により構成されるものと解釈しています。

  • Good Design makes a product useful. (良いデザインは製品を便利にする。)
  • Good Desgin makes a product understandable. (良いデザインは製品を分かりやすくする。)
  • Good Desgin is as little design as possible. (良いデザインは可能な限りデザインをしない。)

4. Good Desgin makes a product understandable.

良いデザインは製品を分かりやすくする。

わかりやすくなければ、作ったものの価値は当然半減します。 どんなに機能がよくても使い勝手が悪く、多くの手順を踏むようなデザインは誰にも愛されません。

わかりやすいとは何か、極端にいうと製品自体が語り、説明不要なもの。 目的を達成しやすい導線になっていることが、わかりやすいということだと思います。 10原則の中の Good Desgin is as little design as possible.(良いデザインは可能な限りデザインをしない。) に通じますね。

身近なものでいうと、iPhoneみたいなイメージでしょうか、iPhoneは説明書もほとんどなく、直感的に操作できるので、長い間、愛されているのでしょう。

5. Good Desgin is unobtrusive.

良いデザインは慎み深い。

わかりやすく言うならば、おしつけがましくないということでしょうか。
製品は芸術品や装飾品ではないので、デザインが独り歩きしないことが望まれることと解釈しています。

また、ここは機能にも言えることかと思います。
作り手の想いが強すぎて、プロダクトアウトにならないことも重要で、ユーザーファーストを根底に持つことが大事だということですね。

6. Good Desgin is honest.

良いデザインは、誠実である。

ここは言うまでもないですね。
誇張や、約束できない操作でユーザーを惑わせない。

7. Good Desgin is long-lasting.

良いデザインは恒久的だ。

短いトレンドを反映させた製品は、あまり長持ちしません。
ファストファッションのように、使い捨てのサイクルが早くなってしまい、 何年、何十年と愛されるプロダクトにはならないということと解釈しています。

ここはとても、難しいところです。 デザインはトレンドを追いやすく、ここに陥りやすいのではないかと思います。

個人的な考えですが、最近の WEBデザインのトレンドとして、 フラットデザインからマテリアルデザインがトレンドになっていることは、 個人的には現在はとてもいい流れができていると思います。

余分な要素を取り除き、シンプルに削ぎ落とした最小限のデザインのフラットデザインから、そこに現実世界のルール(奥行きや立体感、質量など)を足すことにより直感的な操作を促すマテリアルデザイン
ここは、この10の原則の以下に当てはまるところだと思います。

  • Good Desgin makes a product understandable. (良いデザインは製品を分かりやすくする。)
  • Good Desgin is as little design as possible. (良いデザインは可能な限りデザインをしない。)

8. Good Desgin is thorough down to the last detail.

良いデザインは首尾一貫している。

曖昧なものを作ってはいけないということだと解釈しています。
曖昧なものは、それがユーザーへの不安につながってしまうということだと思います。一貫していないということは、ユーザーが操作していく上での予測や期待に背いてしまうことになり、ユーザーの体験を悪いものとしてしまう。

9. Good Design is environmentally.

良いデザインは環境に配慮する。

こはちょっと省略します。すみません…

10. Good Desgin is as little design as possible.

良いデザインは可能な限りデザインをしない。

字面だけ見ると、「んんん?」となってしまいそうですが、 これは、ユーザーに目的を達成してもらうために、できるだけその妨げになるものを削っていけば、 Good Desgin makes a product understandable. (良いデザインは製品を分かりやすくする。)につながり、わかりやすいことの実現を可能にするということだと解釈しています。

また、重要でない箇所のデザインに時間をそそいでも、それはユーザーの助けにならず、 ユーザーに余計な時間を使わせてしまうかもしれない、ミスリードを起こすかもしれないとも考えられますね。
双方にとって無駄なエネルギーを生んでしまうのであれば、必要なものに重点をおき、より良いものを作っていくことが大切ということですね。

まとめ

この10の原則に出会ったのは、プロダクトデザイナーを目指していた学生の頃で、改めて振り返ってみると、さまざまな分野に対応できる原則であると感じました。 10の原則は一つひとつが独立したものではなく、何一つもかけてはならない、とても良く考えられた原則だと思います。

ここに出てくる原則は当たり前のことかもしれません。 10の原則を何一つ欠けることなくデザインに反映させることは難しいですが、特に以下の2つには意識を置いて、開発に挑みたいと考えています。

  • Good Desgin makes a product understandable.(良いデザインは製品を分かりやすくする。)

  • Good Desgin is honest. (良いデザインは、誠実である。)

我々の作るプロダクトが、この10の原則を体現し、多くのユーザーに愛されることを考えながら、デザインに取り組んでいきたいと思います。

lab.holmescloud.com

プロダクトマネージャーとしてのヒアリングスキル

こんにちは。Holmesでプロダクトマネージャーをやっている井上と申します。 今回の記事は Holmes Advent Calendar 2020 - Qiita 17日目の記事です。

はじめに

プロダクトマネージャーのスキルには実に様々なものがあります。調べるとよく出てくるのが下記のプロダクトマネジメントのトライアングルにあたるものです。

f:id:yinoue22:20201223202309p:plain
https://productlogic.org/2014/06/22/the-product-management-triangle/

もちろん全て欠かすことのできない重要な要素ではありますが、そのような中でも特に重要なものとして私が考えているのは、「ユーザヒアリング」です。(上記の図でいうところの「User Research」にあたる箇所になります。)

ユーザヒアリングの目的について

何故「ユーザヒアリング」を行う必要があるのか。 それはいかにお客様が抱えている課題を聞き出し理解し、その上で機能として実装するのかどうかを判断するためです。ここはひとつプロダクトマネジメントにとって大きな観点になります。

今回はその「ユーザヒアリング」を行う上で意識すべき点について書いていきたいと思います。

プロダクトマネジメントの文脈で書いてはおりますが、これは必ずしもプロダクト開発のみならず、どんな種類の仕事を行う上でもはたまた私生活にも十分応用できる考え方になります。

なお、内容についてはほとんどこちらの書籍を参考にしているのでご興味ある方がいれば是非読んでみてください。

「対話型ファシリテーションの手ほどき」

悪いヒアリング

『私たちは、「なぜ?」と聞かれるとつい「言い訳」をするようにできているのです。』

いきなりどきっとする記述がこちらの本の中にあります。

ヒアリングにおいて気をつけるべきことはこの一文につきると思います。 なぜと聞かれるとどうしても責められているように人間は受け取ってしまい、ちょっと濁して答えてしまったり言い訳のようなことをいってしまったりついついその場を逃れようとすぐに謝ったりします。皆様もご経験あるのではないのでしょうか。 (かく言う自分も「なんで?」「どうして?」と聞かれることが非常に苦手です・・・) そして本当に聞きたかったことが全然聞くことができなかったということになりがちです。

お客様へのヒアリングにしても往々にしてこういったことが発生しがちだなと思います。

私:「最近なかなかホームズクラウドを利用できていないみたいですね。どうしたんですか?」

お客様:「いや、ここのところちょっと忙しくて・・・」

私:「そうだったんですね、なんで最近忙しくなってきたんですか?」

お客様:「やらなきゃいけない業務もたくさんありますし・・・」

私:「そうですか、それは大変ですね。いつごろなら落ち着いてきそうですか?」

お客様:「うーん、なんとも言えないところですね・・・」

私:「そうですか、ではまた進捗確認しに打ち合わせさせていただきますね。」

上記の通り、実態はなんで忙しかったのか、どうすれば使ってもらえそうなのかといったことが何も分からず終わってしまいました。

おそらくこの調子だと次回の打ち合わせを行っても特に進捗はないでしょう。

青文字で書いてある部分が悪いヒアリングの部分です。その後事実確認をしようと赤文字の質問をしてはいますが、お客様からするとすでにかなり嫌な気分になっていると思われるのでここの回答も曖昧になってしまっていますね。

よく「なぜなぜ分析」をやったけど問題解決にならなかったというのは、なぜと聞くこと自体が本質的に感情に訴えかけているものなので、どこかに感情が入り込んでいるからだと思います。 問題解決のためには「なぜ」を分析すべきだ!というのはよく分かるのですが、上記の通りコミュニケーションが特に重要な場においては逆効果である可能性もあります。 (そもそもなぜなぜ分析は自分が関わる課題に対してやるのがよく、お客様に対してなぜなぜ分析をしたらおそらく嫌われると思っています笑)

良いヒアリング

では良いヒアリングとはなんでしょうか。

「なぜと聞いてしまうと人はついつい言い訳をしてしまう」 ということであれば、「なぜ」「どうして」を聞かずにとにかく、「何」「いつ」「どこ」「誰」を尋ねていくことと本の中にはあります。 そうやって事実確認のみを行いひたすら事実を積み上げていって、何が問題か何が課題なのかをこちらが推測で立てるのではなく、相手に自ら気づいてもらうことです。 そして本当に解決しなければいけない課題が浮き彫りになってきます。

先ほどの悪いヒアリングを良いヒアリングに置き換えるとどうなるでしょうか。

私:「最近なかなかホームズクラウドを利用できていないみたいですね。何かつまづいているところがありますか?」

お客様:「いや、つまづいているというよりは単純に時間がとれていないって感じですね。」

私:「そうだったんですね、時間がとれていないのは具体的にどなたになりますか?営業の方ですか?法務の方ですか?」

お客様:「うーん、主に法務部、というか私が今は立て込んでいてなかなか時間がとれていないですね。」

私:「そうですか、それは大変ですね。何の業務で忙しいんですか?」

お客様:「今は営業からの契約レビュー依頼がとてもたくさん来ているという状況で、、結構困っているんです。」

私:「主に困っている点はでしょうか?単純にレビュー自体に時間がかかるということでしょうか。それとも数が多く来すぎて把握・管理に時間がかかってしまうということでしょうか。」

お客様:「それでいうとまずは部長である私のもとにレビュー依頼は一旦寄せられるのですが、数が多いのとその依頼がメールで来るのでなかなか全体像が把握しづらいんです。ときには抜け漏れも発生してしまいそのことでまた営業から問合せがきて再度やりとりが発生して。。レビュー依頼の把握と担当者への割り降り等が煩雑になってきており、そこの管理に時間が取られてしまっているという状況です。」

私:「そうでしたか、ありがとうございます。」

この通り事実確認を積み重ねることにより、「業務が多忙でホームズクラウドを使っている暇がない」という認識から、業務多忙が実は課題ではなく「レビュー依頼の数が多く管理がしきれず把握に時間がとられてしまう、ときには抜け漏れも発生してしまうなど、コミュニケーションコストも大きく発生している。」という課題を掴むことができました。

そうすると後は、「各方面から来ているレビュー依頼について簡単に把握でき効率的に最適な担当者にさばけるようになる」ということは実現できればこのお客様はホームズクラウドを利用することで課題解決につながり、活用率も向上していくことでしょう。

さいごに

ユーザヒアリングは直接お客様の課題感を感じられる良い機会である一方、きちんと準備をして臨まないと単に時間の無駄になることも多いです。こちらが一方的に聞きたいことだけ聞こうとすると相手は萎縮してしまったり、意図したことが聞けなかったりということもあります。 そこで相手がいかに答えやすい形で事実確認の質問をするかが重要になってきます。

とつらつら書きましたが自分自身ももちろんまだまだ実践できてはいないため、今後も強く意識して頑張っていきたいところです。

参考書籍:「対話型ファシリテーションの手ほどき」

スプリントレビューでプロダクトの価値を高める

この記事は Holmes Advent Calendar 2020 - Qiita 12 日目の記事です。

こんにちは。 Holmesでスクラムマスターをしている吾郷です。

今日は自分が所属するHudsonチームで行ったスプリントレビュー改善について書きます。

背景と課題

Hudsonチームでは現在のプロジェクトに関わるステークホルダーを毎週スプリントレビューに招待しています。 様々な部署からご参加いただき、ステークホルダーの数は今や20名以上となりました。

組織の拡大に伴い参加人数が大きくなっている中で、ステークホルダーに求めていることや参加スタンスの統一が難しくなり、開発側からは「本来のスプリントレビューの目的を達成できていないかもしれない」、また、ステークホルダーからは「実際に何を質問してよいかわからない」といった声も上がっていました。 また、スプリントレビューを含める開発プロセス全体がステークホルダーや開発者内で不透明であることも課題のひとつでした。

そんな中、スクラムマスターが集まる会議で組織として上記のレビュー課題を改善していこうという流れになり、各チームでそれぞれスプリントレビュー改善を行う事となり、今回のワークに至ります。

やったこと

今回のワークは

  1. チーム内での理想とするプロダクト開発の流れの認識合わせ
  2. 現在のスプリントレビューに対する振り返り
  3. 振り返りからいくつか分類分けを行い、本来の理想の姿や大切にしたいことの洗い出し
  4. それを実現するためのTRY出し

といった流れで実施しました。

結果

ワークの結果

f:id:seiseiholmes:20201217191608p:plain 簡単ではありますが、生まれたTRYと解決したい課題を紹介していきます。 PO・SM・開発者それぞれで誰が行うかというところまで決めたTRYが生まれています。

スプリントレビューの目的資料を一枚挟む
  • 担当:スクラムマスター
  • 内容:スプリントレビューの始めにステークホルダーの方に向けて、このイベントの目的や求めていることを伝える。
  • 背景:参加者の方々とスプリントレビューの目的の認識合わせができておらず、何を発言していいかわからないという状況。スクラムマスターがスクラムガイドにある通り、組織へのスクラムの適用を実現する。
PBとFBの状況を共有する
  • 担当:プロダクトオーナー
  • 内容:スプリントレビューの始めに、現在のプロジェクトの概要・今回のスコープ・過去のFBの状態を共有する。
  • 背景:意見が活発にでない理由の一つに、出た意見の状態やどういう扱われ方をしているのかステークホルダーの方に不透明であることが原因ではないかと考えました。そこで、スプリントレビューで明確に伝えることで、意見を言う意義があることを示します。
ユースケースに沿ったデータの作成
  • 担当:開発者
  • 内容:ステークホルダーの方にイメージしてもらいやすいように、登録する登場人物などの情報を具体的なものにしておく。
  • 背景:よく開発内のテストでも、アカウント名を"テスト"としたりすることが見受けられました。その状態でデモを行っても、ステークホルダーの方には、運用イメージがわきにくく、意見も出にくいといったことがありました。

TRYの結果

今回は、TRY実施後の成果指標としてFBの数と種類を各チームで集計し計測することとしました。 まさに、プロダクトの価値向上に寄与するFBをいくつ引き出せたか、いただけるかといったところを指標としました。

約一ヶ月半ほど計測してみた結果です。(Infinity、Trinityは別チームの名称です。) f:id:seiseiholmes:20201217192302p:plain

TOが行き先です。簡単に定義を説明します。
Close・・・その場で回答し、解決したもの
PB・・・プロダクトバックログに追加となるもの
Research・・・プロダクトバックログに追加すべきか調査が必要なもの
Sprint・・・スクラムチームで検討すべきもの

二枚目は、スプリントレビューごとの推移です。 f:id:seiseiholmes:20201217192811p:plain

総計だけでみると判断しづらいかもしれませんが、推移で見るとチームのFBの変化が確認できると思います。 またHudsonでも、PBやResearchの分類も増えてきており、組織としても非常にいい形で動き出したように考えられます。

まとめ

FBを引き出す技術というのは、認識合わせや求めることの共通理解が必要なため大変難しいことだと感じています。 しかし、今回のワークでは改善の方向に進むことができました。 まだまだ開発としては課題も多いですが、チームないし組織として連携し、改善をしていきたいと思います。 実際にチーム間でも、レビュー用のテンプレートを用意したりといった動きもありました。

Holmesでは、スクラムを用いながらプロダクトを成長させ、契約に関する顧客課題解決を通じた価値提供をしていきます。 興味がある方はご連絡下さい。

lab.holmescloud.com

スプリントプランニング〜虎の巻

この記事は Holmes Advent Calendar 2020 - Qiita 9 日目の記事です。

こんにちは。 Holmesでスクラムマスターをしている吾郷です。

今日はチームで行ったスプリントプランニング改善について振り返ります。 また、それにあたって最近アップデートがあったスクラムガイドも参考にしましたので、そちらにも触れながら自身の所属チームのHudsonのスプリントプランニングについて紹介します。

スプリントプランニング改善したい!という意見が出てきたのでチーム内でプランニングの目的や、やることを再定義する機会を設けました。

背景

自分が参加しているスクラムチームはHudsonといいます。 今年の1月からHudsonというチームで活動を続けています。 この一年の間で様々なTRYが生まれ、各イベントやスプリントで実施してきました。

課題

現在、スプリントプランニング内での実施項目が多く、アジェンダが曖昧。 (特にスクラムガイド2017内でいうプランニング二部) そのため、時間が足りなくなり、目的とするスプリントバックログ作成までできていない。

やったこと

スクラムガイドがアップデートされていい機会なので、きちんとガイドに沿うために読み合わせをする。 30分でトピック1からトピック3を読み、それぞれ気づいたことを共有・ディスカッション

結果

今回は、普段使用しているオンラインホワイトボードのmiroに整理したアジェンダを作ってみました。 結果としてはHudsonチームでは以下の分割・内容でプランニングを進めてみることにしました。 時間はトピック1と2に30分ずつ、トピック3に1時間を目安にしています。

f:id:seiseiholmes:20201214180248p:plain

トピック1:Why
プロダクトの価値の提案 from PO

基本的にはスクラムガイド2020のトピック1をそのまま採用しています。 まずはPOからプロダクトバックログの状況などを共有してもらいながら、どういったことがこのスプリントでできるとよいかを提案してもらい、 その提案をもとにスクラムチームでどういうスプリントゴールを設定するか議論します。

スプリントゴール決め(仮)

一通り意見が固まれば、仮案としてのスプリントゴールとして次のトピックに進んでいきます。

トピック2:What
アイテムの選択

直近のベロシティを確認しながら、どのアイテムを選択するかを話し合います。 また必要であればPBIをスプリントのサイズに分割したり、実装についての認識合わせをしたりといったリファインメントも行います。

Hotfix

また、現在HolmesではHotfixチケットについて、専任チームではなく状況に応じて各チームで対応を行っています。 そのため、対応すべきHotfixがなにかの認識合わせも行います。

スプリントレビューフィードバック検討

さらに、このトピック2でスプリントレビューでいただいたフィードバックの対応方針検討も行います。

トピック3:How

ここからは、各スクラムチームで色が分かれるところになると思いますので、参考にしていただけると幸いです。 基本的には、スプリントバックログを作成していく時間になります。 せっかくなのでアジェンダ内のTRYについても少し触れながら流れを説明します。 気になるアジェンダなどありましたら、ぜひコメントしていただければと思います。

モック確認・タスク作成

モックを確認しながら、現時点で必要な作業をまずは付箋に洗い出していきます。 この際、モックも必要なことがわかれば付箋にして作成していきます。

マッスルマーク

一通りの作業を洗い出したら、各曜日の午前午後に自分たちがスプリントに集中できるかどうかを一見してわかるようにマッスルマークというものを振っていきます。力こぶのようなものがそれです。下記画像参考

f:id:seiseiholmes:20201214185157j:plain

クラス名決め

さらにプランニング時点で想定できるクラス名を決めてしまいます。 ここで決めれば都度都度悩む必要がなくなりますし、誰でもすぐに作業に着手できるためです。

SBIの時間ふり

このあと、各付箋に予定時間をmiroのタグ機能を用いて設定していきます。 これによって、各曜日に置く付箋の量などを調整しやすく、 スプリント内における残タスク量も可視化しやすくなり、適応を促進してくれます。

ロードマップ調整

時間まで入力を終えるといよいよ最後にロードマップ決めとなります。 これまで洗い出した付箋にかかれた情報とカンバンをもとに、 一週間の中でどのようにスプリントゴールを達成するかを決めます。

スプリントゴール最終確認

ここで仮に想定していたスコープでは難しい・違ったといった気づきがあれば、量の調整やスプリントゴールの調整を行います。

以上が、スプリントプランニングトピックでHudsonが行っているものです。

まとめ

ガイドラインが新しくなり、自分もチームで一緒に読める機会が持てたのは非常に良かったです。 他のセクションに関しても、チーム内ないし開発内での読み合わせを行っていきたいです。

また、今回のワークでスプリントプランニングに対する共通認識を作れましたが、今後の経験を通してこのアジェンダも変化していくことと思います。 さっそく、定義後のスプリントで実践してみて、トピック3で時間が足らないなどのこれからの課題も見えてきています。

定期的にどういったプランニングをしているか続編としてブログにしたいと思います。

Holmesでは、スクラムを用いながらプロダクトを成長させ、契約に関する顧客課題解決を通じた価値提供をしていきます。 興味がある方はご連絡下さい。

lab.holmescloud.com

Haskellの型を触ってみた

この記事は Holmes Advent Calendar 2020 - Qiita 16 日目の記事です。


こんにちは。Holmesでインフラエンジニアをしている渡辺です。

Holmesでは社内LT大会が何度か開催されていて、趣味の話や技術話など業務に関係あることないことを持ち寄り、みんなそれぞれ好きなことを話しています。自分も発表に参加したので、ここではその時に自分が発表した内容を紹介できればと思います。

エンジニアであれば、自分が好きなプログラミング言語があるという人は多いと思います。自分が好きな言語はいろいろありますが、Haskellが好きなので今回はそれについてのお話です。

型について

大抵のプログラミング言語で扱える型としては以下のような物があると思います。

-- 文字列型
String s = "Hello, World"

-- 数値型(整数)
Integer x = 256

-- 数値型(浮動小数点数)
Double d = 3.14159265

-- 論理型(ブーリアン型)
Bool b = true

-- 配列型
List xs = [2, 3, 5, 7, 11]

通常取り扱うデータとしてはこのような型があれば普通のプログラムを書く分には困らないでしょう。ですが、例えば成功・失敗を表したい時にはどうするでしょうか。関数の結果として返り値で取得したい場合には構造体などのデータ構造を用いて取得する場合もあると思います。もしくは例外処理で対応することも可能でしょう。Haskellでは次のような書き方を使うこともできます。

Maybe型

失敗を返すかもしれない関数の並びから計算を構築できます。失敗はNothingで表現し、成功はJust a (aは任意の型)で返すことができます。

data Maybe a = Nothing | Just a

-- x が 2 で割り切れない場合には失敗する
div2 :: Int -> Maybe Int
div2 x = if even x
            then Just (x `div` 2)
            else Nothing

使用例は下記の通りです。ghciでの実行例になります。

ghci> :t Just 123
Just 123 :: Num a => Maybe a

ghci> :t Nothing
Nothing :: Maybe a

ghci> div2 6
Just 3

ghci> div2 3
Nothing

Either型

失敗あるいはエラー処理を構造化する例外処理をつかう関数のならびから計算を構築できます。失敗時にもただ終了するのではなく、エラーの内容から次のアクションを設定することができます。

data Either a b = Left a | Right b

head' :: [a] -> Either String a
head' [] = Left "empty list"
head' (x:xs) = Right x

使用例は下記の通りです。

ghci> :t Right 123
Right 123 :: Num b => Either a b

ghci> :t Left "failure"
Left "failure" :: Either [char] b

ghci> head' [1,2,3]
Right 1

ghci> head' []
Left "empty list"

さて、通常の型の使用方法としてはこれぐらいにして、もっと型を駆使して面白いことはできないでしょうか。

型レベル計算

Haskellは型の表現力が高く、型レベル自然数という物が扱えます。

まずは下準備として、今回の記事の書き方を使うにあたって必要なGHCの機能を有効化します。

{-# LANGUAGE FunctionalDependencies, MultiParamTypeClasses, UndecidableInstances, FlexibleInstances #-}

型でペアノ数を表していきます。Z は 0 を表します (zero)。S は (+1) を表します (successor,後者)。S Z は 1 、 S (S Z) は 2 という意味になります。

-- ペアノ数の定義
data Z
data S a

型クラスとそのインスタンスで関数を定義しています。

-- 型レベルの演算として加算を定義
class Add a b c | a b -> c

-- 0 + a は a になる
instance Add Z a a

-- a + b の結果を c に入れる
instance Add a b c => Add (S a) b (S c)

足し算(add), zero, oneについては型のみで表現し、two, threeについてもそれらの組み合わせでできています。

add :: Add a b c => a -> b -> c
add = undefined

zero = undefined :: Z
one = undefined :: S Z

two = add one one
three = add one two

ここまで書くと実際に型での計算が確認できるようになります。

ghci> :t one
one :: S Z

ghci> :t two
two :: S (S Z)

ghci> :t three
three :: S (S (S Z))

というわけで、型をうまく扱うことで型の上で数字の取り扱いができるようになりました。 今回の内容ではあまり高度な例とも実用的な例とも言えないかもしれませんが、型の表現力の一端は感じていただけたのでは無いでしょうか。

感想

業務では使用していないプログラミング言語なので難しかったという声はありましたが、内容を理解したうえで面白かったと言っていただけたり、Haskell関数型言語に興味を持ってくれた人がいたのでとても有意義で楽しい社内LT大会になりました。

最後に

Holmesはエンジニア・デザイナーを募集しています。 興味がある方はぜひこちらからご連絡ください!

lab.holmescloud.com

lab.holmescloud.com