Photoruction工事中!

Photoructionの開発ブログです!

【ノーコード】Slackで最もバリュースタンプが押されている人を表彰できるようにしてみた

f:id:photoruction_tech_blog:20211220100258p:plain

フォトラクション採用責任者の野田です。アドベント・カレンダー18日目の記事として、「SlackでValuesスタンプが誰のどんな投稿に押されているのか数えて、獲得数が多い人を表彰できるようにしてみた」というネタを思いつき、Botを作ってみました。

 

GASなどは使わずノーコードで作成できるので、世の中のValues定着に頭を悩ませている人事担当の方のお役に立てれば嬉しいです!

Valuesのスタンプを数えようと考えた背景

フォトラクションは7月にValuesの再策定を行いました。これまで書籍を題材にしてValuesの元となる価値観の勉強会をしたり、締め会ではValuesの体現者を表彰するなど、組織にValuesを定着させるために連続的に施策を行ってきました。

結果として、Valuesを目にする頻度が増えて慣れてきた部分はあると思います。

 

しかし、Valuesは日々の業務の中で使われてこそ意味があります。そこで、日々のSlackの中で誰のどんな行動がValuesの体現として称賛されているのか可視化出来ないかと考えました。

また、スタンプが集まると称賛されるらしいという文化を作ることで、積極的にValuesを体現しよう、仲間のValuesを体現した行動を称賛しようという風にベクトルが向かうと良いなとも思っています。

可視化のためのアプローチ

  • Zapierを利用しValuesのスタンプをトリガーとしてスプレッドシートにデータベースを構築する
  • 関数を駆使してデータベースを整形し、スタンプを獲得している数が多い人と投稿を毎月自動的にソートする
  • Slackのワークフロービルダーを使い、スプレッドシートから取得した情報を取り込んだ文章を、任意のチャンネルに日付をトリガーとして投稿する

アウトプットのイメージ

こんなポストを毎月指定の時期に自動投稿する

f:id:photoruction_tech_blog:20211215103557p:plain

Zapierを利用しValuesのスタンプをトリガーとしてスプレッドシートにデータベースを構築する

(1)Slack上で押されたValuesのスタンプをトリガーに設定する

みなさんZapierはご存知でしょうか。ノーコードで様々なアプリと連携して自動化をしてくれる便利なサービスです。ZapierでSlackとGoogleスプレッドシートを連携させてまずはデータベースを作成します。

①タイムスタンプ②押されたスタンプ③スタンプを獲得した人④スタンプが押された投稿の4つが格納されていれば今回の目的は果たせるため、指定されたスタンプ(今回は各Valuesのスタンプ)が押されると、上記4つの情報をスプレッドシートにセル追加するように設定をします。

NewReactionAddedをトリガーとして設定します。

f:id:photoruction_tech_blog:20211215103628p:plain

トリガーに設定するスタンプを設定します。画像では最速挙動のスタンプを設定していますが、後ほど全てのスタンプで設定をする必要があります。

f:id:photoruction_tech_blog:20211215103647p:plain

 

この時、チャンネルを指定すれば任意のチャンネルのみで集計、指定しなければ全チャンネルで集計となります。

例えばValues用のチャンネルを作って公式に「このチャンネルでのスタンプは集計して表彰に利用します」とアナウンスすることで、そのチャンネルに注目を集めるやり方もあると思います。今回は全てのチャンネルで集計しています。

これにてトリガーの設定は完了です。

(2)必要な情報をスプレッドシートに送信し、データベースを作成する

(1)でトリガーを設定したら、今度はスプレッドシートに送信する設定です。+のボタンを押してステップを追加してGoogle スプレッドシートを選択します。先程のデータをスプレッドシート上に追加したいので、アクションは「2. Create Spreadsheet Row in Google Sheets」を選択してください。

f:id:photoruction_tech_blog:20211215105015p:plain

手順に沿ってアカウントを設定して、データを蓄積するシートを選択します。(シートは事前に作成しておきます)送信するデータは以下の4つです。

1.Message User Name

2.Message Ts

3.Reaction

4.MessageText

f:id:photoruction_tech_blog:20211215105123p:plain

以上でZapierの設定は完了です。これでSlackに指定されたスタンプが押される度にスプレッドシートにデータが飛ぶようになりました。

関数を駆使してデータベースを整形し、スタンプを獲得している数が多い人と投稿を毎月自動的にソートする

続いて、データベースを整形してSlackに自動投稿を飛ばす準備をします。ここまでで、スプレッドシートには以下のようなデータベースが出来ています。

f:id:photoruction_tech_blog:20211215105406p:plain

方針としてはシンプルにCOUNTIFS関数を使って当月に追加されたデータを数えて、Rank関数で順位付けしQuery関数を使って抜き出します。

大きく以下の手順です。

【下準備】

①元データを参照し、編集用のデータベースを作成する

②COUNTIFS関数で拾えるようにタイムスタンプを変換する

【スタンプを集めた人を集計する】

③COUNTIFS関数で当月に獲得したスタンプの獲得数を数える

④Rank関数でランク付けする

⑤Query関数で1位の投稿を集める

【スタンプを集めた投稿を集計する】

⑥Query関数で当月にポストされた投稿を抜き出す

⑦UNIQUE関数で⑥を列挙し、COUNTIFS関数で集計し、Rank関数でランク付けする

⑧Query関数で1位の投稿を集める

※⑦と⑧は上と同じ手順です

【下準備】

Zapierから飛ばしてきたシートに関数を事前に入れておいても、最下部にセルが追加されたタイミングで下部の関数が削除されてしまうため、編集用のシートを用意します。

シンプルに(='DB'!)でセルを参照するだけだと同期性が悪く、毎回セルを上書きしないとデータが最新に更新されなかったので、より同期性が強いIMPORTRANGE関数を使います。

f:id:photoruction_tech_blog:20211215110621p:plain

一番左上のセルに関数を入力すると、指定したURLの指定したシートの情報を自動で同期してくれます

任意のスプレッドシートのシートをまるっと参照できる便利な関数で、シートごとに権限を分けたいときなどに役立ちます。(詳しい構文などは既出の記事に譲ります)

続いて、Zapierで飛ばしたタイムスタンプですが、このままだと何のことかわからないためyyyy/mm/ddの形に置き換えます。これは後ほどCOUNTIFS関数で拾うために必要な処理です。

f:id:photoruction_tech_blog:20211215110824p:plain

タイムスタンプのままだと1636934988等の数字の羅列ですが、処理を入れると2021/10/25という日付になります。

詳細かっ飛ばしますが、=(B2+32400)/86400+date(1970,1,1)という処理を入れてください。こうすることでタイムスタンプが現在の日付に変換されます。詳しくはこちらの記事を

後ほどの行程でCOUNTIFS関数を利用して当月の投稿を集計するのですが、その際に各投稿の年と月を条件で設定する必要があるため、yyyy/mm/ddに変換したら年、月の列をつくってYear関数とMonth関数でそれぞれ月と年を抜き出しておいてください。

f:id:photoruction_tech_blog:20211215111117p:plain f:id:photoruction_tech_blog:20211215111108p:plain

こんな感じになります。空白がエラーになるのを防ぐためにIF関数を入れているためわかりにくいですが、シンプルにYEAR関数とMONTH関数を使っているだけです

【スタンプを集めた人を集計する】

続いて当月にスタンプを集めた人の集計を行います。ここまでくればあとは結構シンプルです。集計用の新しいシートを作り、オーソドックスに一番左側の列に集計したい人名、一番上のセルに集計したいスタンプ名を設定して、COUNTIFS関数でDBから数えていきます。

f:id:photoruction_tech_blog:20211215111207p:plain

こんな感じです。

以下2点ワンポイントです。

①UsernameはUNIQUE関数で自動取得させる

f:id:photoruction_tech_blog:20211215111234p:plain

人名の列挙は自動的に行いたいので、DBのUsernameの列をUNIQUE関数で検索させると良いと思います。こうすることで、新しいユーザーが追加されても自動的に一番左の列に追加されるので手動を挟む必要がなくなり自動BOT化できます。

②日付はtoday関数を参照させる

f:id:photoruction_tech_blog:20211215111339p:plain

このシートのそもそもの目的は、毎月任意の日付になったらSlackのワークフローを使って自動投稿をさせることです。したがって、Slackに投稿する時の日付でカウントされている必要があります。

そこで、適当な場所にtoday関数で現在の日時を表示しておき、year関数やmonth関数を使って現在日時を表示し、COUNTIFS関数で条件を拾うときに、ここの日付を拾うようにしましょう。当月ではなく前月の数字を集計したい場合は=MONTH(TODAY())-1 のようにしておけばOKです。

【スタンプを集めた投稿を集計する】

先程は一番左の列をusernameにしてCOUNTIFS関数で集計しましたが、今回は一番左の列を投稿にして集計していきます。(その先でやることは同様なので省略します。)

f:id:photoruction_tech_blog:20211215111424p:plain

投稿文を一番左の列に自動で集めるやり方として、今回はQuery関数を利用します。

Query関数はデータベースの中から「○列の値がXXの時、△列の値を返す」といったことができる便利な関数です。例えば先程のデータベースから「F列が2021年、G列が12月のとき、投稿のセルの値を返す」ということが出来ます。

 

このQuery関数にUNIQUE関数を加えることで当月に投稿されたポストの原文を重複なく列挙することが出来ます。

Query関数の構文は自由度が高く長くなるので、こちらの記事をご参照ください。

最後にRank関数で数えたスタンプの数を順位付けします。

【Slackに投稿できる形に整える】

この後の行程で、Slackのワークフロービルダーを活用して投稿文を作るのですが、その際に参照できる形にシートを整えましょう。

一番上のセルに順番に項目を記載して、その下に各項目の一番のデータを返しておきましょう。前までの行程で作ったシートをQuery関数で検索させるのが一番楽だと思います。

f:id:photoruction_tech_blog:20211215112108p:plain

Slackのワークフロービルダーを使ってスプレッドシートの値を取得し、自動投稿する

ここまできたら後は簡単です。Slackにはワークフロービルダーという機能があり、様々なものをトリガーに自動投稿するBotを作ることができます。

今回は「毎月最初の月曜日」をトリガーとして、ここまでのプロセスで作成してきたスプレッドシートから値を取得し、文中に挿入して自動投稿文を作成しました。

雷のマークからワークフロービルダーを立ち上げて

f:id:photoruction_tech_blog:20211215112139p:plain

参照するスプレッドシートや参照したいセルを選択します

f:id:photoruction_tech_blog:20211215112157p:plain

すると、スプレッドシートから取得した値を変数として文中に挿入できるようになるので、挿入しながら文章を作成します。

f:id:photoruction_tech_blog:20211215112223p:plain

保存したら完成です!

これで毎月決まった時期がやってくると、前月に各Valuesスタンプを最も獲得した人と投稿を調べて自動投稿してくれるbotが完成しました。

ノーコードでも簡単にBOTは作れる!

Zapierを利用することで簡単にデータベースを作成することができるので、多少スプレッドシートの作法に慣れている人であればアイディア次第で簡単にこのようなBOTを作ることが出来ます。

ちなみに、Zapierの無料プランではなんと月に100回までしかスタンプを数えてくれないので、本格導入される方はお気をつけください,,,(約2,000円で750回、5,000円で2,000回数えられるので許容範囲かなと思います)

フォトラクションのValuesが気になるよという方は是非以下の記事もご覧ください!

 

 

それでは!

 

株式会社フォトラクションでは一緒に働く仲間を募集しています


 

これまでに感じたQAエンジニアと他エンジニアの相違(QA視点マシマシ)

こんにちは!株式会社PhotoructionでQAエンジニアをしています日隈です。 Photoruction Advent Calendar 2021の17日目の記事です。

そもそもQAとは


QAという職種に馴染みのない方もいらっしゃるかと思いますので、軽く解説をしておきたいと思います。 QAは「Quality Assurance」の名の通り、品質保証を担当するエンジニアです。 「品質保証」と言っても会社や組織によって求められるものや方向性がわりとばらっばらなので「こういうお仕事です!」と断言しづらい部分はあるのですが、ユーザーが問題なくソフトを使用できることを担保するというのが基本的な業務になります。

具体的には概ね以下の業務が多いですね。

  • 企画の要件定義の際に「それいる?」「ユーザー使いにくくなってない?」と文句をつける
  • 開発エンジニアが作ってきたものに対してテストを実施してダメ出しする
  • テストで見付けた、細かくて要件が定まっていない部分に対して「こうしたほうが便利ですから!」と押し切る
  • リリース後のプロダクトをいじった際に感じたことを「やっぱここ変えたほうがよくね?」と言ってねじ込み、開発の仕事を増やす

以上を踏まえてQAエンジニアと一般的な開発エンジニアがどう違うのかというところを、QA歴10年ちょいの私の視点から見ていきたいと思います。

(かなり個人的な偏見が入っており、必ずしも全ての事例に当てはまるわけではないのでその点予めご了承下さい)

目次


1.QAは無産階級

2.QAは保守的

3.QAは大雑把

4.QAは細かい

5.まとめ


 

QAは無産階級


文字通り、QAエンジニアは単体では何も産み出せません。 「ユーザーが問題なくソフトを使用できること」を確認するのが業務である以上、大前提として誰かが何かを作ってくれないとそもそも仕事が始まらないのです。

その点開発エンジニアは自身の力でコードを書いて作るべきものをを作ることが可能です。凄い。

そんな皆様の作り出したものをテストという名の棍棒でぶっ叩くのが我々QAのお仕事なのです。 この点を指して、俗に「開発は創造者、QAは破壊者」などと言われることもありますね。

口さがない人からは「QAは寄生虫」なんて言われますが、泣いちゃうので面と向かっては勘弁して下さい。

 

QAは保守的


全てのQAがそう考えているというわけではないのですが、QAというものはわりと少なくない比率で「現状で問題なく使えているもの」に対する変更を忌避する習性を持っています。 過去の経験でいうと、「appのリニューアル&話題作りのため、UIどころか導線から何から全てガラッと変えましょう!」という案件に対して明確かつ強固な反対意見を出したのはQAだけでした。

開発エンジニアは新しい技術をキャッチアップしていく必要があるためか進取の精神を持っている方が多く、変化に柔軟に対応する方が多いように感じます。 対してQAの判断基準は「既存を含むユーザーが使えるか使えないか」という点が非常に大きいため、見た目上の変更はなくとも今まで問題なかった箇所にバグが発生する可能性のあるバックエンドの改修やデザイン大幅変更による既存ユーザーの使用感切り捨てなどにはどうしても抵抗したくなるのです。

決してスモーク/リグレッションテストを作り直すのがめんどくせぇなどという理由ではない点ご承知おき下さい。

 

QAは大雑把


これまでのところでも書きましたが、QAはユーザーのポジションでの「使えるか使えないか」が判断の基準です。 そのため、裏側で何がどうなっているかなどはまず確認しません。 めっちゃコードが汚かろうが、何かよく分からん処理が走ってようが、それが表に出てこない以上一切気にしません。

たまに開発の方が「問題なく動いてるけどちょっとコードがとっちらかってるので整理しますね」的なことを仰るのを見たりするのですが、個人的には現状でも大丈夫なのにわざわざ整理するなんてマメな方なんだなー、きっとお部屋も整理整頓出来る人なんだなーという尊敬の目で見ています。

 

QAは細かい


上の内容と相反してそうですが実は並列であり得るのです。

前項の通り裏側なんか気にしないQAですが、それはつまり表に出てきたものに関してはめっちゃ気にするということなのです。 toCtoB、ユーザー層がどのあたりかなどターゲットによっても変わるのですが、場合によってはデザイン確認において1pxのズレも許容しないなんてこともあります。

この辺開発の方からすると意味分からんと言われることもありましたね。 自分でもたまに意味分からんです。

 

まとめ


思いついたことをつらつらと書いてみましたが、QAエンジニアと他エンジニアの違いで一番大きいのはやはり「作る側か否か」という点かなーと思ってます。 「作る側」と「使う側」という根本的な相違からスタンスや視点の差も生まれてきてるように感じますね。

そんなわけで会社によってはQA vs 開発みたいな空気になることもあったりするのですが、今回の記事が相互理解に繋がるととても嬉しく思います。

ご精読ありがとうございました。

 

 

株式会社フォトラクションでは一緒に働く仲間を募集しています 

Androidアプリのアーキテクチャの現状

Androidアプリ開発者の久木田です。

この記事はPhotoruction Advent Calendar2021の16日目です。

まずはこちらの記事をお読みください。
また、この記事はあえてネガティブなことを抜き出して書いています。記事を読むタイミングによっては改善済みの場合もあります。

TL;DR

理想を決めたけど、あれもこれもまだまだダメダメです。

ただし、よくなる兆しも、よくしていく動きもあります!

これからのPhotoruction Androidアプリにご期待ください!

第1段目のゴール目標と現在

第1段目のゴールは「秩序をしっかり作って、秩序に慣れてもらうこと」です。

それで、今どうなの?というと、

  • 設計方針については理解できてるし、新しいものはそれに沿って作れているしリファクタする時も沿えている
  • ただ、これまでに作られた膨大なコードについては全然まだまだこれから

というところです。

これからどれだけ全然まだまだなのかをいくつか数字を出しながら説明していきます。

ファイル数からわかること

種類 条件
Activity 63 ファイル名にActivityがついている
Fragment 73 ファイル名にFragmentがついている
ViewModel 59 ファイル名にViewModelがついている
  41 ↑のうち、ViewModelもしくはAndroidViewModelを継承しているクラスのあるファイル
Repository 27 ファイル名にRepositoryがついている
Realm 49 RealmObjectを継承しているクラスのあるファイル
Room 26 @Entityが付いているクラスのあるファイル

これだけでもわかることがいくつかあると思います。

  1. Realm / Roomのファイルに対してRepositoryのファイルが少ない → Repositoryを経由していないDBアクセスが大量にある
  2. Activityの数が多い → ViewがActivityに直接紐づいているものが多い
  3. ViewModelって名前なのにAACのViewModelを継承してないファイルが多くある(これはそういう方針なのであれば問題ないと思うが、そうではないので問題と認識している)
  4. ViewModelがActivity / Fragmentに比べて少ない→Fat Activity / Fat Fragmentになっている

ステップ数からわかること

種類 条件
平均 210.8 拡張子が.javaのファイルの行数の平均
  75.8 拡張子が.ktのファイルの行数の平均
中央値 92 拡張子が.javaのファイルの行数の中央値
  35 拡張子が.ktのファイルの行数の中央値
ファイル 19 拡張子が.javaのファイルの1000行を超えているファイル数
  0 拡張子が.ktのファイルの1000行を超えているファイル数
  1. 特にJavaのファイルに関して、ステップ数が多い → 適切な責務分けがされていない
  2. Kotlinのファイルは比較的新しいこともあり問題があるようには見えない → 当然見えづらくなってるだけで問題点のあるコード、ファイルはある
  3. 平均と中央値の差が大きいことから、とにかくステップ数が多いファイルがいくつかありそう

こちらはこういったところでしょうか

コードからわかること

まだまだアーキテクチャに沿えていないコードが多いです。

それは↑のところからわかることも多いですが、実際はそれ以上に、アーキテクチャに沿えていない ≒ Fat Activity / Fat Fragmentなので、責務の分割から始めることになったり、そもそも密結合すぎて大幅に書き換えないとアーキテクチャに沿えなかったりというファイルも多くあります。

また、コードとはまた違いますが、package構成もぐちゃぐちゃだったりします。

これもアーキテクチャを決めたタイミングでpackage構成を決めているので、とりあえずはAndroid Studioの機能を使いながら移動させるだけですが、1072ファイルあるのでそれだけでも大変です💦

そのほか、あげればキリがないほど課題はありますが、本当にキリがなくなるのでこの辺で

1年で良くなったこと

辛そうな話ばっかりだとアレなので、最後によくなってることを話して終わりにしたいと思います。

2021年(2020年からやってることもあるんですが)で改善したことも併せて記載しておきます。

アーキテクチャの導入

これまでは設計の「せ」の字もないコードだったのをアーキテクチャを決め、設計方針を固めて書くようになったので、責務の分かれたいわゆるいいコードに近づいたと思います。

CI/CD/GitHub Actionsの導入

CIやActionsはまだまだできることはあるのですが、Lintの指摘やビルドが問題ないかなどまだまだ基本的なことしかやれていませんが0→1の大きな変化だと思っています!

やれることはあるのでこれからもどんどん面倒なことを自動化させたいなと思います。

今はライブラリのアップデートがめちゃくちゃ面倒なのでCIで自動でPR作られるようにしたいなって思ってます。

テストの導入

テストに関しても、これまで全く書かれていませんでした。そもそも書けるようなコードになっていません。(これは現在進行形です)

なので、アーキテクチャを決めて、それによって責務分けをしたタイミングで、次はテストコードを書くぞと決めて、新しいところのViewModelなど書くべきところは書くようにし出しました。

こっちもまだまだこれからですが、TDD的な書き方をしたり、テスタブルなコードを書けるようにして、どんどんよくしていきます!

今後どうしていくのか

とにかく、今は少しでも多くのファイルをアーキテクチャに沿った構成に近づけることを最も優先しています。(開発の傍らですが)

まだしばらくそちらに時間がかかると思いますが、大方の対応が完了すると別のつらみが出てくると思っています。そうなった時にはまた新しい施作を実行して行きます。

来年のアドベントカレンダーでは別の課題の解決をしてるといいな

 

株式会社フォトラクションでは一緒に働く仲間を募集しています 

corporate.photoruction.com

www.wantedly.com

Photoruction Androidアプリのアーキテクチャとこれからについて

Photoruction Advent Calendar2021の15日目です。

はじめまして。Androidチームに業務委託としてかかわっている @kgmyshin というものです。

この記事では Photoruction Android アプリのアーキテクチャについて触れていきます。

経緯

PhotoructionのAndroidプロジェクトは、しっかりしたアーキテクチャやルールを設けるタイミングを失ったまま開発を続けてしまっていたため、無秩序気味のコードとなってしまっていました。

そもそも十分に知見がある人を採用できない中でスピードを出さないといけないケースもあるので、これ自体は別に責められるべきことではないです。

ただ結果としてみんなが思い思いのコードを書いてしまう。そして、コードの読解に時間がかかる、修正したいがそもそも影響範囲がめちゃくちゃ広いといったコードになってしまっているため、そこは今後の開発のために対処が必要です。

といった経緯もあり。わりかし知見がある私に「アーキテクチャの方針を決めてもらいたい」というタスクが降ってきたのでした。

ここら辺の現状については、あすの久木田さんの記事でもう少し詳細に書かれると思います。

アーキテクチャの選定のための要素

アーキテクチャ選定に至っては様々な変数があるのですが、その中でもとりわけ大きい変数は以下の二つです。

  • 作るアプリの複雑度や規模
  • チームの習熟度

作るアプリの複雑度や規模という観点について。Photoruction というアプリは、オフラインでアプリがしっかり動く必要があることと、機能が単純に多いという特徴があります。アーキテクチャは対象のアプリによって適切なものが変わってきます。

下記は アプリにおけるアーキテクチャを示したものではないですし、最近採用されるアーキテクチャではないですが、この図からは、複雑さによって適したアーキテクチャは変わってくるということがわかると思います。

f:id:photoruction_tech_blog:20211209142528p:plain

Martin Fowler著: Patterns of Enterprise Application Architecture より引用

肌感ですが。この図に Photoruction アプリを差し込むなら、かなり右の方によるアプリだと感じています。

チームの習熟度について。こちらは現行アプリがレガシーな技術であったり、そもそもアーキテクチャなどが導入されていなかったということもあり、 まだ アーキテクチャなどの精通しているメンバーは多くないというのが現状だと感じています。

まずは秩序だったアーキテクチャがあることに慣れてもらうフェーズ

以上のような要素の中、自分が選択したものは Android Developer サイトにアーキテクチャガイドのアーキテクチャを少しPhotoruction用にかみ砕いたものでした。

このアーキテクチャの特徴は、 ViewModel と Repository があるだけの単純なものです。

Photoruction用にかみ砕いて、実際には次のようなアーキテクチャになっています。

f:id:photoruction_tech_blog:20211209142545p:plain

Photoructionアプリは 、先にも述べた通り複雑度が高く規模が大きいアプリです。そのことだけを考慮すると、主観では この Android Developer のアーキテクチャは適していない、というか粒度が大きすぎて足りていない部分があります。

しかし、今回はチームの習熟度という要素を優先して、このアーキテクチャを選びました。

もし、チームの習熟度を無視して、粒度の細かい高難易度のものを選定してしまっても、学習コストが高くて、そこに自分ががっつりコミットする時間がないうえに、もしうまくコードが書けるようになっても、アーキテクチャの細部を理解するまえに「そういうもの」「おまじない」という扱いになりかねなくチームの習熟度への貢献には至らないと考えたためです。(今のところその予定はないですが)自分が抜けてしまっても大丈夫なようにするためには、チームの習熟度を高めることの方が重要なのです。

このアーキテクチャのゴールは「秩序をしっかり作って、秩序に慣れてもらうこと」です。

これが徐々に根付いていけば、例えばルールが決まってないところが出てきて、チーム内でコードの書き方等にブレが出てきた際に、チームでルールを決めようとする振る舞いが散見されるようになります。

まだまだ導入の道半ばですが、実際にそういうケースを見かけることが多くなってきてます。

あと、余談ですが、DIコンテナライブラリ等も使用しておりません。めんどくさいですが、手動で似たようなことを実現してもらっています。手動でやってるので、ゆくゆくは DI コンテナライブラリが何をやっていて、何がうれしいかを知って、導入しましょうという流れになるのかもしれません。

このアーキテクチャだと、まだまだ課題がたくさんあるよね?ってなった時が次のフェーズ

このアーキテクチャだと、まだまだ粒度が大きすぎて課題がたくさんあるよね、と課題を認識できるようになったら次のフェーズです。

では、次はどんなアーキテクチャにするのかについては、特になにも決めておりません。というより自分がすべてを決めるべきではないと感じています。アーキテクチャに沿って開発してきたが、そのアーキテクチャにはいろんな課題があった、じゃあどういうアーキテクチャがいいかをチームで考えてもらって、そこにその時のAndroidアプリ開発事情、チームメンバーの志向を取り入れて、議論する。可能な限り、その際にサポートしようと思っています。

株式会社フォトラクションでは一緒に働く仲間を募集しています。

playwrightを使ってWEBのE2Eテストを自動化してみた 〜失敗談編〜

こんにちは!株式会社PhotoructionでQAエンジニアをしています内田です。 Photoruction Advent Calendar 2021の14日目の記事です。

playwrightを使ってE2Eテストの自動化をすすめる上で失敗したこと・詰まったこととその解決策を記載していきます。 E2Eテストの自動化を検討中の方の役に立てたら幸いです。

目次


  1. 失敗したこと・詰まったことリスト
    1. 自動化の進め方・構成での失敗談
      1. テスト実行時間が長すぎる
      2. テスト実行がコマンド実行できる人しかできない
      3. テストのどの箇所で落ちたのかがわからない
      4. テストで実行している内容が実装者しかわからない
      5. テスト実行によりデータ量がどんどん増えてく
    2. playwrightの使い方での失敗談
      1. 実行環境によってキャプチャ差分が出ちゃう
      2. ファイルダウンロードできない
      3. モーダルが完全表示される前に次の操作をしてしまう
  2. まとめ

自動化の進め方・構成での失敗談


テスト実行時間が長すぎる

背景 : 「テスト用ユーザー増やすの面倒だし、とりあえず直列実行すればいいよね・・?」という軽い感覚で直列実行にしか対応しない記述の仕方をしていました。実行時間が長すぎてストレスを感じました。

対策 : テストを並列処理できるよう実装を変えました。

教訓 : 最初から並列実行できるようにしておくべきでした。並列処理を実装することにより実行時間が1/2程度に削減できました。

コマンド実行できる人しかテスト実行できない

背景 : playwrightはコマンドライン上で実行するツールです。テスターさんがE2Eテストを実行したいタイミングにテスト実行依頼するというフローを挟まないといけませんでした。

対策GitHub Actionsのワークフロー手動実行機能を使ってテスト実行できるようにしました。

テストのどの箇所で落ちたのかがわからない

背景 : テスト実行しfailedになってもどのステップで落ちたのかがわからない

対策 : ①アクションタイムアウトの設定にしました ②操作キャプチャ動画を残す設定にしました

テストで実行している内容が実装者しかわからない

背景 : たとえば「写真アップロードのテスト」でもどの写真をアップするのか、拡張子はなにか、ドラッグ&ドロップでアップロードするのか・・・などの操作詳細がテスト実装者にしかわからず、テスターさんへの共有ができてませんでした。

対策 : テスト実装前に自動テストでの操作詳細をドキュメントに記載しました。

テスト実行によりデータ量がどんどん増えてく

背景 : データ作成テストによりデータ量が増えていき、MAX登録数に達したり他のテストで参照されるデータが参照できなくなる自体が発生しました。

対策 : データ作成テストとデータ削除テストをセットで実施するようにしました。

playwrightの使い方での失敗談


実行環境によってキャプチャ差分が出ちゃう

背景 : 一部のE2Eテストで要素で判定できないテストがあり、画像比較テストを導入しています。当方の環境はMac/Windows上で開発&GitHub Actionsでテスト実行 という構成でした。Mac/Windows/Linux上で撮影したキャプチャに差分が出てしまいました。

Mac

f:id:photoruction_tech_blog:20211209142209p:plain

Linux

f:id:photoruction_tech_blog:20211209142235p:plain

差分

f:id:photoruction_tech_blog:20211209142257p:plain

結構差分ってあるんですね・・・。

対策 : ゴールデンファイル(正解とするキャプチャ)をDockerを用いてLinux上で撮影しました。

ファイルダウンロードできない

背景 : ダウンロードボタンをクリックする実装をしてもダウンロードが始まらず詰まりました。

対策 : オプションに説明がありました。ちゃんとドキュメントは見るべきですね・・・。

https://playwright.dev/docs/api/class-testoptions#test-options-accept-downloads

playwright.config.jsに以下の設定を追加しました。

const config = {
(略)
    use: {
        acceptDownloads: true,
    }
}

モーダルが完全表示される前に次の操作をしてしまう

背景 : 弊社のサービスはモーダルがゆっくり上から降りてくるアニメーションで表示されます。こんな感じです。

f:id:photoruction_tech_blog:20211209142358g:plain

モーダルがブラウザに表示された瞬間、つまり完全に降りきる前にモーダル内の操作が始まってしまい、テストが落ちることがよくありました。

対策 : モーダルの移動アニメーションが終わるのを待ちました。下記の記述を加えました。

await page.click('{モーダルを表示させるボタン}');
const modal = await page.$('{モーダルの要素}');
await modal.waitForElementState('visible');
await modal.waitForElementState('stable');
// 次の操作へ・・

まとめ


自動テスト未経験者が手探りで自動化を進めています。振り返ってみると詰まったことだらけでした。 自動化を検討している人やplaywrightを使っている人の参考になれば幸いです。

   

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com

playwrightを使ってWEBのE2Eテストを自動化してみた 〜導入編〜

こんにちは!株式会社PhotoructionでQAエンジニアをしています内田です。 Photoruction Advent Calendar 2021の13日目の記事です。

手動で実行していた最低限のリグレッションテストを自動化してみたのでその記録です。

目次


  1. 自動化しようとした背景
  2. 自動化してみた結果所感
    1. スムーズに導入できなかったよ
  3. 導入までの道のり
    1. ツール選定
    2. 自動テスト実装
      1. 実装詳細
  4. まとめ

自動化しようとした背景


  • 毎回同じテストの実施が面倒なのでなんとかしたい(これが1番)
  • テスト工数削減

の目的で自動化を検討しはじめました

自動化してみた結果所感


playwrightの導入はスムーズにできました!

が、テスト実装がスムーズできませんでした・・・(詳細は次の記事へ)

導入までの道のり


ツール選定

世の中には自動テストツールやSaaSがたくさんありますが、playwrightを選んだ理由は下記です

  • 自動テストの導入・実装が簡単なこと
    • テストコード自動生成機能があること
  • 手動で実行した場合と比較してコストが安くなること
  • 好きなときにテストをたくさん実行できること

自動テスト実装

インストール

$ npm i -D @playwright/test
$ npx playwright install

configファイル作成します。(なくてもOKです) テストの各種詳細を設定できます。 詳細は公式ドキュメントを参照ください。 以下おすすめの設定です。

// playwright.config.js

const config = {
    use: {
        browserName: 'chromium',
        video: 'on', 
        acceptDownloads: true,
        actionTimeout: 10000,
    },
    timeout: 40000,
    testDir: './testcase',
    expect: {
        toMatchSnapshot: { threshold: 0.2 }
    },
    maxFailures: 10
};

テストファイル作成

弊社サービスの写真機能の表示切り替えが有効かを確認するテストをサンプルで記載します。 表示切り替えボタンをクリックすると、写真一覧の表示がタイル表示⇔リスト表示に切り替わる機能です。 手動で操作すると以下の操作になります。

操作手順としては以下になります。 ①ログインする ②テスト対象ページをひらく ③切り替えボタンをクリック ④切り替えボタンを再度クリック テストコードは以下です。

//testcase/photo.test.js

const { test, expect } = require('@playwright/test');
const path = require('path');

test.beforeAll(async ({ browser }) => {
    let context = await browser.newContext();
    let page = await context.newPage();
    {{ログイン処理}} ・・・手順①
    // ログイン情報を保存
    await page.context().storageState({ path: path.join({{保存先のパス}}, 'strageState.json') });
        {{対象の画面への遷移など事前準備をしておく}} ・・・手順②
    await context.close();
});

test.describe('写真機能', () => {
    test('表示形式が変更できるか', async ({ page }, testInfo) => {
        await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        await page.click('#change_display'); ・・・手順③
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title, {{実行環境情報}} ,'表示形式リスト.png']);
        await page.click('#change_display'); ・・・手順④
          await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title,  {{実行環境情報}}, '表示形式タイル.png']);
    })
});

テスト実行

$ npx playwright test

※テスト初回実行時のみ、キャプチャのゴールデンファイル(正とするファイル)が生成されます

実行結果

こんな感じの出力になります configで指定したフォルダ配下に.webmの拡張子でキャプチャビデオが生成されています キャプチャビデオはこんな感じです。 test()で囲った部分から操作キャプチャが開始されます。

まとめ


playwrightを導入すること自体は簡単でした。 目的であった手動テスト工数削減も少しずつですが達成できています。 今後は自動テスト項目数を増やしたり、メンテナンスしやすいコードにしたいと考えています。 機会があればCIでのテスト実行方法も記事化したいです。

この記事の続きはこちら kojichu.photoruction.com

   

株式会社フォトラクションでは一緒に働く仲間を募集しています www.wantedly.com

corporate.photoruction.com

gatherで「ちょっと、いいですか?」ができる空間を作った話

こんにちは!株式会社フォトラクションでWebエンジニアをしている田中喜規です! Photoruction Advent Calendar 2021の12日目の記事です。

 

2020年からテレワーク環境が続いていますね。

 

これまでのようにオフィスに出社ができない状況だと、社内のコミュニケーションの絶対量は少なくなってしまいますよね。

おそらく、どの会社でも、こうした悩みや課題があるのではないでしょうか。

 

今年から、PhotoructionのWebエンジニアチームでは、gather.town(以下gatherと省略)というツールを使って、チームのコミュニケーションを促進しようと頑張っていました!

 

 

目次

 

gatherとは?


ポケモンドラクエを彷彿とさせる、レトロなUIで、さまざまなスペースを選択し、複数人のユーザーがチャットやビデオ通話ができるサービスです。

 

出社時と同じ感覚を得られる

Zoomやgoogle.meetは、URLリンクから参加できる人全員が一律同じ空間で、会話ができるものとなっていると思います。いわゆる、「Web会議ツール」ですよね。

 

gatherは、Web会議だけではなく、もっと用途が広いです。

Photoructionでは、以下のように、社員1人1人が部屋を作って、作業。

 

用がある時に、他メンバーの部屋を訪ねるようなイメージです。 「オンラインオフィスサービス」として利用してます。

f:id:photoruction_tech_blog:20211203104027p:plain

(私田中の自室です笑。宇宙船内で、ソロキャンプをしています)

パーソナルスペース

gatherでは、以下の状況で会話に参加ができます

  • 一定の距離感にいるか
  • パーソナルスペースにいるか
  • パブリックスペース(大部屋など、全員にアナウンスできる場所)

 

パーソナルスペースは、Zoomやgoogle.meetのように、同じ空間にいるメンバー全員に会話が聞こえるということはなく、オフラインの出社と同じ感覚で、ある一定の距離感の範囲内でないと会話が聞こえない仕組みとなっています。

 

実際のオフィスで、会議室を利用して打ち合わせを行う要領で、メンバー複数人で会話が可能です。打ち合わせが終われば、そのまま、自室に帰って各々の業務に戻る形で運用しています。

f:id:photoruction_tech_blog:20211203104441p:plain

ちょっと、いいですか?ができる空間を作りたい


元々、弊社のWebエンジニアチーム内の課題として、コミュニケーションが希薄になっていることが課題の1つとしてありました。

 

現在Photorucitonのエンジニアチームは、完全リモートでの働き方となっています。

定例やPJごとのミーティングがない限りは黙々と、業務を進めていくことになります。

勿論それはそれで利点になっているのですが、チーム全体でものづくりをしている意識や、困ったときに、助け合いができるような連帯感が薄いことに課題感がありました。

 

オフィスワークでよくある、隣のメンバーへの「ちょっと、いいですか?」ができれば、それだけで問題が解決することも、リモートワークでは時にはgoogle.meetで開催をセッティングし、slackで質問内容を考え、送信することが必要になります。

 

また、日々のちょっとしたやり取りから、メンバー間の関係性ができて、より良い職場環境となることも、リモートワーク環境以前では、当たり前のように生まれていたと思います。

 

そんな、「ちょっと、いいですか?」ができる環境づくりに適しているツールとして、gatherを活用していく運びになりました。

gather内でやったこと


用途は多岐に渡り、さまざまな楽しみ方ができます!

  • ランチ会(Webチーム内で週一)
  • bug bash(Photoructionのバグを社内で見つける月一イベント)
  • オンライン飲み会(不定期)

bug bashの時の様子

f:id:photoruction_tech_blog:20211203104512p:plain

 

無人島で、オンライン飲み会を開催(パブリックスペースがなく、密になりながら乾杯)

f:id:photoruction_tech_blog:20211203104536p:plain

実際、効果はあったか?


田中の独断と偏見だと、かなり働きやすくなったと思いました!

話しかけにいっていいんだ!って安心感を得た部分があり、「聞くハードル」が下がったように思います。

 

また、slackで何か問題が流れてて、gather内でその件について話をしていたりすると、

それを聞きつけて、他メンバーが心配して、覗きにくる場面もあったので、「コロナ前のオフィスワーク」にかなり近い雰囲気、連帯感も感じられました。

 

Webエンジニアチームに関わらず、他部署のチームも気軽に話しかけに来てくださることもよくあるので、間違いなく、コミュニケーションは増えたと思います!

 

コミュニケーションの問題なので、ツールを導入して解決!ということはないですが、解決のひとつのきっかけになるかもしれないので、個人的にはおすすめです笑。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています