✨開発合宿の成果物を磨いて新機能にする

こんにちは、@mugi_uno です。

暑くて溶けそうです。

新機能をだしました

新機能を出したら開発ブログで何か書く、というのが自分のルーティンになりつつありますが、 先日、表計算ソフトからのコピー&ペースト機能を追加しました。

www.misoca.jp

Excelなどからコピーして、Misocaでペタッと貼り付けると一気に明細が作れるというもので、 先日開発ブログに書いた電卓機能*1と同じく、こちらも4月に実施された開発合宿の成果物がベースになっています。

とはいえ合宿の成果物でいきなりゴールしたわけではなく、リリースまでにかなりのブラッシュアップを行いました。

というわけで今回は、開発合宿の限られた時間で一人で作った機能が、新機能として正式に提供されるためにどのように磨かれていったかをご紹介したいと思います。

合宿終了時点での成果物

まず、合宿が終わった時点での状態がこちらです。 特に誰とも相談せず、思いつくままガッと実装した形です。

f:id:mugi1:20190808171413g:plain
合宿終了時点の動作イメージ

  • 行列の移動がCSSアニメーションでヌルヌル動く(合宿の成果発表時のインパクトのために作ったのは否めない)
  • タブ区切り、カンマ区切りの両方に対応できる
  • 実は全項目編集できる

などが特徴です。

UI/UXを練る

これをベースに、まずは「使いやすいUI/UXはどんなものだろう?」というのを、デザイナーの@kanizmbを中心に一緒に練ります。すると、色々と現状のままではイケてない部分が見えてきました。

列移動がパズル状態になる

貼り付けたデータの列をどの項目に挿入するかを選択するのに、ボタンをクリックでの列と列を入れ替えることで実現していました。 見た目はヌルヌル動いてオシャレですが、実際やってみると動かしたい列の隣の列も動いてしまうので、まったく直感的ではなく、かなり混乱します。

f:id:mugi1:20190808174654g:plain
列移動のややこしさに悶絶する図

まるでスライドパズルを解いているような気分に陥ります。

IQ脳トレ知育玩具 スライドパズルすうじ 15パズル

何かほかの方法で列と明細項目の紐付けが必要だな〜という話になりました。

横スクロールがつらい

表計算ソフトで作られた文書の場合、レイアウト調整などの理由から、必要のない列がデータ間に多く含まれる可能性が考えられます。(いわゆる 'Excel方眼紙' などの場合は特に顕著でしょう。)

そういったデータから貼り付けたい場合、大きく横スクロールが発生する可能性があります。

f:id:mugi1:20190808173139p:plain
横スクロールが発生して困る図

トラックパッドなどが利用できればよいですが、そうではない場合なかなかの使いづらさです。

UI/UXを見直した後のイメージ

ほかにも様々な観点からUIを見直し、次のような修正をすることで方針を固めました。

  • "列に対してプルダウンから項目を割り当てる"という形に変更する
    • 「このデータは数量だな〜」→「項目は数量を選ぼう」という操作ができた方が直感的
  • 行の移動はドラッグアンドドロップでの移動に変更する
    • 文書の明細行並べ替えUIと揃えて、操作感を統一する
  • ひと目で可能な操作がわかるようにする
    • 削除ボタンはマウスホバーせずとも常に表示して、行・列の削除できることがわかるように
    • 既存の画面で可能な操作(並び替えや削除)とUIを揃える
    • 並び替えや削除の範囲が明確になるようにレイアウトを調整する
  • 多すぎる列のデータはグレーアウトして削除だけ可能にする
    • まず不要な列を削除する、という操作をすることで横スクロールを回避する
  • Misocaのアプリケーション全体と見た目を揃える

これらを含め、修正前に一度イメージを共有し、関係者で認識のズレがないことを確認します。

f:id:mugi1:20190808175922p:plain
初期段階で見直したイメージ図

さらに使い勝手などの面から次の対応も入れることにしました。

  • データが多すぎると構築するDOMの量が多すぎてブラウザがクラッシュする恐れがある
    • 一定の列・行数で打ち切るようにする
  • 空行・空列は邪魔になる
    • 空行・空列はすべて削除する

PRレビューでの指摘の数々

見直したイメージに沿う形への修正が完了したら、PullRequestを作成し、まずは開発者でレビューしてもらいます。

コード自体に関するレビューはもちろんのこと、Misocaのレビューでは「そもそも仕様として○○は✕✕のほうがいいんじゃない?」というコメントも頻繁に見かけます。その中でも様々な意見をもらいました。

カンマ区切りいらないのでは?

最初は、表計算ソフトからの貼り付けに加えて、CSVファイル(カンマ区切り)も使えました。 合宿時点では「使えるファイルの種類多くて色々できたほうが便利でしょ!」という軽い考えでしたが、レビューの中で次の意見をもらいました。

f:id:mugi1:20190809102534p:plain

できることが増えることは一見良いことに感じますが、選択肢があれば操作時に思考や迷いを生みます。 あらためてカンマ区切りの是非について検討しました。

  • なんとなく対応してたけど、CSVファイル貼り付けるシチュエーションはかなり稀
  • 暗黙的な挙動が増え、ユーザに戸惑いを与える恐れがある
  • サポートしていることで実装が複雑化し、メンテナンスコストも増える

議論した結果、「最初のリリース時点ではカンマ区切りはサポートしない」とすることにしました。

空列・空行を勝手に削ってほしいとは限らない

「データの中の空列・空行を貼り付けた後にいちいち消すのは手間だから、こっちで除去しておこう!」 と空データをフィルタリングしていましたが、これに対して貰った指摘が次のものです。

f:id:mugi1:20190809105150p:plain

例えば普段は次のような請求書を利用していたとします。

f:id:mugi1:20190809105645p:plain:w400

貼り付ける際には「品目→単価→数量」の順番で左からセットされるのを期待し、実際にもそのように動きます。 しかし、「まったく同じレイアウトで単価は入っていない」といったデータを考えてみます。

f:id:mugi1:20190809110320p:plain:w400

単価に該当する列には何もデータがありません。 この場合、空データのフィルタリングによって「空列」と判断されて削除されてしまいます。 同じファイルから同じ範囲をコピー&ペーストしたにも関わらず、画面上で見えるデータが別のものになってしまうと、 「あれっ?なんで違う項目になるの??」と戸惑うことが予想されます。

便利だと思って入れた空データの除去フィルターでしたが、実際のユースケースを考えると混乱を招く要因になり得ることがわかりました。

除去するのは末尾の空行・空列のみとする」という方針に見直しました。 不用意に除去するより、常にある程度同じ挙動をするほうが使いやすく戸惑いが少ないという判断です。

さまざまな視点からの意見をもらう

開発者やデザイナーだけではなく、マーケティングやコールセンターの方などにも触ってもらいました。違った視点での意見がとても貴重です。

モーダルが狭い

f:id:mugi1:20190809131037p:plain

貼り付ける際に開くモーダルが小さくて使いづらいという意見です。 こちらも取り入れ、デフォルトのサイズを少しだけ大きくし、かつ拡大・縮小を可能にすることにしました。

f:id:mugi1:20190809132418g:plain
拡大・縮小を可能にした状態

数値しか入ってないとはかぎらない

確認してもらっている中で、とある意図しない挙動が発覚しました。

f:id:mugi1:20190809135135p:plain

表計算ソフトで作られた文書の場合、こちらが数値を期待している項目だとしても、本当に数値が入っているかはわかりません。

単純に単価が「10000」だとしても、一般的には次のようなバリエーションが想定されます。

  • 10000 (数値のみ)
  • 10,000 (桁区切りを含む)
  • ¥10000 (金額を示す文字付き)
  • 10000円 (金額を示す文字付き)
  • 10000(全角)
  • 10,000(全角で桁区切りを含む)

このあたりについて一部考慮が漏れていたため、うまく反映されないという動きになっていたのです。

これは、1件ずつ画面で入力する際であれば、リアルタイムで注意喚起や自動的な変換を行ってくれる仕様になっています。

f:id:mugi1:20190809134302g:plain

今回の機能の場合には一括で大量のデータが挿入されることもあり、サービス側でいい感じに変換しないとかなりの手間になることが予想されました。

最終的には、サービス側で数値変換を自動的に行うように対処しました。

f:id:mugi1:20190809135406g:plain
数値の変換を行うようになった状態

Before→After

上記以外にも細かな修正をリソースの許す限り行いました。

開始時点(合宿での成果物)と完成品(リリースされたもの)を改めて比較してみましょう。

Before

f:id:mugi1:20190808171413g:plain
合宿での成果物

After

f:id:mugi1:20190809140118g:plain
最終的にリリースされたもの

こうやって比べてみると、かなり変わっていますね。

最初の状態はパッと見ではスタイリッシュですが、使いづらいところをたくさん抱えていました。 実際のユースケースを想定し、様々な視点からの意見を参考に使いやすさを追い求めていった結果、大きくUIが変化したのは興味深いな〜と思いました。

Misocaにアカウントをお持ちの方は、ぜひ請求書の作成画面で試してみてください。

採用

Misocaでは、より良いものを作っていきたいエンジニアを募集しています

www.wantedly.com

初めてのデザイナーインターン受け入れ

夏ですね。デザイナーのとりみずのです。

北海道の道東を旅行で訪ねてから、毎日北海道のことを考え、最推しが北海道になりつつあるこの頃です。

Misoca社として、7月にはじめてデザイナーインターンの受け入れを実施したので、今回はその取り組みについて紹介します。

インターンプログラムを考える

会社としても、インターンに来られる方も、得るものがある3日間にしたかったので、それが実現できるプログラムを検討しました。

他社のインターン事例を調査したり社内で相談を重ね、最終的には、下記のプログラムで受け入れを実施しました。

  • 期間:3日間
  • 場所:名古屋本社
  • 担当:デザイナーのメンターが1名サポート
  • 内容:サービスを触り、業務上実際にある課題の改善にひとつ取り組む

▼参考にさせてもらった他社のデザイナーインターン事例

https://jobs.freee.co.jp/recruitblog/aboutus/freee_internship_ux/ https://internship.cookpad.com/2019/summer/#tenday-sixday https://cybozu.co.jp/company/job/recruitment/intern/summer2019/

インターン実施

いよいよインターン受け入れの開始です。

初日にインターンの方が来たときに、3日間という限られた時間の使い方の意識をしてもらいたかったので、まず最初にインターンプログラムのスケジュールを共有しました。

ざっとこんな感じです。

## 1日目

午前:オリエンテーション

-会社の紹介
   - 過去事前に実施されていればスキップ
- PCセットアップ
- デザイナーの業務内容の共有
- Misocaのサービスの概要について説明する
- インターンでの互いのゴールの意識合わせ
    - 本人が何を得たいかにより、実務内容やメンタリングを考慮する

午後:サービス開発実習

- Misocaを触ってみて気づきをあげる
- 課題1個選んでもらう。もしくは自分で見つけてもらって取り組む
- 成果発表のタイミングを相談し、カレンダーにいれる(デザインチーム+任意で人事やその他メンバー)

## 2日目

- デザイナー朝会に参加
 - リモートのデザイナーとの交流
 - 何時に検討案を共有できそうか相談
- レビュー依頼方法についての説明とポイントの共有
- 中間共有:レビューを体験してもらう

## 3日目

- レビュー反映
- 発表内容をまとめ
- 発表内容まとめの確認
- 成果発表
- 過去のデザインの紹介と意図を共有
- インターンの振り返り
 - KPT
 - 最初にたてたゴールのふりかえり
- 感想をもらう

オリエンテーション

1日目に実践してみて特によかったことが、2つあります。

①インターンでの互いのゴールの意識合わせ

インターン受け入れで何を期待しているか話した結果、「デザインの意図や意思の言語化のスキルアップしたい」という言葉を引き出すことができました。 さらにそこから、3日後にどうなっていれば成功と言えるのか?を続けて話し合いました。

「学校でエンジニアと一緒に何かを作る時に、伝えたものと成果物にギャップがある時がある」というエピソードを聞けたので、このインターンを終えた後はそれが解消されるよう「次に学校のチーム何かをつくるとき、認識齟齬がなくなることで、つくるスピードやクオリティがあがる」をゴールイメージとしました。

f:id:torimizuno:20190807094512p:plain

ゴールの意識合わせをしたことにより、メンターとして、「何を意識して伝えるべきか」「何にトライしてもらうか」が明確になり、私自身、3日間でやるべきことがクリアになりました。

▼参考:こばかなさんのコーチングツイート

https://twitter.com/kobaka7/status/1130266794755624961

(ゴールを明確化するのにとても役立ちました!ありがとうございます)

②サービスを触ってもらい気づきをあげる

こちらに関しては、2つの狙いで実践してもらいました。

ひとつめはドメイン理解度をあげてもらうこと。ふたつめは、プロダクトに愛着を持って考えてもらうことです。

3日間という短い期間ですが、少しでもサービスやユーザーのことを知ってもらってデザインするとしないでは大違いのプロセスになっていたと思います。

サービスに触れてもらう中で、質問が何度も出たり、気づきもまとめてもらえたので、ドメイン理解とプロダクト愛につながっているように感じました。

サービス開発実習

オリエンが終わった後はいよいよサービス開発実習です。

サービスを触って得た気づきの中から、もしくはデザイナー陣があらかじめピックアップしていた課題の中から、取り組む課題をひとつ決め、UI改善の検討を進めてもらいました。

Misocaでは、なんのためにやるのか?を明確にするために、「インセプションデッキを書く」というレームワークを採用しています。

UI改善の第一歩として、インセプションデッキを書くことにもトライしてもらいました。

レビュー

改善案がある程度固まってきたら、次はデザインレビューの体験です。

レビューは、視野を広げたり、他者を巻き込んでプロトタイプの精度を高めたり、意思決定判断材料のための手段のひとつとして活用できるものなので、インターンの方には今度どんどんレビューにチャレンジしていってもらいたい気持ちを込めて、自分が意識しているポイントを共有しました。

共有したレビューのポイント

  • レビューは対人でなく対アイデアに対してされる
  • レビューを依頼する時は、相手がその情報だけで理解できる言葉を意識して書く
  • 目的や前提も、見てもらいたいアイデアと合わせて伝える
  • 相手のレビュー意見全てを受け入れるのではなく、あくまでいち意見として自分の中で噛み砕いて捉える

レビューを経験する前はかなり緊張していたようでしたが、実際に一度デザインチームでデザインレビューを経験してからは、「自分では気づかなかったものもあって参考になったので、レビューしてもらってよかった!」とレビューへの苦手意識が緩和されているように感じたので、インターン受け入れで実施できてよかったです。

成果発表

レビュー後はレビューを踏まえてUI改善のプロトタイプのブラッシュアップを進めてもらい、最終日の午後に、成果発表を実施しました。

ここでもレビューと同様、何に取り組んでいるか前提を知らないメンバーに対しても理解できるように一連の流れからの実際に考えた検討案の成果発表を意識してもらい、4人のメンバーを前に発表してもらいました。

10分ほどの発表でしたが、横で見ていて、デザイン意図が言語化して伝えられているように感じたのと、メンバーからの質疑応答にも答えられていて、「この部分、すぐに取り入れてもいいね」という声も出たので、いい成果発表の時間になりました。

ふりかえり

サービス開発実習が終わってからは、インターン3日間の振り返りをKPTで、最初に立てたゴールについての振り返りを対面で、実施しました。

▼KPTでの振り返り

f:id:torimizuno:20190807100035p:plain

▼ゴールに対してのふりかえり f:id:torimizuno:20190809093247p:plain

ふりかえり時に、「学校で次にメンバーと何かを作る時、認識齟齬がなくなってつくるスピードやクオリティがあがりそうですか?」と尋ねたのですが、「はい!今回実際に経験したことを取り入れてやってみます!」との言葉をいただけたので、きっと身になったはず…!

まとめ

インターン終了後は、実施内容をまとめたり、受け入れを他のメンターでもできるようドキュメント化共有してしくみを整えたり、発信用にこうしてブログにまとめたりと、Misocaとしても今後会社新卒の方を受け入れられるような土台づくりの一歩の成果が得ることができたのではないかなぁと思っています。

ご協力いただいた社内のみなさん、インターンに来てくれたFさん、ありがとうございました。

私自身はじめてのインターン受け入れで緊張などもありましたが、最後にインターン楽しかったです!」という言葉頂けたのが、個人的にとても嬉しかったです。

採用

引き続きMisocaでは、一緒に働いてくれるデザイナーを募集しています!

www.wantedly.com

木曜の夜はもくテク!

こんにちは、k0matatsuです。

突然ですが皆さんは「もくテク」をご存知ですか? もくテクは弥生株式会社が木曜日に開催しているテクノロジーを語る勉強会です。 普段は弥生株式会社のメンバーを中心としたラインナップですが、Misocaも「もくテクpowered by Misoca」として隔月で勉強会を実施しています。 今回は開催を来週に控えた第二回のもくテクpowered by Misoca登壇者からコメントを貰っているので紹介したいと思います。

Firebase Functions x puppeteer でスクレイピング入門

「定期的にweb上のデータを集計・確認したい。」という時に、スクレイピングが便利ですよね。
ただスクレイピングの実行環境を自前で整えようとすると、サーバーを借りてインフラを整備して、curlで定期実行など結構大変です。
ですが、Googleが提供するmBaasのFirebaseを使えば、スクレピングの定期実行からテキスト・画像データの集計、更に変化量によってのslack等への通知までサーバーレスで行うことができます。
しかも料金もほぼほぼ無料です。
本発表では、自分用に作っていたスクレイピングプログラムを通して、Firebaseリソースでスクレイピングの実行方法、やってみてわかった利点、欠点、注意事項などを紹介します。

テスト戦略の考え方

少し前に「画像を使ったテストでリリースサイクルをあげる」というブログを書きましたが、そこから視点をさらに高くして製品に対しどのようにテストを行うかというテスト戦略の考え方について話したいと思います。
主に私の携わっているモバイルやAndroidを中心とした話になりますが、取り扱うのは考え方なので他のプラットフォームでも参考にしていただけるのではないかと思います。
もちろんプロダクトによって最適なテスト戦略は異なりますので、皆さんのこだわりのテスト戦略についても発表後やコメントなどで教えていただけると嬉しいです。

Feature Flagを利用したリリース戦略

アジャイルのプラクティスに「ビッグバンリリースを避ける」というものがあります。
これは、コードの変更量が大きいほど問題があった場合の特定が難しくなること、変更の衝突が起こりやすくなること、など様々な問題を孕んでいるためです。
一方で、ひとまとまりの開発が終わるまではリリースできない、といったプロジェクトもあるのではないでしょうか。
こうしたプロジェクトでも細かく機能をリリースしていくための戦略として、機能フラグ(FeatureFlag)を使う方法が知られています。
機能フラグを使うことによって、一部のユーザにのみ機能を公開したり、デプロイを伴わず任意のタイミングで機能を公開するなど、柔軟な制御を行うことが可能になります。
本発表では、FeatureFlagの基本的な考え方を解説した上で、Misocaでの実用例を紹介します。
なお、本発表の内容はRailsDM 2019でのujihisa氏のセッションA-7 雑に強い影響を受けています。

勉強会について

いかがでしたでしょうか?
内容が多岐に渡るのでどれかひとつは気になるトークがあったのではないでしょうか?
もくテクpowered by Misoca #2 は 8/8(木)19:00に開催します。
イベントの詳細な情報はconnpassのページをご確認ください。

運営の都合で今回は名古屋会場・YouTube会場は無しになります。
次回はYouTube会場も復活したいなと思っていますが、今回は各会場でお会いしましょう。

Misocaではプロダクトだけでなく自分自身を成長させるのも好きなエンジニアを募集しています。

recruit.misoca.jp

DENTAKU

こんにちは、 @mugi_uno です。

娘が保育園で私の似顔絵を描いてくれました。
黒いメガネがオシャレで、とてもよく描けていました。

ちなみに私はメガネはかけてません。誰の顔を描いたの。

電卓機能

先日Misocaに電卓機能を実装しました。

www.misoca.jp

f:id:mugi1:20190718175926p:plain

この機能は、2019年4月に行った開発合宿*1の成果物が元になっています。

「たかが電卓、されど電卓」ということで、リリースまでに様々な知見やハマりどころがあり、とても楽しかったです。 今回はこの電卓機能がリリースされるまでのお話です。

🤔なぜ電卓?

「Webサービスなんだから小計とか合計は自動で計算されるのに、なんで電卓なんか必要なの?」と思うかもしれませんが、 文書を作成するときには、意外と些細な計算が必要となることが多く、

  • 10%引きにした単価にしたい
  • 総額3万円からの差額を明細に含めたい

といったケースがよくある例です。

従来のMisocaでは、これらの計算はユーザ側で物理・あるいはアプリなどの電卓を用意する必要がありました。 そしてそこから結果をまた画面上で入力する必要があり、とても面倒です。転記時に間違えるリスクも増えてしまいます。

請求書を作る体験の中にシームレスに電卓が組み込まれていることで、 ストレス無く文書を作ることができるようになるというわけです。

...と、前々から考えていたものの、なかなか「おっしゃ気合い入れて電卓作るぞ!」とはならないものです。 そんな中ちょうど開発合宿があり、ガッとプロトタイプを作ってみたところ社内でも評判が良く、ブラッシュアップしてリリースしよう!という運びとなりました。

📚電卓を知る

正直言うと「電卓なんて押された数字で四則演算できればいいだけでしょ〜」程度に軽く考えていましたが、 実際作るために様々な電卓の仕様・挙動を調べていると、なかなかに奥が深くて面白かったです。

ボタン

電卓に ボタンがあるのをご存知でしょうか。私は存在自体に気付いていませんでした。 これを利用すると、「特定の値のN%引きの値」などを簡単に算出できます。

2 0 0 2 0

と入力すると、240 が結果として得られるのです。便利ですね。

しかし、この挙動は電卓のメーカーによって違いがあり、たとえばCASIO製の電卓の場合には

2 0 0 × 2 0 %

と入力する必要があります。 Misocaで機能実装するにあたって、どの挙動に揃えるかの検討が必要でした。

最終的には、多くの電卓の挙動である

2 0 0 2 0

240 が得られる方式を採用しています。

計算順序

次の順番でボタンを押したときの計算結果が、電卓によって異なります。

1 0 0 5 × 2

ほとんどの一般的な物理電卓では、掛け算・割り算の順番は考慮されずに (100 + 5) × 2 扱いとなり、結果は210 です。 しかし、例えばiOSに搭載されているデフォルトの電卓アプリなどの場合は、式全体を考慮して 110 になります。

Misocaでは物理電卓側に寄せて、この場合は 210 となるようにしています。

💪使いやすさを追求する

機能追加するなら、せっかくなら使いやすい便利なものにしたいですよね。 内部の多くの人に触ってもらい、さまざまな感想をもらいつつ動作を調整していきました。

⌨️キーボード入力対応

最初はマウスなどで電卓をポチポチクリックして操作するのみのイメージだったのですが、 以下の感想をもらいました。

f:id:mugi1:20190719133151p:plain:w400

確かにそのとおりだな〜と思い、キーボード入力でも動作するように拡張しました。 しかし、軽い気持ちで始めたら色々とハマって大変で..

key / code / keyCode が環境で色々と変わる

JavaScriptで入力されたキー情報はkeyDownやkeyUpといったイベントから KeyboardEvent.key / KeyboardEvent.code / KeyboardEvent.keyCode といった値を参照する方法がよく知られていますが、 これらの値はブラウザによって一部に差異があり、個性の強いわんぱくブラウザではまったく違う値を返すこともあります。

また、たとえば keyCode はキーボードのJIS/US配列によって、期待値とズレる可能性があります。*2 US配列のHHKBを愛用している私だけ挙動が違っていて大変でした。

というわけで開発中は、Windows/MacOS × Chrome/Safari/FireFox/Edge/IE11 × JIS/US といった多数の組み合わせで確認しつつ、 どの環境でも自然に動かせる最適解を見つけるためにひたすら試行錯誤を繰り返していました。

最終的にはこんな感じで動作するように仕上がりました。

f:id:mugi1:20190719141643g:plain:w500

🔧細かな動作調整

ほかにも様々な動作調整を行いました。

  • 電卓の開閉のショートカットキーは何が良い?
  • すでに入力されている状態で電卓を開いたら?
  • 文字選択状態で電卓を開いたらどうする?
  • 100 / 3 * 3 の結果は何になるべき?
  • などなど..

あまり華やかではありませんが、頻繁に使うことになる可能性も高い部分なので、 ストレスを感じない使いやすいものを目指し、コツコツと地道な修正・改善を繰り返します。

🎉リリース

そんなこんなで、先日無事に機能リリースできました!

昨年に引き続き*3、 今年も合宿の成果をプロダクションへのリリースに繋げることができたので、個人的にはとても満足なプロジェクトでした。

合宿の価値が証明されつつあるので、来年あたりはハワイでの開発合宿に期待したいと思います。

採用

Misocaでは使いやすさを追い求めるエンジニアを募集しています

www.wantedly.com

「斧を研ぐ時間」エンジニアリングフライデーという試み

こんにちは Misoca 開発チームの id:mallowlabs です。最近は ドラえもん のび太の牧場物語 にハマっています。使っている道具のグレードを上げるために、牧場はそっちのけで鉱山にこもって鉱石を掘り出す毎日です。

さて、先日の 軽減税率・区分記載請求書対応のリリース は開発チームにとっても比較的大きなリリースでした。そのため、リリースの直前には、このリリースに関係しないコミットは master ブランチにマージを控えることになり*1、自然と開発メンバーが普段使っているツールの整備や自由研究が行われることになりました。 ふりかえりで、このいわゆる「斧を研ぐ時間」がよかったという声が複数出たため、この時間を狙って作ってみようという TRY が生まれて「エンジニアリングフライデー」という試みが生まれました。 今回はこのエンジニアリングフライデーについて紹介したいと思います。

エンジニアリングフライデー

プレミアムフライデーにちなんで、その月の最終金曜日に開発メンバーがプロダクトの開発以外のことを行う、という取り組みです。 特に細かいルールは設けず、

  1. 事前にやろうと思っていることを Scrapbox に書き出す
  2. 16時になったら成果発表をする

ということだけ決めて実施してみました。

f:id:mallowlabs:20190711151254p:plain
Scrapbox の様子

エンジニアリングフライデーの成果

様々な試みが行われましたが、例えば以下のような改善が行われました。

  • 気になっている箇所のリファクタリング
  • CI の高速化
  • フロントエンドのテストのカバレッジを CI で表示
  • Lint のルールの整備
  • BigQuery で分析した結果を Redash で可視化
  • Trello / GitHub / esa の URL を Slack に貼ったら展開
  • etc...

たった一日でしたが目に見える成果が数多く出て驚きました。 「やってよかった」という声が複数出たため、また次回もやってみようということになりました。 「合宿より誘惑が無いから逆に捗るのでは?」という意見もあり、一日とはいえ大きな進捗を感じたメンバーが多かったようです。 残念ながら日程の関係で参加できなかったメンバーからも「次回は絶対参加したい」という声が上がりました。

次回のエンジニアリングフライデーもどんな成果が出るか楽しみです。

Trello / GitHub / esa の URL を Slack に貼ったら展開

ちなみに私の成果は「Trello / GitHub / esa の URL を Slack に貼ったら展開」です。 せっかくなのでオープンソースにしています。

AWS SAM で簡単に動かせるので試してみてください。

f:id:mallowlabs:20190708175939p:plain
展開の動作イメージ

採用

Misoca では斧を研ぐ時間も大切だと思っているエンジニアを募集しています。

www.wantedly.com

*1:master へのマージを控えるという人の意識に頼った運用はミスが生じかねません。現在、大きな機能変更をしながらも、master へのマージを可能にする仕組みを構築・運用中です。詳細は後日このブログで公開予定です。

Misoca メンテナンス画面の裏側

Misoca の開発をしている id:mizukmb です。

先日、Misocaでは軽減税率8%の入力、および区分記載請求書の形式に対応しました。今回のリリースはシステム全体に関わる大規模なものとなったため、リリース作業中の時間はWeb・API・iOS/Androidアプリ全てのサービスを停止し、メンテナンス中としていました。

これまでMisocaではサービスを長時間停止させたメンテナンスやリリースをほとんど実施しておらず、メンテナンスモードを簡単に切り換える機能はありませんでした。加えて、今回のリリース作業の時間においては、下記を実現する必要がありました。

  • 一般ユーザからはMisocaサービスにアクセスさせたくない(メンテナンス中として見せたい)
  • 開発者など、特定の条件を見たすユーザの場合は、メンテナンス中でも本番環境にアクセスして動作確認ができるようにしたい
  • 外部連携するシステムによっては、メンテナンス中でもアクセスを止めたくない

そこで、今回のリリースに合わせて上記の要件を満たすメンテナンスモード機能を実装しました。本ブログでは、メンテナンスモード機能の紹介や、実際のメンテナンス画面などをお見せしていきたいと思います。

メンテナンスモードの仕様

メンテナンスモードの有効・無効の切り換え方法として以下の2パターンを用意しました。

  • スケジュール実行による有効・無効の切り換え
  • 手動による有効・無効の切り換え

メンテナンスモードの状態は上記2パターンをORで判定しています。ですので、どちらかが有効になっていればメンテナンスモードになりますし、どちらも無効にならない限りはメンテナンスモードは停止しません。

こうした仕組みにした理由は、メンテナンスの時間を延長した場合にスケジュールの時間を変更するよりも簡単にできるようにするためです。

また、メンテナンスモードの状態管理はRailsアプリケーションに持たせています。調査の段階では、ロードバランサで制御する方法も検討しましたが、先に述べた要件を満たすためには、現行のシステムでは実装コストが非常にかかるということが分かったので、Rails内で制御する方法に決定しました。1

設定方法

スケジュールの設定

メンテナンスモード設定用のYAMLファイルに時間を書きます。デプロイすると、指定した時間内はメンテナンスモードが有効になります。

開始・終了時間の設定は2つ以上設定できないようにしました。メンテナンス自体は頻繁に行われるものではないため、高機能にさせすぎず実装をシンプルに保つためです。

# メンテナンスモードの有効・無効を設定する
# `start_time` `end_time` に記述する日時のフォーマットは以下の通り。タイムゾーンはJSTとする
#   YYYY/MM/DD hh:mm:ss
production:
  start_time: 2019/06/18 05:00:00
  end_time: 2019/06/18 06:00:00

手動の設定

手動のON/OFFはThorタスクを使うようにしました。誤って使われないように、こちらの機能は実行できる権限を持つ人を限定しています。

特定ユーザのアクセスを許可するための設定

メンテナンス中に開発者を含む特定ユーザがアプリケーションにアクセスして動作確認できるように、ホワイトリスト方式でアクセスを許可するIPアドレスやHTTPヘッダを指定できるようにしました。

# メンテナンスモードの有効・無効を設定する
# `start_time` `end_time` に記述する日時のフォーマットは以下の通り。タイムゾーンはJSTとする
#   YYYY/MM/DD hh:mm:ss
production:
    (snip)
    ips: ['XXX.XXX.XXX.XXX', 'YYY.YYY.YYY.YYY']
    header:
      name: 'X-Foo-Bar'
      value: 'value'

これにより、前述の

  • 開発者など、特定の条件を見たすユーザの場合は、メンテナンス中でも本番環境にアクセスして動作確認ができるようにしたい
  • 外部連携するシステムによっては、メンテナンス中でもアクセスを止めたくない

を実現しました。

実際の様子

f:id:mizukmb:20190702145424p:plain
メンテナンス画面

全てのページで上記画面を表示するようにしました。メンテナンス情報は別ページを見てもらうようにリンクを貼っています。サービスによってはツイッターの公式アカウントを載せているところもあるみたいです。速報値を伝えるためにこうした情報は外に置いておくことが重要だと思います。

HTTPステータスコードは 503 Service Unavailable を返しています。

おわりに

メンテナンスモードの仕組みについて紹介しました。調査の段階で得た気付きとして、他サービスのメンテナンス画面を調べようとしてもそんな都合良くメンテナンス中のWebサービスは見つからないということです。Herokuがメンテナンスモード機能2を提供しているため、社内のHeroku上で動いているサービスをメンテナンスモードにして参考にしていました。

採用

Misocaのサービスをメンテナンスしてくれる人を募集しています。

recruit.misoca.jp


  1. 根本原因を解決することも検討しましたが、一旦スコープから外しました

  2. https://devcenter.heroku.com/articles/maintenance-mode

画像を使ったテストでリリースサイクルをあげる

こんにちは、MisocaでAndroidアプリを作っている @k0matatsu です。

MisocaのAndroidアプリではリリース前に通常10営業日のテスト期間を設けています。
おおよそ1ヶ月に1回リリースを行っているため、開発期間の半分がテストに費やされていることになり機能追加にさける時間が圧迫されています。

そこで、品質を落とさずにテスト期間を圧縮するために画像のdiffによるテストを導入しました。
これにより表示を確認するテストケースは大幅に削減できます。

spoonを使ったスクリーンショットの取得

f:id:komatatsu:20190624193113j:plain

画像のdiffによるテストを導入するためにspoonというソフトウェアを使いました。
これはAndroidの開発を行っている人にはポピュラーな選択肢だと思います。
この記事では詳しい使い方などは説明しませんが、ネットにたくさんの知見がありますので興味を持たれた方は調べてみてください。

espressoやUI Automatorを使って画面表示や遷移を行い撮影したい状況を作り、spoonを使ってキャプチャするという方法でスクリーンショットを撮影しています。
撮影されたスクリーンショットはdiffの比較がしやすいようにスクリプトでまとめています。
本当はreg-suitなどを使って見やすくしたかったのですが、最初から完璧をめざしているとなかなか導入できないので、ひとまずgithub上で見比べることができることをゴールとしました。

ほかにも次の点については導入段階では対応しない判断を行いました。

  • 通信処理のモック化
    • これはチャレンジしていたのですがハマってしまったので諦めました
    • スクリーンショットの撮影は日に何度も行うわけではないので決まった環境で実施する運用でカバーするものとします*1
  • 画面表示のバリエーション網羅
    • 税の設定や金額で多岐にわたるバリエーションがあるため断念しました
    • 徐々に範囲を拡大したいと思っています

一方で、テストの安定性については妥協せず進めました。
UIの絡むテストだと表示の待ち合わせなどで成功率がさがりがちですが、偶発的に失敗するテストは信頼感を損ないます。
テストが信頼できないと人間による確認の手間が発生してしまい、メリットが薄まってしまうのでこの点はこだわりました。
今はテストコードが原因で偶発的に失敗するようなテストはリポジトリにありません。

恩恵について

この画像のdiffによるテストが適用されたバージョンはまだ開発中なので具体的に何日短縮できたのかはまだ明らかになっていませんが、多くのテストケースが削減できそうなので期待を寄せています。
テスト工数の削減はリリースサイクルをあげるだけでなく、人間でないと判断が難しい作業にリソースを集中させられるメリットがあります。
UIテストにおいてテストケースのメンテナンスコストがよく問題視されますが、毎バージョン変更が入るような画面はほとんど無いはずです。
テストが自動化されることで些細な変更でも「変更した部分だけ確認しよう」ではなく、すべてのテストケースを確認しやすくなります。
このような変化が品質の底上げにつながると信じています。

MisocaのAndroidアプリもカバレッジはまだまだ低いですが、効果の高い部分から地道に自動テストの範囲を拡大しています。
私はこういった基盤的な作業が好きなのですがMisocaにはAndroidエンジニアは私しかおらず、普段はサーバーサイドエンジニアに手伝って貰っています。
たしかに品質も大事なのですが、フリーランスの商取引における課題はまだまだ山積しています。
これらの課題を解決し、フリーランスの方々が安心して自分の業務に集中できる環境を構築すべく新たな機能の設計開発にももっともっと取り組みたいと思っています。

Misocaでは私の背を守りバリバリと価値を形にしてくれるAndroidエンジニアを募集しています。

recruit.misoca.jp

Twitterなどでお声がけいただければ普段の様子などお話できますのでぜひご気軽ににお声がけください。

追記: テスト対象とした画面について

Twitterにて対象とする画面について質問がきたのでこちらに追記します 。

画像のdiffによるテストの導入は普段の作業の合間に少しずつ進めていました。
この作業に割ける時間は少なかったので、テストを書いてもすぐ修正することにならないように、変更頻度の低そうな設定画面のキャプチャからはじめました。
次いで全画面のファーストビューのスクリーンショットを撮ろうとしているのが今の状態です。
今後は再現させるのが難しいエラーの表示から優先的に範囲を広げていこうと思っています。
これは元の目的がテスト期間の削減なので、簡単にテストできる正常系よりも再現手順の面倒な準正常系を自動化したほうがテスターの負荷がさげられると考えているためです。

*1:ユニットテストは既にモック化されているのでこの判断になりました