Appiumの環境構築を劇的に効率化した話

Mercari Advent Calendar 2018 の7日目の記事になります。

メルカリの自動化&品質保証グループ(Automation & QA Group:通称AQA)の @AHA_oretama です。
私は普段、テスト自動化やCI / CD を主に行っています。

今回は、Appiumの環境構築をインストール用のシェルを作成して劇的に効率化した話をしたい、と思います。

全員自動化という目標と、それを進める上での課題

全員自動化について

AQA グループでは現在、QAエンジニアも含めてグループのすべての人が自動テストに関われるように、「全員自動化」を目標に掲げています。

いままでは、自動テストに関しての情報がAutomationエンジニアからQAエンジニアへうまく共有されてなかったこともあり、QAエンジニアが自動テストの内容をあまり把握できていませんでした。
その結果として、QAエンジニアが自動テスト化されているテストをマニュアルテストで行ってしまったり、逆に自動テスト済みと思ってマニュアルテストをしなかったが、実はそこまで自動化されておらずにテストされてなかった、というようなことも発生していました。

「全員自動化」の効果として様々なものを期待していますが、その一つがAQAチームとして自動化を進めることで、テスト自動化を自分ごととして捉えてもらうことだと考えています。
テスト自動化を自分ごととして捉えてもらうことで、上記のようなことは起きなくなる、と考えています。

「全員自動化」については、以下のスライドも見てもらうとより理解が進むと思います。

全員自動化を進める上での課題

その「全員自動化」ですが、自動化を始めようとした場合、まず環境構築をしなければなりません。

いままでは環境構築に関するドキュメントがあり、それを見ながら各自が手動で進めていっていました。
人によっては、(別作業と並行したり、手順書を読み間違えたり、環境構築の問題にハマったりして)環境構築で1〜2日もの時間が取られてしまっていることがありました。
また環境構築中に問題が発生した場合、周りのメンバーがフォローしなければならず、実質的にはそれ以上のコストがかかっていました。

少し話は変わりますが、今後、メルカリはエンジニアを1000人に増やすという公言(MTC2018 – Microservices Platform at Mercari – Speaker Deck)していて、AQAグループも日々仲間が増えている中で、このままの方法ではスケールしないことも目に見えていました。

そのため、環境構築をいかに簡単にして、時間を節約できるか、そして「全員自動化」へのハードルをいかに下げるかが重要な課題となっていました。

環境構築の検討

最近であれば、環境構築を簡略化するとなれば、Dockerでしょう。
当初、私もDockerを使い、以下のような構成で実現できないか、を検討しました。

f:id:AHA_oretama:20181205142438p:plain
Docker – Appium 構成(検討段階)

しかしながら、以下のような理由でDockerによる環境構築の簡略化は現実的ではありませんでした。

  • Docker For Macの場合、USBからDockerコンテナへのアクセスはできない(Link
  • Docker-AndroidはMac上にUbuntu OSのVirtualBoxを立てる必要(Link)があり、その上でDockerを起動し、Docker内でAppiumやテスト実行を行うため処理速度の懸念が大きい

そこで、Dockerを使わずに、ローカルPCにAppiumの実行環境を自動で整えるように方針転換しました。

そうした場合、以下の2つの選択肢が候補に上がりました。

  • シェルでAppiumの実行環境に必要なものを設定する
  • AnsibleやChefのような構成管理ツールを使用してAppiumの実行環境を設定する

今回は、そこまで複雑なものにならないという予想があったため、またメルカリのPCは幸いすべてMacに統一されていたためシェルで作りました。
今後、必要があればAnsibleなどの構成ツールを使用した方法へ変更するかもしれないです。

シェルの実装

冪等性(べきとうせい)の担保

今回のシェルでは、何度実行しても同じ状態になる(冪等性)ように作成しました。

例えば、homebrewをインストールする場合、既にインストールされている場合インストールは行わないようにすることで、結果としてこのシェルの実行後はhomebrewがインストールされている状態になるようにしています。

if [[ ! "$(which brew && brew help)" ]]; then
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
fi

バージョンの統一

AppiumやAndroidで使用されるNode.js、Java、Ruby(メルカリはAppiumのテストコードをRubyで記述)などは、
anyenvndenvjenvrbenv をインストールし、リポジトリ上の.node-versionなどのファイルにバージョンを記載することでバージョンを統一しています。
またそれらのライブラリはそれぞれの言語のパッケージマネージャで管理することでバージョンを統一しています。

例えば、Node.jsであれば、.node-versionでNode.jsのバージョンを固定し、package.jsonpackage-lock.jsonとnpmを使用してライブラリのバージョンを統一しています。

version=$(cat ./.node-version)
if [[ ! "$(ndenv versions | grep ${version})" ]]; then
ndenv install "${version}"
fi
npm install

上記のようにシェルを記述することで、仮にNode.js、もしくはライブラリのバージョンをアップデートした場合も、(リポジトリをPull後に)このシェルを実行するだけで新バージョンがインストールされるようになります。

その他工夫した点

また上記以外にも工夫した点として、

  • パスワードなどの秘匿情報は、ユーザにインプットしてもらい、シェル上には保存しない
  • 手動でインストールしなければならない場合、ユーザがインストールに迷わないようにメッセージを出す

などがあります。

例えば、メルカリではJFrogを社内専用に立てているのですが、ここからライブラリを取得する場合はユーザごとにユーザ名とAPIキーを入力してもらう必要があります。
そのユーザ名とAPIキーはJFrogにログインすることで確認できるので、
シェルで対象のURLをブラウザで開き、ユーザからの入力を待つようにしています。

    open "${ARTIFACTORY_URL}"
read -p "$(tput setaf 3) Input your username diplayed above right corner in JFrog site (sign in with Google) :$(tput sgr0)" username
echo "${username}"
read -p "$(tput setaf 3) Input your apikey which is diplayed by clicking your username in JFrog site :$(tput sgr0)" apikey
echo "${apikey}"
bundle config https://xxx.jfrog.io/mercari/api/gems/gems "${username}:${apikey}"

インストールのシェルを導入してみて

このインストールのシェルを導入することで、インストールの時間は大幅に短縮でき、1〜2日かかることもあった環境構築の時間が1〜2時間ほどに短縮されました。
(AndroidSDKなど、どうしてもダウンロード時間はかかってしまうため、数分では終わらないです。)
環境構築のためのドキュメントは1〜2行のコマンドに集約されることで、手順ミスもなくなりました。
結果として、この取り組みで、今回の目標であった「全員自動化」へのハードルを下げることができました。

また今までは各自が使用していたバージョンも異なっていることもありましたが、
このシェルを使用することで、統一され、バージョンアップも容易になりました。

最後にこのシェルを導入して苦労した点も紹介しておきます。
1例としては、ローカルPCに既にいろいろなものをいれている場合は、シェルの実行中にエラーが発生することがときどきあり、そうしたときは原因と対策のためのフォローが必要でした。
(各インストールコマンドはなるべく公式のコマンドを採用しているため、エラーを検索すればある程度すぐに対処方法を知ることができました。)

最後に

12/11にMercari AQA Pop Talk #4をやります。英語でのセッションとなりますが、興味がある方はぜひ参加してみてください!

www.meetup.com

明日 8 日目の執筆担当は @hidenorigoto です。引き続きお楽しみください〜

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加