Figma Organization Planでデザイン🎨しよう!(セキュリティ編)

こんにちは、7月に入社したUIデザイナーのよつくらです。
ANDPADではすべてのプロダクトで、UIデザインツールとしてFigmaを採用しています。

ANDPADのセキュリティ強化の一環として8月頭にFigma Organization Planを検討しはじめ、8月下旬には導入できました。Organization Planはなかなか欲しい情報が無いことも多いので、この記事に導入前にセキュリティ面で気になりそうなところをまとめてみたいと思います。

* 2020年9月時点でのFigma Organization Planの仕様について記載します。最新の仕様に関しては公式FAQ等をご確認ください。
* Figmaのプランごとの機能差についてはこちら
* Organization PlanのAdmin向けのガイドはこちら

👍 SSO(シングルサインオン)が利用可能になる

FigmaをOrganization Planにするとシングルサインオンが利用可能になり、会社のメールアドレスとパスワードでFigmaを自動的に利用開始できます。またこれによって退社したメンバーが自動的にFigmaにアクセスできなくなります。
ANDPADもこの機能をメインの目的にOrganization Planの利用をはじめました。
help.figma.com

またANDPADは社名変更に伴い、メールアドレスのドメインが複数存在していたのですが、Figma側のサポートをいただき、SSO対象のドメインを追加することができました。

👍 Teamを分けることで業務委託のメンバーにも安心して共有

ファイル単位やプロジェクト単位で、共有メンバーを増やしていくと、どこまで誰に共有しているのか管理が難しい...というのがProfessional Planあるあるだと思います。
ANDPADで現在落ち着いた運用としては、業務委託メンバーにもEdit/ViewしてほしいプロジェクトについてはTeamを分割し、分割したTeamに業務委託メンバーをゲストとして追加する方法をとっています。
help.figma.com
分割したTeamに対しては、AdminがTeam Librariesを有効にすると、分割した先のTeamでも、Organization Plan導入前と同様にコンポーネントを流用することができます。

👍 FigmaのURLの公開範囲を安全なものにできる

Professional Plan以下のプランでは、ファイルのURL公開を以下のどちらかの設定にして共有していると思います

  • Anyone with the link [can view/can edit]

 └(リンクを知ってる人なら誰でも)

  • Only people invited to this file

 └(ファイルに招待された人のみ)

Organization Planでは以下の共有範囲を設定できます。

  • Anyone with the link

 └(リンクを知ってる人なら誰でも)

  • Anyone at Organization with the link

 └(組織内でリンクを知っている人のみ)

  • Anyone at Organization

 └(組織内誰でも。ライブラリファイルなどに有効とのことです)

  • Only people invited to this file

 └(ファイルに招待された人のみ)
help.figma.com
この中で、「Anyone with the link」は、ドメイン外のユーザーにFigmaを共有出来てしまうという意味で最も危険な選択肢ですが、Organization PlanではなんとAdminがこれを無効にすることができます🎉 (ANDPADでもオフにしてあります👍)
f:id:syotsukura:20200923192646j:plain

この機能と、前述のTeam分割により、リンクが一人歩きしてファイルが外部から見えてしまう可能性がなくなります。

🤔 Slack通知ができない

と、ここまでアップグレードすることで非常に便利になることを説明したFigma Organization Planですが、一点だけ困ったことがありました。
Professional Planでは使用できていたSlack通知がOrganization Planだと現在使用できないようです。


プロジェクトによって、Figma上のコメントでコミュニケーションをとっていたチームもちらほらあったようですが、これは仕方なくコンフルエンス等別のツールでコミュニケーションをとってもらうように変更しています。

さいごに

ANDPADに入社する以前からOrganization Planは使ってみたかったものの、情報が少なく当時はなかなか導入までは至りませんでした。まだ入社して3ヶ月も経っていませんが、ANDPADではスピード感を持って皆のアイディアを具現化することに積極的に投資してもらえる環境だと実感しています。

ANDPADでは、今回導入したFigma Organization Planを使って、一緒にプロダクトをつくりあげていくUIデザイナーを積極的に募集しています!興味がありましたら、ぜひ採用サイトをご覧いただくか、ハードルが高ければお茶をのんでお話しましょう🍵三
hrmos.co

朝の歯磨きのような10min勉強会

こんにちは、自宅でのリモート環境が整って音楽制作が捗りそうな soe-j です。

アンドパッドには5月に入社しました。
入ってすぐ「良い取り組みだなあ」と思ったのが、毎朝開催されている「10min勉強会」でした。
いろんな企業さんで行われているかもですが、今回はアンドパッドではどんな感じで実施されているのか紹介できればと思います。

毎朝の文化

現在のタイムテーブルはこんな感じ。
毎日、朝会が始まる11時の直前まで開催されています。
なるべく時間が被らないように開催されるので、気になるものを選んでハシゴすることもできます。

  • データ分析 9:00〜
  • k8s 9:30〜
  • Vue.js 10:00〜
  • Flutter 10:30〜

30分置きなのはバッファで、これが詰め込む限界かと思います。 (9時前も空いてるじゃないかって?)

以前には、Monolith to MicroServicesというテーマがあったり、Reactを触ったり....
他にも、10分とは銘打ってないですがClean Architecture勉強会があったり、「建設業界について」のようなテック以外の勉強にも派生してきています。

自然発生的に発足するので、捕捉しきれてないものもあるかもしれない...
ということで、最近はGoogleカレンダーに「勉強会カレンダー」なるものが誕生しました。

もはや、文化といっても過言ではないかもしれない。

最近の実施の流れ

会によって少しずつ違うとは思いますが、私がよく参加しているVue.js勉強会を例に流れを説明します。

担当者はローテーション。

  1. おはようございます
  2. 担当者が画面共有して、ざっと書いてあったことをまとめながら読み上げていく
  3. 気になるところを議論
    • これはどういうときに便利?
    • これは便利だけど注意点は.....
    • こういう実装なのはなぜ?
    • 書き方色々あるけど、どう書きわけていく?
  4. 明日の範囲と担当者を確認
  5. ありがとうございました

なぜ10min勉強会なのか

業務においても新しい技術を積極的に採用しているので、その中で得られるものが沢山あるし、個人で勉強することもあるし....
それでもなぜ毎朝10分の勉強会をやるのか。

行動のフックに

買った本って積むものですよね。
取り組もうと思っても取り組んでないことって結構いっぱいあったりするんじゃないでしょうか。
「明日の朝までに勉強しておかないと議論に参加できない」という背水の陣

無理なく続けられる

背水の陣と言っても10分で終わる内容なので、さっくり見るだけです。
週イチの勉強会の予習が重くて....とかなりません。

すぐ聞ける、深く理解できる

これは勉強会全般に言えることですが、理解に躓いたところを議論することができます。
ただ、毎日やってるので気になったところをすぐに聞ける感覚があります。
こまめに聞けるので深く理解した上で、次の単元に向かうことが出来ます。

結果、習慣化される

私自信、業務で直面していることしか勉強しない傾向が強く、
新しい技術のキャッチアップに課題を感じていました。

こうした取り組みから、少しずつ習慣になってきている実感があります。
Vue.jsの内部実装を読んだことで、computedとmethodの理解が深まったことは印象に深く残っています。

おわりに

こんな勉強会に興味ある方、ぜひ一緒に開発してみませんか?

engineer.andpad.co.jp

Autifyを導入して3ヶ月経ったので振り返ってみる

はじめに

はじめまして。QAエンジニアの佐藤です。
最近、Slackのアイコンを "ピカチュウ" から "ミミッキュ" に変更したのですが、複数人から「闇落ちしたの?」と心配されてしまったため、ミミッキュの認知度をあげていかないとなぁと思っています。笑
www.pokemon.co.jp


さて、今回はコードを書かずにテスト自動化できるプラットフォーム、Autifyを導入して3ヶ月経ったため振り返ってみたいと思います。
Autifyとは、ブラウザ上での操作を録画し、それをシナリオとして作成してくれるテスト自動化プラットフォームです。
autify.com

導入した背景

ANDPADの定期リリース後、開発者が主要動線テストを行っているのですが、フロントエンジニアの方々から

  • リリースのたびに開発者の工数を使っている
  • 毎回同じテストなので自動化したい

という声があがったのがきっかけでした。
f:id:Mimikkyu-oct:20200916214742p:plain

Autifyの

  • 一ヶ月間トライアルのキャンペーン中だった
  • テストコードを書かなくてもテスト自動化できる

という点から、まずは試してみようということで、Demo Webinarを開催していただくことになりました。
Webinarには、興味のあるエンジニアが任意で複数人参加し、質疑応答なども活発に行われました。
活用イメージが湧いたためトライアル契約することが決まりました。

トライアル期間から本運用まで

Autifyをトライアル導入するぞ! となってからはざっくり以下のスケジュールで進めました。

  • 6月 - トライアル
    • 簡単なシナリオテストを作成し、Autifyに慣れる
    • シナリオ作成時のルール決め
    • 毎時定期実行で安定性確認
  • 7月 - 契約
    • シナリオの拡充
    • 本番運用に乗せるシナリオの選定
    • 毎日定期実行で複数ブラウザの安定性確認
  • 8月
    • 一部のシナリオを本番運用開始

f:id:Mimikkyu-oct:20200916213236p:plain

E2Eテスト自動化に関わるメンバー全員がテスト自動化未経験だったため、ANDPAD技術顧問の @tarappo さんの助言をいただき、主に以下のことを意識、実行しました。

  • トライアル期間中は、スモールなテストを作って毎日実行する
  • 安定性を確認してから運用に乗せる
  • 入力値はユニーク値とする
  • E2Eは運用コストが高くなるので、代表値を確認するに留める
  • テストケースが増えがちなことを念頭においておき、運用コストが上がらないことを重要視する
  • どこの機能に対して、どのテストが有効かを確認した上で設計する

メリット・デメリット

Autifyを導入して3ヶ月間で感じた、よかったこと・よくなかったことをまとめてみました。

メリット

  • 作成・実行したシナリオテストに対してキャプチャがあるので、何をテストしているかがイメージしやすい
  • エンジニアだけではなく、QAや他のチームも巻き込んで運用できる(ソースコードを読む必要なし)
  • テスト実行がうまくいかないときに気軽にサポートに問い合わせできる

デメリット

  • Linux/chrome以外の並列実行がデフォルトでサポートされていないため実行に時間がかかる *1 *2
  • 実行環境依存の不安定さがある
  • シナリオの並び替え・フォルダ分けができない(運用に対しての手間がかかる)

メリットもデメリットもどちらもあるので、日々どうやったらコストをかけずに最大限の価値を発揮できるかを考えています!

メリットにあげたシナリオの作成画面ですが、このようになっています。
f:id:Mimikkyu-oct:20200916233952p:plain
パスワードはマスクして表示されます。
ステップをクリックすることで、入力値の変更も可能です。
画面操作の録画を行うと、このようにキャプチャと操作をシナリオとして作成してくれるので、とっても便利です。
このシナリオを実行した結果がこちらです。
f:id:Mimikkyu-oct:20200916233806p:plain
実行結果もキャプチャ付きで表示されます。
失敗があるときは失敗理由も表示されるためキャプチャをみて、どこが失敗しているのかを一目で確認することが可能です。

テストを実行した後は、実行結果がSlackに通知されるように設定しています。
f:id:Mimikkyu-oct:20200917134720p:plain
Slack通知が来ることで、テスト終わったかな?とAutifyの管理画面へ実行結果を見に行く手間が省けるため役立っています。
失敗した件数も表示されるため、失敗がある場合はすぐに確認するようにしています。


デメリットであげたシナリオの管理についてですが、並び替えやフォルダ分けが現状はできません。作成順に並んでいます。
f:id:Mimikkyu-oct:20200916232817p:plain
そのため、先頭に「画面名をつける」というルールとし、検索ボックスで検索できるような運用にしています。
また、テストプランとして画面ごとにシナリオを作成するなど工夫しています。
こちらはAutifyのロードマップに掲載されていたため今後改善されると思いますので、楽しみに待ちたいと思います(`・ω・´)

テストを実行した後、chromeでは成功していたけど、Edgeでは失敗している、というケースが稀にあります。
現状シナリオの不備や、本番環境でも失敗しているような事象ではなく、Autify環境での失敗であることが多いです。
f:id:Mimikkyu-oct:20200917140709p:plain
"不明なエラー" として失敗してしまったり、"Javascriptでエラーが発生" して失敗してしまったりします。*3
この場合は、再度実行をしてみます。
それでも解消しない場合は、「サポートを受ける」ボタンから問い合わせを行っています。
問い合わせを行った結果、改善していただき、少しずつ安定してきている状態です。(ご対応感謝しております🙇‍♀️)

さいごに

現状は、当初目標としていた主要動線テストの1/3を自動化できましたが、今年中には1/2以上は自動化していきたいと思っています。
エンジニアの方々も、私QAも、E2Eテストだけを対応しているわけではないので、まだまだやりたいのにできていないことはたくさんあります。
限られた工数の中での対応になってしまうので、運用コストをどれだけ下げられるかをAutifyに期待しています(^^♪
この3ヶ月でひとまずAutifyの知見は深まっていますので、これからもどんどん活用していきたいと思います!

ANDPADでは、一緒に働く仲間を募集中です!テスト自動化にも興味がありましたらぜひ採用サイトをご覧ください。
engineer.andpad.co.jp

*1:WindowsServerも並列実行をサポートしているが、まだ本運用にのせていないためLinux/chromeのみにフォーカスをあてています

*2:有料で並列数を増やすことが可能

*3:"Javascriptでエラー"は、シナリオ内にJSステップを追加している際に発生しています

CodeBuildでRSpecのテストレポートを表示する

はじめまして。サーバーサイドエンジニアの kinakobo です。

唐突ですが、自動テストの実行にはどんなCIツールを使用していますか?

色々と選択肢があると思いますが、自分は今までCircleCI、GitHub Actionsを使うことが多く、ANDPADに入社して初めてCodeBuildでテストを実行しました。
それまでCodeBuildを使ったのはDocker imageの構築くらいだったので、あまりテストの実行に向いている印象は持っていませんでした。

ですが調べてみると意外と機能が充実しており、中でもテストレポート機能は便利だと思ったので今回紹介したいと思います。

テストレポート機能とは

AWS CodeBuild でのテストレポートの使用 - AWS CodeBuild

テストレポート機能は、テストのレポートファイルをいい感じに整理して表示してくれる機能です。 CircleCIにも似たような機能があるので、使ったことがある方はイメージつきやすいかもしれません(テスト メタデータの収集 - CircleCI

また、テストのレポートだけでなくコードカバレッジのレポートも最近表示してくれるようになりました。

以降はテストレポート機能のうち、テストレポート、コードカバレッジレポートに分けて順番に紹介していきます(名称がややこしいですね)

続きを読む

#アンドパッド #EMインタビュー

f:id:nakano88:20200819233902p:plain

はじめまして。アンドパッド人事の中野です。
アンドパッドの開発部は昨年から1年で倍の組織となり、今年の4月と5月にEMが入社し採用面接など対応することが増えてきました。
今後このTech Blogへの投稿やイベント登壇なども行っていく予定ですが、もっとたくさんの人に知っていただきたくインタビューをしてきました。

-本日はよろしくお願いします!まずは、お二人のいままでのキャリアを教えてください!

早田:学生の頃は、公務員になりたいと考えていました。結局は公務員に受かったのですが「やっぱり違うな」と感じる部分があって法律系の専門学生から、SIerへエンジニアとして入社しました。それまでの人生で自分がエンジニアになるとは思ってもなかったのですが(笑)友人がエンジニアになると聞いて「なにそれ、カッコイイ!」が最初の動機です。

f:id:nakano88:20200820000019j:plain
-そこからエンジニアとしてのキャリアがはじまったんですね。

早田:最初はperlJavaの開発を行うことになりました。開発自体がはじめてで、とても楽しかったのですが自分の作ったものを皆に使ってほしい、見てほしいと思いはじめ、3年勤めた会社を退職しソーシャルゲームの会社へ転職しました。Rubyで開発をしている会社で、メンバーが少人数のときに入社したので割と何でもやらせてもらえる環境でした。触ったこともないflashでのアニメーションを急に振られて必死にキャッチアップしたこともありますし、シナリオを書いたりと本当にたくさんの経験をさせてもらいましたね。

-すごい!シナリオまで、書かれていたんですね・・・!

早田:次の仕事は個人の能力だけでなくチームでの開発をしっかりと考えている会社を探そうと考え、特に業界は絞らず色々な起業に話を聞きに行きました。実は学生の時に祖父の手伝いで大工のバイトも短期でやったことがあり、アンドパッドの事業内容はイメージが沸きやすく、マネジメントもプレイヤーもやりたいというわがままも叶えられそうという点が最終的な決定打となり、入社を決めました。

-続いて、土方さんのキャリアも教えてください!

土方:私は学生の時に人材派遣会社でアルバイトをしていたのですが、その会社に声をかけてもらい社内SEとして入社することとなり社会人生活が始まりました。そこからエンジニアとして経験を積み、KDDIのグループ会社にバックエンドエンジニアとして転職しました。ちょうどスマホが普及してきたタイミングで、フロントエンドに携わりたかったのですが会社の事情もあってなかなか携わる業務ができなかったのでソーシャルゲームの会社へ転職。そこではこれでもかってくらいガチャを作りましたね(笑)そういう時代でした。

f:id:nakano88:20200820000051j:plain
-ちょうどソーシャルゲームのバブル期ですね!

土方:そこでスマホにも携わることができたので、KDDIのグループ会社に出戻りしたのですが、”キャリアの中”でやっていくということに疑問を持ち始め、転職活動をすることにしました。その中でもオンラインとオフラインが繋がって仕事のできる事業に興味を惹かれアンドパッドへジョインすることを決めました。

面接は婚活!

-今はアンドパッドではどういう役割なのでしょうか?

早田:実は私の役割はちょっと社内でも特殊で、テックリードとEMを兼務しています。
テックリードとしては引き合い粗利管理の新機能の開発や設計を、EMとしては面接対応にはじまり、社内の組織や文化構築にあたって施策を考えたり実行しています。最近ではインタビューを受けたりなど社外向けの記事にも登場しています。
findy-code.io

土方:タスク管理とアプリの管理を主に担当しており、プロジェクトマネージャー的な立ち位置で動いています。主に定例のMTGをとりまとめたり。開発している皆が開発に集中できる環境を作りたいと思っており、稟議・社内ルールなど開発以外にある細かいことはすべて引き取るつもりです。
あとは、採用など仲間あつめをはじめとした、組織づくりに力をいれていきたいと考えています。CTO金近・CDO山下が技術面でリードしているので、私たちは組織面をVPoE下司と共にリードしている形ですね。
flxy.jp

-最近だとカジュアル面談を多く担当されていますね!

早田:そうですね、面接・面談は婚活と同じだと思っているのでアンドパッドの魅力を伝えたり今の課題感など包み隠さずお伝えしています。面談に応じていただける方は、少なからずアンドパッドに興味を持っていただいていると思っているので、面談での期待値を伺ってから会社について深くお伝えするのか、技術について深くお伝えするのかなどアレンジしながらお伝えしています。

土方:面談の場で、合否の判断は特にしていないので他社さんなどと比較している場合にはぶっちゃけて質問をしていただだけた方が答えやすいですね。せっかくお互いの時間を使っているので「応募したい」と思うまでのボトルネックがあれば、なるべく潰してもらいたいです。極力なんでもお話しできるように心構えしているので、ぜひなんでも聞いてください!

-面接や面談で多い質問などありますか?

早田:最近は、リモート勤務についての質問も多いです。コロナウイルスの影響で今は皆リモートで働いていますが、今後はどうなるのかなどは多い質問のひとつです。アンドパッドとしては、リモートの制度がない中で、情勢動向を見ながら臨機応変にリモートワークに移行ができています。オフィス環境も密にならないようレイアウト変更も随時行っていたりと、今後についても前例のないことなので、しっかり動向を追いながら対応をしていくことをお伝えしています。

土方:あとは開発体制についても、よくご質問いただきます。現在チームは機能ごとに分かれているのですが、チームによって開発体制は異なっておりアジャイルのチームもあれば、ウォーターフォールのチームもあります。職種もフロントやバックエンドにこだわらずフルスタックで活躍できるのかということも質問いただきますね。入社する前からそれを確実に約束することはできないですが、しっかり担当領域で信頼を勝ち取ればもちろん別の領域にスキルを伸ばしていただくことも可能で、それを叶えたメンバーもいます。また、バックエンドは主にRailsで開発していますが、最近では一部Goで開発もしておりSREからバックエンドエンジニアになった人もいますね。フェーズによっても異なるので詳しくは直接お伝えしたいなと思っています。
施工管理チームも真のスクラムを目指して - ANDPAD Tech Blog
Kubernetesがコンテナイメージのダウンロードに失敗する原因を探る - ANDPAD Tech Blog

まだまだ組織拡大期。変化に対応できる人と働きたい

-どういう人がアンドパッドに合うと思われますか?

早田:カルチャーフィットは重要だなと思っていますね。考え方についてはお互いが不幸にならないためにも、しっかり確認しています。チームで開発したいのか、個人で開発したいのかを過去の経験を踏まえて伺ったり、社内での役割分担、スピード感を持って開発したいのか・1つのことをとことん突き詰めて開発したいのかなど、キャリアの考え方など伺って今のアンドパッドで叶えていただけるのかどうかはすり合わせしています。特に今は急成長フェーズなので、その変化への対応をポジティブにとらえてくださるかも大事なポイントですね。

土方:アンドパッドの6バリューに基づいて、当てはまる部分があるかどうかは大事にしています。例えば、「Mission Driven」などは今までのご経歴の中でやってきたことを深堀りして伺い、問題解決をどういう立場でどうやって行ったのかなどを伺うと仕事に対する向き合い方などが分かるのでよく伺いますね。問題から学んでどれほど身に着けているのか、どこまで考えて設計をされてきたのかなどは働く上でのスタンスも知れると思っています。
andpad.co.jp

-EMとして、エンジニアとしてこだわっていることなどあれば教えてください。

早田:開発者としてもマネジメントをする身としても、私は技術ありきの存在だと思っています。技術力がないEMにマネジメントされることは不都合が多いので、私は一番に尖った人物ではありませんが技術をしっかりと追いかけ、開発にもマネジメントにも活かせるように心がけています。

土方:個人的には、熱血漫画家十訓はエンジニアにも通ずるものがあるなと思っていて、忘れないように心掛けています。面談や面接時にも「当てはまるところはあるかな?」と考えながら質問などさせてもらってます。
※熱血漫画家十訓とは漫画家島本和彦先生の名言

ありがとうございました!

さいごに

アンドパッドでは、エンジニアの募集を行っております。
まずはカジュアルにお話ししましょう。ぜひお気軽にエントリーいただければうれしいです😉
hrmos.co

iOSのWebViewでUIテストが安定しない - Bitrise / Firebase Test Labで検証してみた

ANDPADでモバイルアプリエンジニアをしている @kanari3333 です。

初日にGitHubのパスワードをど忘れして、社内では本名で活動していましたが、これを機に覚えて頂ければと思います。GitHubも移行していきたいです (規約的にも)

ANDPADのアプリ開発では、UnitTestはもちろんUITestにも力を入れています。
今回は、iOSのUITestを実装していく中で遭遇した辛い事案を紹介したいと思います。

概要

  • iOSのWebViewのUITestは、要素が取得できないことがある
  • Simulatorはテストが安定しない
  • 特に最新のOSで顕著

この記事では検証用のサンプルアプリを作成し、BitriseでSimulator / Firebase Test Labの実機テストを回し検証していきます。

まえおき

ANDPADのiOSアプリでは、CI/CDとしてBitriseをメインに利用しており、
UITestにはFirebase Test Labの実機テストを利用しています。

ある日、社内の検証端末を使いテストを実装し、ローカルで問題無かったのでpushしました。
しかし、Bitriseのテストは何度回しても失敗していました。
ログを追ったり、Firebase Test Labの動画を追ったりしたところ、どうやらWebViewを利用した画面では、iOSのversionによってUIテスト時に要素が正しく取得できないバグがあることが分かりました。

この場合は、iPhoneX (iOS 13.3) では「送信」ボタンが押せるのに、
iPhone11 Pro (iOS 13.1.3) では「送信」ボタンが見つからずテストが落ちるという現象が発生していました。

この件に触れた記事は見つからなかったので、頭の片隅に入れておいて頂ければ幸いです。

影響範囲

UITest時にElementsが参照できないバグがありますが、実際の利用では正しく動作するようです。
テストの信頼性は落ちますが、プロダクトへのダイレクトな影響はないと思います。
(手動テストが必要という意味では影響大ですが…)

原因

XCUITestでは、対象アプリとは別に、XCTRunnerアプリからUIテストを実行しています。
アプリ内部に直接アクセスできない為、画面要素が取得できたり、できなかったりという現象が発生していると考えられます。
iOS SDKのバグですね。versionが上がると直るというより、上がることで不安定になることもある印象です。
AppleはWebViewのUITestを重要視していないということでしょうか。

また、iOS 13.3.1ではiOS 13.3.0で発生していたUITestのバグが修正されました。
developer.apple.com

テストフレームワークの信頼性がないとどうなるか

動的に生成される画面

種別により表示する項目が違う場合というのは多々あります。
テストしたいWebViewの画面が動的に生成されるページだと、想定の要素が表示されていないのか、テストが不安定なのか分からず目視で確認することになります。
(Visual Regression Testでスクリーンショットを比較するという方法もあります)

同じ要素が複数ある

例えば、項目別に「編集」ボタンが表示されていて、ページ内に複数同じボタンが存在するという場合があります。
このとき、app.webviews.buttons["編集"]では要素が特定できません。
app.webviews.buttons["編集"].element(boundBy index) を使うことが多いのですが、
テスト側で正しくボタンが取得できていないと、違う項目の編集画面に飛ぶことになります。


それでは、XcodeiOSのversionが変化したとき、どの画面要素で差異が出るのかを把握する為にサンプルアプリを作成していきます。

これまでWebViewのUITestを走らせていて失敗することがあると感じた要素は以下の通りです。

Button

ボタン押下テストで使用

TextField

入力文字列の編集テストで使用

TextView

基本はTextFieldと同じですが、複数行対応によりキーボードの確定が改行になり、閉じるのが厄介だったりします。

StaticText

WebViewのチェックボックスは、チェック横の文字列をStaticTextで参照することでtap()で選択可能です。

これらを検証可能なアプリを作成します。

調査範囲

WebView

WKWebViewを対象にします。
UIWebViewはリジェクト対象になったので除くことにします。(2020.5月から)

iOS

WKWebViewの対応がiOS 11.0からなので、iOS 11.0以降を対象にします。
2020.8月段階ではiOS 14.0までテストできそうです。

Xcode

同じiOSのversionでも、使用するXcodeにより動作が違うのでは…という感覚があったので確認します。
ローカルではできるだけ最新のXcodeを使っていきたいので、これは払拭しておきたいです。
2020.8月の段階ではXcode12 beta5が出ており、BitriseでもXcode12.0に対応しています。
Xcode10, 11, 12を対象とします。

端末種別

端末のモデルの違いは要素の検出には影響を感じたことが無いので対象外とします。
記事中でテストにより、モデルが違う場合がありますが、使用できるiOSの種類で仕方なく変更しています。

検証用アプリ作成

先程の点を踏まえて以下のようなアプリを作成します。

f:id:kanari3333:20200821105000p:plain:w300
確認したい要素が並んでいるだけのアプリになります。

サンプルコードは以下に置いてありますのでご覧ください。
github.com

アプリ実装

Xcode10ベースでプロジェクトを作成します。
Xcode11から登場したSceneDelegateがあるとXcode10でビルドできない為です。
実は、この辺の互換性維持で2回プロジェクトをつくりなおしました 😇

WKWebViewを実装し、アプリ内のHTMLをロードします。

import UIKit
import WebKit

class ViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!

    oversionride func viewDidLoad() {
        super.viewDidLoad()

        if let html = Bundle.main.path(forResource: "WebViewSource", ofType: "html") {
            let url = URL(fileURLWithPath: html)
            let request = URLRequest(url: url)
            webView.load(request)
        }
    }
}

ロードするHTMLは以下のようにしました。

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <link rel="stylesheet" type="text/css" href="css.css">
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>

<body>
  iOS WebView UITest
  <form>
    <p>
      StaticText
    </p>
    <p>
      <input type="button" value="button1">
    </p>
    <p>
      <button type="button">button2</button>
    </p>
    <p>
      <input type=text size="40" value="TextField1">
    </p>
    <p>
      <input type=text size="40" value="TextField2">
    </p>
    <p>
      <textarea cols="50" rows="3">TextArea1</textarea>
    </p>
    <p>
      <textarea cols="50" rows="3">TextArea2</textarea>
    </p>
  </form>
</body>
</html>

Schemeの追加

UITest用のSchemeを作成します。
f:id:kanari3333:20200821104714p:plain

UIテストの実装

import XCTest

class WebviewUITestsCheckerUITests: XCTestCase {

    let app = XCUIApplication()

    oversionride func setUp() {
        continueAfterFailure = false
        app.launch()
    }

    func testTextFields() {
        let textFields = app.webViews.textFields.count
        XCTAssertEqual(2, textFields)
    }

    func testButtons() {
        let buttons = app.webViews.buttons.count
        XCTAssertEqual(2, buttons)
    }

    func testTextView() {
        let textViews = app.webViews.textViews.count
        XCTAssertEqual(2, textViews)
    }

検証用アプリ実行 (ローカル)

各アイテム数のカウントを取得していきます。
手元では、Xcode11.6 iOS12.4だと全てのテストがpassしましたが、
iOS13.3のSimulatorはTextFieldのカウントが0になり失敗しました。

f:id:kanari3333:20200821112053p:plain

うっすら闇が見えてきました。

一応、画面表示後すぐに取得できない場合があるので
XCUIElementに対してwaitForExistence()で見つからなくても5秒は待つようなテストも併設しました。

    func testTextFieldsWithWait() {
        let textFields = app.webViews.textFields.element(boundBy: 1).waitForExistence(timeout: 5)
        XCTAssertTrue(textFields)
    }

    func testButtonsWithWait() {
        let buttons = app.webViews.buttons.element(boundBy: 1).waitForExistence(timeout: 5)
        XCTAssertTrue(buttons)
    }

    func testStaticTextsWithWait() {
        let staticTexts = app.webViews.staticTexts["StaticText"].waitForExistence(timeout: 5)
        XCTAssertTrue(staticTexts)
    }

    func testTextViewWithWait() {
        let textViews = app.webViews.textViews.element(boundBy: 1).waitForExistence(timeout: 5)
        XCTAssertTrue(textViews)
    }

これで「待てば取得できるがすぐには表示されない可能性がある」場合を検出できるようになりました。

f:id:kanari3333:20200821121915p:plain

この結果の場合、withWaitの方は全て成功しているので成功とみなしてOKです。
想定通りの動作なので、テストから待たない場合を削除しておきます。

Bitrise

f:id:kanari3333:20200821105538p:plain

なぜCIを使うのか?

既にCI/CDが定着し過ぎて、具体的な理由が漠然としているのではないでしょうか。一般的な視点は(つ´∀`)つ置いといて、今回の観点に絞りあらためておさらいします。

Xcode

Xcodeには起動可能なOSの制限があります。
例えばmacOS 10.15.6 Catalinaでは、Xcode9.4.1や10.0は起動しませんでした。

SSDの容量を圧迫する

Xcodeは11系で16GB、12beta4で27GB使っていました。細かいversion違いまではさすがに入れておけないです。
Simulatorのversionもイメージをダウンロードするとそれなりの容量になるのでBitrise上で気軽に試せるのは助かります。

所有していない端末で検証可能

端末を多く揃えるのはコストが掛かります。
BitriseはFirebase Test Labと連携して実機テストを行うことができます。
Firebase Test Labは、ローカルからも実行できるので用途に応じて使い分けています。

誰でも検証できる

個人の環境に影響されずにテストが実施可能です。
これが一番大きいですね。

Workflow

ベーシックに組み、デバイスの選択の箇所以外を共通化しました。

f:id:kanari3333:20200821105832p:plain:w300

BitriseのUITestのセットアップは以下がリファレンスとなります。
https://devcenter.bitrise.io/jp/testing/running-xcode-tests/

まずは、「Xcode Test for iOS」を使用し、Simulatorでテストします。

f:id:kanari3333:20200821111117p:plain


しかし、このステップだと、どのversionのiOSが選択可能かが分かりません.

f:id:kanari3333:20200821105943p:plain

そこでScriptステップに以下を記載しておきます。

# xcodeのversion (xcode-testステップでも出力されます)
xcodebuild -version
# 利用可能なSimulator一覧を出力
instruments -s devices

Xcode11.3のSimulator一覧にはiOS11.0.1, 12.0が含まれていますが、
Xcode11.6では13.0以降しか含まれていなかったりするので毎回出しておくと便利です。

出力はこのようになります。

+ xcodebuild -versionsion
Xcode 10.3
Build versionsion 10G8
+ instruments -s devices
Known Devices:
iPhone 8 (11.0.1) [B7A24D53-33DC-42D1-B12F-74F70DE6FED5] (Simulator)
iPhone 8 (11.1) [F22CA5BB-2A45-4D3E-BAD9-F330DBE8229B] (Simulator)
iPhone 8 (11.2) [E951C4B7-3D18-40E8-A546-0EF4E557F87D] (Simulator)
iPhone 8 (11.3) [E97F64EC-1D09-41E4-958F-0CC87DDE9CA6] (Simulator)
iPhone 8 (11.4) [A2F0B36C-C4BB-473A-BF30-27195DED221B] (Simulator)
iPhone 8 (12.0) [E6636952-E492-45D1-BF08-6A8B4E001764] (Simulator)
iPhone 8 (12.1) [F17B5890-3A35-4A72-B401-7D3BDB32D3D0] (Simulator)
iPhone 8 (12.2) [E9102C7A-BA16-4D26-A388-0B2466F9306C] (Simulator)
iPhone 8 (12.4) [C55C04CE-55C6-4242-BE9B-0E243E80B3AF] (Simulator)

Simulatorのテスト結果

失敗したテストのみを抽出した表が以下になります。失敗したテストのみ2回チェックしています。
※視認性が悪くなったのでPASSは記載せず、N/AとNGのみ記載してあります。

  • 縦軸:Xcodeのversion
  • 横軸:SimulatorのiOS version

f:id:kanari3333:20200823190529p:plain

確認できたこと

  • Xcodeのversionにより差があるように見える (そんなことないと思いたいのですが...)
  • iOS 13.3はテストが通らない可能性が高い、全てのテストで失敗していました。
  • Xcode12.0とiOS12.1の組み合わせについて、規則性が無く、StaticText / Button / TextFieldでランダムに失敗していた。(このパターンが一番厄介そうです)

手元のメモだとiOS 12.1がほとんど通らないとあったのですが、今回確認したところそこまで結果は悪くありませんでした。
また、この段階で正常系のみで153個テストを回したのでいくら自動とはいえ疲弊しました。

Bitriseのプラン

個人のBitriseのFreeプランの上限である200ビルドを超えたので、$40のDeveloperプランにしたのですが、アップグレードの誘導ではなくPrice一覧からたどれば「14日間お試し」のリンクが存在していることに気付きました 😇
www.bitrise.io

実機テスト

f:id:kanari3333:20200821111814p:plain

Firebase Test Lab等で、実機テストを行います。

iOS Device Testing」ステップを利用します。
これはBitriseからFirebase Test Labで実機テストを実行してくれるステップで
本来必要なTokenなどの認証を設定しなくても良い便利なものです。料金も無料です。

f:id:kanari3333:20200821112717p:plain
Xcode Build for testing for iOS」ステップと組み合わせて使用します。

なぜFirebase Test Labを使うのか

Bitriseの「Xcode Test for iOS」だと、Stackで選択したXcodeに含まれているSimulatorしか選択できない為、
Firebase Test Labだと、ビルドに使用するXcodeのversionに関係なくデバイスファーム側で用意されている実機を指定できます。
また、Simulatorと実機の動作の違いがないか確認したい気持ちもあります。

f:id:kanari3333:20200821112808p:plain

こちらはどのデバイスが選択可能かステップから見ることができます。

しかし... @tarappo さんからのコメント
「そのデバイス一覧はハードコードだからホントとは限らないよ」

最新の状況が知り合い場合は、gcloudコマンドから以下で確認できます。

gcloud firebase test ios models list

実機テストの結果

テスト結果は以下の通りです。
errはInternal errorもしくはtimeoutで、非対応等の理由でテストが実施できなかったものになります。
f:id:kanari3333:20200824004556p:plain

  • 利用可能なiOSが少ないのでテストは楽でした。(iOS 11.2、11.4、12.0、12.1、12.3、13.2、13.3)
  • 最新版への対応では、iOS13.2がiPhone XRで、iOS13.3がiPhone 11 / Proで利用可能になっています。
  • Xcodeによるテスト結果への影響はなさそうです。
  • Xcode 12.0とiOS 13.2の組み合わせでは、TextViewが取得できない場合がありました。
  • iOS 13.3はXcode12.0でしか動作しませんでしたが、全てのテストが失敗していました。

まとめ

WebViewのUITestが期待通りに動かない場合がある。ということが分かりました。
傾向としては、最新のOSだと多い印象です。

ただ、Simulatorで上手く動作しなくても実機では動作するパターンが多いということが分かったので、Firebase Test Lab等で検証しておけば、ひとまずそちらを正として良さそうです。
また、iOS 13.3については、Simulator / 実機共にWebViewのUITestは正しく動作しない。と考えてください。

UITestは、複数台の端末で動かしておきたい場合というのが多々あると思うので、
テストが失敗する場合に思い出して頂ければ幸いです。

補足

実は、WebView以外も不安定

ANDPAD技術顧問の @tarappo さんが、ios_ui_test_sandboxというリポジトリを作成されています。カウントだけでなく、Exists・Hittableの検証も行っているので興味がある方は見てください。
github.com

さいごに

ANDPADでは、一緒に働く仲間を募集中です!
engineer.andpad.co.jp

MySQL勉強会〜ロックについて(DDL編)〜を開催しました!

f:id:fkmy:20200811121843j:plain

こんにちは。最近リモートワーク用にマイクを買ったソフトウェアエンジニアの福間(fkmy)です。

先月、ANDPADのデータベースの技術顧問をして頂いてる三谷(mita2)さんによるロックの基礎編)〜について勉強会を開催しました。今月はロックのDDL編について8/4(月)に勉強会を実施しました。重要な箇所をピックアップします!

また今回も在宅勤務期間中のためオンライン開催となり当日は16名が参加していました。

内容

当日の資料はこちらになります。

DDLについて

DDLとはData Definition Languageの略称でデータ構造を定義するための言語のことです。SQLではCREATE文、DROP文、ALTER文、TRUNCATE文が該当します。

DDLの仕組みと改善の歩みについて

  • MySQLのALTER TABLEの初期実装
    • 新しいテーブル定義のテーブルにデータコピーする
    • 実行中は書き込みがブロックされる
  • バージョンアップごとに機能拡張されています

    ver サポート 概要
    v5.5 ・First Index Creationがサポート インデックスのみの変更はテーブルをコピーせずインデックスを追加することにより高速化
    v5.6 ・オンラインDDLがサポート 更新中にブロックされず、テーブルのロック待ちが発生しなくなった
    v5.7 ・オンラインDDLのサポート範囲拡大 varcharのカラム長の変更もサポート
    v8.0 DDLがアトミック化
    ・Instant Add Columnがサポート
    ・処理途中で止まってもデータが壊れなくなった
    ・Add Columnの高速化

オンラインDDLについて

オンラインDDLの対応判別表

項目 対応 補足
インデックスの追加と削除 -
カラムの追加と削除 -
varcharカラム長の変更 v5.6以前は非対応
カラムの型変更 -

手元での確認方法

  • ALTER TABLE 実行時に LOCK=NONE, ALGORITHM=INPLACEを指定して判別が可能です。オンラインDDL非対応の場合は以下のようにエラーが返ってきます。
-- コマンド例およびエラー
mysql> ALTER TABLE sbtest.sbtest1 MODIFY COLUMN v1 VARCHAR(110), LOCK=NONE, ALGORITHM=INPLACE;

ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.

metadata lock について

  • metadata lock:完了直前に行われるテーブル定義などのロックのことです。
  • 問題となるケース
    • 長いトランザクションがALTERの完了をブロックしmetadata lock待ちのALTERの完了を後続のSQLが待つことになる
  • 対策案
    • 長いトランザクションが流れていないタイミングを狙う
    • lock_wait_time を短く設定する
      • ただし、過度に短いとmetadata lockが取れずALTERが失敗しやすくなります

ALTER関連のTips

  • 複数の変更は1つのALTER 文で実行できます
    • ただし、オンラインDDL非対応のものを混ぜるとロックが掛かります
  • Rolling Schema Upgrade

    • オンラインでDDLを実行する運用手法です
    • レプリケーション遅延をなくすことを目的としています
      f:id:fkmy:20200811113838p:plain
      Rolling Schema Upgrade
  • pt-online-schema-change

    • オンラインでDDLを実行するツールです
    • オンラインDDLに対応していないものをオンライン実行可能にします
      f:id:fkmy:20200811113945p:plain
      pt-online-schema-change

Amazon Auroraについて

  • DDLによるレプリケーション遅延がほとんど発生しない
  • レプリカではmetadata lock待ちは発生しませんがマスターではmetadata lock待ちが発生します
    • 検証結果が三谷さんのブログに記載されています。 mita2db.hateblo.jp

さいごに

DDLによるレプリケーション遅延が素のMySQLでは発生してしまいますが、Auroraではほとんど発生しないらしくAurora最高!!というのが1番の感想です。AndpadでもAuroraを使用して開発を行っているので、オンラインDDL対応のものは積極的に日中リリースしていきたいと思います。

勉強会を通してMySQLと徐々に仲良くなれてる気がするので来月のデータベース勉強会も楽しみです!

ANDPADではエンジニアを募集しています

データベース勉強会に限らず定期的に勉強会を開催していますので一緒に成長したい!と思った方は以下の採用サイトから詳しい職場環境などもご覧になってみてください!

engineer.andpad.co.jp