こんにちは、データエンジニアリングチームの宮崎です。この記事は、UniFaアドベントカレンダー2020の21日目の記事となります。 最近、文字を自由に編集できるLINEスタンプがあることを知りました。いつの間にか色々進化していますね・・・! そこで今回はDeepLearningのモデルを使って、以下のように写真からLINEスタンプ風画像の自動作成を行ってみたいと思います。
続きを読むリスクベースドテストやってみた話
ごあいさつ
こんにちは!ユニファアドベンドカレンダーをご覧頂きありがとうございます! ユニファQAチームの斉藤です。 このブログは、UniFaアドベントカレンダー 20日目となります。
今年はコロナで大変な1年でしたね。ユニファQAチームも今年の早い時期からフルリモートに切り替えて活動を行ってきました。もともとリモート勤務可能ではありましたが、案件が去年の2倍以上に増えたり、メンバーの入れ替わりがあったりしたので、フルリモート体制で乗り切るには大変な1年だったなぁと感じています。
そんな中ですが、新しい取り組みにもチャレンジしてみました。リスクベースドテストです。 今回はそこから学んだことをふりかえってみたいと思います。
新しい取り組み 「リスクベーステストを始めよう!」
冒頭のごあいさつさらっと記載しましたが、今年はテスト案件が去年に比べて大幅に増えました。
去年までは当時のQAチームメンバーでもなんとか回せる量だったのですが、今年の春頃から数か月規模の案件が並行で走り、秋頃からさらに増えて、現在は多くの案件が並行して動いています。案件が増えることは計画内だったので、今年の春頃から「案件が増えた時にそなえて、テストを考えねば」という話題はチーム内であがっていました。
そこで当時のQAチームリーダーから提案されたのが、リスクベースドテストでした。
リスクベーステストって?
では、リスクベースドテストとは何でしょうか。
JSTQB用語集で引くと、以下のような記述が出てきます。
リスクベースドテスト(risk-based testing): プロジェクトの初期段階からプロダクトリスクのレベルを低減させ、ステークホルダにその状態を通知するテストの方法。プロダクトリスクの識別の他、テストプロセスをガイドする際のリスクレベルの活用もこれに含まれる。
プロダクトリスクというものを識別し…テストプロセスをガイドする…なるほどわからん。
私の理解をざっくりいうと、要はプロダクトリスク(そのプロダクトで起きてほしくない事象)の重大度と発生率を整理して定義し、それに基づいてテストする機能やしない機能を選んでいく、というテスト戦略です。
プロダクトリスクのリスクタイプやリスクレベルも、以下のようにリーダーの方で定義して頂いたので「それに基づいてテストする機能やしない機能を選んでいくのだよ」の具体的な方法を、いよいよQAチームメンバーで考えていくことになりました。
ユニファQAチームで取り組んだやり方
ユニファQAチームは、メンバーによってテスト設計から実装までのやり方が少し異なります。このリスクベースドテストを導入しようとしている時は、複数プロダクトにそれぞれメンバーが分かれてアサインされていました。 いつもだと、それぞれのプロダクトに合わせてメンバーがテスト設計をしますが、このリスクベースドテストを導入するなら、複数プロダクト統一したやり方じゃないとレビューがしにくいな~と考えました。
そこで複数プロダクト間である程度、統一できるやり方として、テスト観点を抽象化したリスク設定要素、基本リスクレベル、補正リスクレベルという項目を使ってみようと考えました。
リスク設定要素
リスク設定要素とはいわゆるテスト観点です。 ユニファQAチームで行うリスクベースドテストでは、このテスト観点をできるだけ抽象化したものをリスク設定要素と名付け、これに重みづけすることで「テストする機能やしない機能を選ぶ」ことをやってみようと考えました。
このリスク設定要素(テスト観点)は、ユニファQAチームメンバーの認識をそろえるため、全員参加でマインドマップを使ってブレストして決定しました。
基本リスクレベル
次に基本リスクレベルです。 基本リスクレベルとは、リスク設定要素の基本的な重みづけです。 リスク設定要素とリスクタイプでマトリクスを作り、QAチーム全員で話し合いながら1~5点の間で点数をふっていきました。(5点がリスクとして一番重い点数です) 全てのリスク設定要素に基本リスクレベルとして点数を設定したら、次にそれを、プロダクトリスクレベルへマッピングを行いました。 リスク設定要素のもつ下限値~上限値を均等にリスクレベルへわりつけ、該当するリスク設定要素をマッピングして、QAチームで眺めてみました。 結果、リスクレベルとリスク設定要素の組合せに違和感はないね!ということで、基本リスクレベルの設定が完了できました。
補正リスクレベル
基本リスクレベルの設定が完了しました。この後のフローとしては、機能・画面ごとにリスク設定要素をあてはめて、QA保証対象以上のリスク設定要素のみに対しテスト設計をしていく、という形にいったん整いました。
ただ機能・画面によっては、リスク設定要素(基本リスクレベル)通りにあてはめてしまうと、具合が悪いというものもあります。 たとえば、リスク設定要素の「バリデーション」や「画面UI」は、QA保証対象外ですが、機能・画面のビジネス的な重要度によっては、QA保証対象とした方がよいこともあります。
これを補うために、補正リスクレベルを使うことにしました。 補正リスクレベルとは「基本リスクレベルを見ると、QA対象もしくは対象外だけど、担当QA判断によってレベルを調整してよい」というものです。
レビュー時にレビューアに対して「ここは重要もしくは重要でないと判断したから、確認してくれ」というアピールとしても使えると考えました。
リスクベースドテストやってみた結果
やってみた結果は以下です。
①工数はあまり削減できなかった
②短期間のテスト実行で、重要度の高いバグが検出できた
①については、もともとリスクベースドテストは「工数削減」が目的ではなく、「少ないリソースで品質を担保するためにテストするしないをプロダクトリスクに基づいて決めていく」やり方なので正しいのですが、今回は「テストしない」と決めた部分についても
- QAチーム以外にテストしてもらおう!
- QAチーム以外にテスト依頼してOKもらったが、「テストするからチェックリスト下さい」となりQAチームにタスクが戻ってきた!
という動きをしてしまい、結果、QAチームはQA保証対象外のリスク設定要素についても、なにがしかの形でテスト設計することで工数削減効果はあまりなかった、という結果になりました。
リスクベースドテスト時、工数も適正な量に抑えたいのであれば、QA保証対象外部分については「やらない」という選択をすること、「やらない」代わりに問題発生した時はどのようにするか等をステークホルダーと話し合っておくことが必要そうだな、と感じました。
②はまさに、リスクベースドテストで狙いたいところだったので、満足いく結果でした!
これから
リスクベースドテストをやってみたのは2020年初夏~秋頃のテスト案件なのですが、現在ユニファQAチームではリスクベースドテストを行っていません。
理由としては、案件がさらに増えたため外部QA会社さんに入って頂いたりと大幅なQA体制変更があったこと、並行して複数案件が走っているので日々変わりゆく状況変化に対応することの方が、QAチームとしても重要になっているためです。
ユニファQAチームって、品質をあげるための活動は何でもできることが魅力です。 今はQA体制の安定化に力を入れていますが、いつかリスクベースドテストももっとブラッシュアップした形で取り組みたいと思っています!
ここまでお読み頂き、ありがとうございました! まだまだコロナで大変な時期続きそうですが、体調に気をつけて、元気にQA&テストエンジョイしていきましょうね!では!
ユニファQAチームではQAエンジニアさん、テスト自動化エンジニアさんを大募集しています!
カジュアル面談も大歓迎です!
「ちょっとならお話してあげようかな」って思われた方はWantedlyの求人ページから「話を聞きに行きたい」ボタンをクリックお願いしまーーーーーーす!
心理的安全性への第一歩としてのふりかえり
はじめに
こんにちは。スクラムマスターの渡部です。
最近、正式に6チーム(開発が動いている殆どのチーム)でふりかえりの支援を受け持つことになりました。
実は、そのふりかえりの支援は、僕から「やらせて欲しい!」と頼み込んで実施に至ったのですが、その際に話したことの一部を、詳しい解説付きでブログとして残そうと思います。
また、はじめて1ヶ月半ほどしか経っていませんが、やってみたメンバーからの感想だったり、こんなことトライしてるよ!ということも紹介しようと思います。
※ この記事は、ユニファAdvent CalendarとふりかえりAdvent Calendarの19日目の記事です。
目次
- ふりかえり支援をしたいと思ったきっかけ
- 心理的安全性を高めるには?
- 改めて、いま、僕がふりかえりでやりたいと思っていること
- 実際にやってみて出てきたトライ
- やってみたみんなからのフィードバック
- おしまい
ふりかえり支援をしたいと思ったきっかけ
ユニファは、まだまだ小さな会社です。色んな面で十分なことなんてありません。見渡せば「やらなきゃいけないこと」がゴロゴロ転がっています。それはとても有り難いことで、めちゃくちゃやり甲斐のあることでもあります。
僕は2019年3月に入社したのですが、個人的な感覚としては、入社直後から常にハイペースを維持し続けている感覚があります。(僕から見える範囲は極一部ですが、全社員、本当にめちゃくちゃ頑張ってるなと思っています。)
そんな中、この頃、ふとした会話の中で「お、それ地味にめちゃくちゃ良さげなカイゼンポイントだね!!ちゃんとした場所で相談してみるね!」ということがポツポツと出てくるようになってきたなと感じていました。
そして、そのようなことを「たまたま会話してたから、今回偶然気づけただけ」で終わらせてしまうのは勿体ないとも思いました。
話しやすい適切な場を設けることで、セレンディピティ(ふとした偶然をきっかけに幸運を掴み取ること)の機会を増やす、つまり、偶然からの幸運を意図的に増やしたいと思ったのです。
そしてそのためには、先ずは、心理的安全性を高めなければと考えたのです。
続きを読む分かりそうで分からないでも分かった気になれる午睡チェックの仕組み補足
みなさんこんにちは。
午睡チェックのディレクター/スクラムマスターをしている保坂です。
この記事は、UniFaアドベントカレンダー 18日目の記事となっております。
先日AWS Startup Architecture of the Year Japan 2020 Live Finaleで、ルクミー午睡チェックのアーキテクチャが評価され、ユニファが優勝することができました。
当日の生中継を見ていて優勝とった瞬間、とても興奮してslackに画面キャプチャを貼りまくっていたことを思い出します。 Well-Architected な仕組みに関してブログを見てください。
さて、今回のブログでは、午睡チェックの仕組みの補足と、施策を実装してからの失敗談を書きたいと思います。
■センサーとタブレットの間
午睡チェックの構成は大きく分けると、
続きを読むすき焼き鍋からタスク並列処理
この記事はユニファAdvent Calender 2020の17日目の記事です。
こんにちは、プロダクトエンジニアリング部のちょうです。最近天気は段々寒くなってきましたね。こんな時期欠かせない料理といえば鍋でしょう。鍋は煮ながら食べる料理ですゆえ、準備の手間はかからないし、好きな食材をどんどんいれることができます。
どころで、最近どれぐらい早く鍋をできるのを考えていました。例えば、炊飯器を15分でご飯を炊けるとする。その15分で鍋の食材を何も処理していない状態からホカホカの鍋にできるのでしょうか。
ここで、この鍋を人気のすき焼き鍋にしましょう。すきやき鍋は必要な食材はこちらです。
レシピから抜粋
- 牛ロース肉(薄切り)
- ねぎ
- しらたき
- えのきたけ
- 焼き豆腐
- しいたけ
- 白菜
- サラダ油
- 卵
割り下については、市販のすき焼きのたれを代用。
ざっくりな料理の流れは
- 具材の下処理
- サラダ油でねぎと牛肉を炒めて、すきやきのたれを回しかける
- 鍋に具材を入れて煮込み
家に二口のコンロはあれば、炒めるのと鍋の煮込みを同時にできます。そして下処理も同時にします。フライパンが熱くなるまではちょっと時間がいります。鍋に水とすきやきのたれを入れて沸騰するまでは5分ぐらいかかります。なので
- 鍋に水とすきやきのたれを入れて煮る
- ねぎを下処理する
- フライパンにサラダ油を入れて中火にする
- 牛ロース肉を下処理する
- フライパンが熱くなったらネギをフライパンにいれる
- ネギに焦げ目がちょっとでたら、牛ロース肉をフライパンいれる
- のこり時間でほかの具材を下処理する(硬いから柔らかいもの順)
- 硬いものから柔らかいもの順で鍋にいれる
が一番効率でしょう。
この料理の流れを技術的な視点からみると、コンロ2口プラス料理する人で実質三プロセッサーです!言い方はちょっと変かもしれませんが(料理する人はコンロではない)、同時に処理することでスピードが上がったのはたしかです。
並列処理の中で、これはタスク並列処理と分類されると思います。もうひとつ、データ並列処理がありますが、それはすべてのプロセッサーはが別々のデータに同時に同じ処理を行うというタイプです。
タスク並列処理では、各タスクの間依頼関係があると、その前後関係が決められます。逆に依頼関係がないと、タスクは同時に行うことができます。例えば、フライパンでネギと牛肉を炒めるのは、先にネギをいれるのです。牛肉はあとなので、 ネギ > 牛肉
という関係があります。そして、フライパンが熱くなるまでネギをいれないので、 フライパンが熱くなる > ネギ
という関係があります。最後、ネギを下処理しないと、フライパンにいれないので、 下処理前のネギ > ネギ
という関係があります(同じく 下処理前の牛肉 > 牛肉
)。まとめると
- ネギ > 牛肉
- フライパンが熱くなる > ネギ
- 下処理前のネギ > ネギ
- 下処理前の牛肉 > 牛肉
並列処理では、この関係を満たされば問題ないです。一つの答えは
料理する人 | コンロ |
---|---|
ネギを下処理する | |
牛肉を下処理する | サラダ油を入れ、中火 |
ネギをいれる | |
牛肉をいれる |
タスク並列処理ではどれぐらい早くなるのは、依頼関係の洗い出し及びプロセスの設計が重要です。
ネギの下処理とコンロの中火を一緒やってしまうと、下処理に時間がかかって、コンロに警告が出て自動的に止まることもあります。安全のために、ネギを先に処理するのがおすすめです。こういうタスク間で直接ではない関係性も含めて考慮しましょう。
ではプログラムでシミュレーションしましょう。
import org.junit.jupiter.api.Test import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit class SukiyakiTest { class StoveCell() : Cell() { private var waitingForBeef = false override fun receive(context: CellContext, event: Event) { when (event) { TurnOnStoveEvent -> context.schedule(500, TimeUnit.MILLISECONDS, FryingPanReadyEvent) FryingPanReadyEvent -> context.parent.tell(event) AddLeekToFryingPanEvent -> { waitingForBeef = true context.schedule(2000, TimeUnit.MILLISECONDS, WaitingForBeefEvent) } AddBeefToFryingPanEvent -> { if (waitingForBeef) { waitingForBeef = false } context.schedule(4000, TimeUnit.MILLISECONDS, DoneEvent) } WaitingForBeefEvent -> if (waitingForBeef) { context.logger.info("牛肉を待つ") } DoneEvent -> context.parent.tell(event) PoisonPill -> context.stopSelf() } } } class ChefCell(private val latch: CountDownLatch) : Cell() { private var _stove: CellRef? = null private val stove: CellRef get() = _stove!! override fun start(context: CellContext) { _stove = context.startChild(StoveCell()) context.logger.info("ネギを下処理する") context.schedule(1000, TimeUnit.MILLISECONDS, TurnOnStoveEvent) } override fun receive(context: CellContext, event: Event) { when (event) { TurnOnStoveEvent -> { stove.tell(TurnOnStoveEvent) context.logger.info("フライパンにサラダ油をいれ、中火") context.logger.info("牛肉を下処理する") context.schedule(2000, TimeUnit.MILLISECONDS, AddBeefToFryingPanEvent) } FryingPanReadyEvent -> { context.logger.info("フライパンにネギをいれる") stove.tell(AddLeekToFryingPanEvent) } AddBeefToFryingPanEvent -> { context.logger.info("フライパンに牛肉をいれる") stove.tell(event) } DoneEvent -> { context.logger.info("できあがり") stove.tell(PoisonPill) // to stop stove latch.countDown() } } } } object TurnOnStoveEvent : Event object FryingPanReadyEvent : Event object AddLeekToFryingPanEvent : Event object WaitingForBeefEvent : Event object AddBeefToFryingPanEvent : Event object DoneEvent : Event @Test fun test() { val latch = CountDownLatch(1) val system = CellSystem() system.add(ChefCell(latch)) system.start() latch.await() system.stop() } }
CellSystemが私が作ったActorモデルのスケジューラーシステムです。Actorモデル自体もタスク並列処理にピッタリするモデルです。コードの中各ステップの時間:
- ネギ処理 1
- 牛肉処理 2
- フライパン熱くなるまで 1
- ネギを入れてから牛肉を入れるまで 2
- 牛肉をいれてからできあがり 4
単位は秒ですが、実質は10秒20秒単位と思ってください。
結果
2020-11-30 16:42:32.888 [worker-0] INFO cell://ChefCell - ネギを下処理する 2020-11-30 16:42:33.897 [worker-0] INFO cell://ChefCell - フライパンにサラダ油をいれ、中火 2020-11-30 16:42:33.897 [worker-0] INFO cell://ChefCell - 牛肉を下処理する 2020-11-30 16:42:34.400 [worker-1] INFO cell://ChefCell - フライパンにネギをいれる 2020-11-30 16:42:35.902 [worker-1] INFO cell://ChefCell - フライパンに牛肉をいれる 2020-11-30 16:42:39.908 [worker-1] INFO cell://ChefCell - できあがり
ここでworker-0は料理をする人です。worker-1はコンロです。
いかがでしょうか。普段の生活からも並列処理に関する知識も潜んでいますね。並列処理が人間の生活をモデルにしたといっても過言ではありませんね。時間があったら、ぜひまわりのことをタスク並列処理で考えてみてください。
最後に、ユニファが一緒に働いてくれるメンバーを募集しています。興味がある方ぜひ見てください。
Local Development with LocalStack
こんにちは。プロダクトエンジニアリング部の杉本です。
この記事は、UniFaアドベントカレンダー2020 の16日目の記事になります。
(私事ですが、2020年6月にユニファにjoinして半年がたち、初めてのブログ投稿です!)
皆さんは、AWSマネージドサービスに依存する機能を開発する場合、ローカルでどのように動作確認をされていますか?
- 実際のAWS環境にローカルから接続する
- レスポンスをスタブ化する*1
- ローカルはそこそこに、とりあえず検証環境にデプロイして確認する
他にも様々あり、プロジェクトのフェーズや事情によっていずれも選択肢になりえると思います。
でもそれに相まって、多少なりともかかるコスト、誤接続や誤操作によるリスク、動作確認不十分な品質 など課題もでてきますよね。。。
今回は、そんなときにオススメな LocalStackを紹介したいと思います。
続きを読む7月から始めた英会話のお話
こんにちわ。プロダクトマーケティングに所属している鈴木です!
この記事は、UniFaアドベントカレンダー 15日目の記事となっております。
そろそろ新しい年をお迎えすることになりますので、新しいことを始めたいと考える方も増えそうということで、 少し前に英会話を始めまして、今までのことを書かせていただければと思います。 英会話を始めようと思っている方の役に立てば幸いです。
私はDMM英会話を使っており、その前提でお話をさせていただきます。
また、英会話レッスン25分+15分の予習や復習で1日の英会話に使う時間は40分ほどです。
ちょっと先生が怖そうな描写もありますが、基本的に先生方はとてもやさしい人が多いです。
始める前の状態
質問されても言っている意味がわからないし、なんて返答すればいいかもわからないレベル。
辛うじて読むことはできる。がしかし単語力がほぼ失われている状態。
はじめの1週間
先生の困惑した表情とため息に何度も心が砕けそうになります。
こんなに話せないものなのね。。。と愕然しました。
このタイミングでやったレッスン内容は写真を英語で描写するというものです。
言いたいことをグーグル翻訳使って翻訳し、それを伝えるので精一杯でした。
始めてから1か月
はじめの1週間でやることが何となくわかってくるので、すこし予習(ズル)をするようになりました。 レッスンで使いたい教材は事前に選べるのでグーグル翻訳を使って写真を描写してメモしてました。
そのメモを読むときは自信満々なのですが、それ以外は急に勢いが無くなるイメージです。 だた、やっと自力で頑張って伝えてみたりするようになります。間違っているので伝わらないのですが。
来る日も来る日も写真の内容を英語で描写する毎日です。
始めてから2か月
2か月目も写真を描写し続けました。 写真題材にレベルがあり、ちょっと難しいのを選んでみようと思えるようになります。 そして、もちろん完ぺきではないのですが写真描写に飽きるという状態がやってくるのです。 写真を描写するのは伝えたい文章を自分で作るトレーニングになるのですが、日常生活であんまり話すイメージが湧かず、もっと会話の方を鍛えたいと思いました。
最初では考えられない状態です。
始めてから3か月
3か月目からは、デイリーニュースという長文の文章を読むレッスンに切り替えました。 これは先生が読んでくれたあとに、自分も後に続いて読むというのを行い、内容確認のための質問や自分の考えを聞くような質問をされる内容です。
これが、中学校の授業のような感じで私としては非常に面白くなかったので1週間ほどでやめました。 次に、選んだのがフリートークになります。英語を話せるようになりたいのであれば話さないとだめだろう。であればフリートークだよね。という考えでした。
ただ、フリートークが思っていた以上にハードルが高く、いかにまだまだなのかと思い知らされる結果になりました。
まずフリートークなので話題が必要になります。「で?何について話したい?」と言われたりすることがあるのですが、正直こちらとしては何でもいいんですよね・・・。うまい先生は話題を広げたり、質問してくれたりするのですが、なかなかうまくいかないこともあります。 この時の対処法としては、後々思いついたのですが最近自分に起こったことを話す。というものです。 そうすると、自分事で作文するので良いトレーニングになります。
次に先生が何言っているかわからないです。テキストがないので。 正直笑顔で、わかったふりもたくさんしました。今でもしてます(笑)
最後になんて言っていいかわからないです。すぐに文章なんて作れないので。 なので、聞いた単語で言いたいことを何となく把握して、グーグル翻訳で翻訳して伝えるということを繰り返してました。
ただ、あまりにもスムーズじゃないので、「レッスンのテキスト使った方がいいよー」と言われることが良くありました。
やっぱりフリートークもやめようか・・・写真を描写に戻ろうか・・・ と何度も脳裏を過りますがここは踏ん張りどころだな。と思い耐えました。 話したいなら話し続けなければと。
始めてから4か月
なかなか難しいな・・・。と思っていたのでどうしたらいいかといろいろ悩んだ末、このころから取り入れたのがシャドーイングというトレーニング方法でした。英語の音声を追いかけて読むようなトレーニングで、同じ文章を何回も読みます。YouTubeなどで無料のがあるのでそれを使ってます。1日10分とか15分程度ですが...。 これの効果も相まって?耐えたから?少し話すのが楽しくなる場面が出てきます。 全然拙いのですが、先生もうんうんと聞いてくれて「つまりこう言いたいんだよね?」 と教えてくれることが多くなった気がします。 コロナで仕事以外では誰とも話さないことも多いので、ちょっとこの時間がたのしみ。とすら感じるようになります。
始めてから5か月
5か月目もひたすらフリートークを続けました。 4か月目よりは少しまともな会話はできてきたかなと感じます。 先生とコロナの状況を話したり、いろいろな国のことを聞いたり、女性の先生から彼氏の愚痴をずっと聞いたりもました。「ケンカ中で、彼の言い方がムカつく」のだそうです。 一番面白かったのはスターウォーズの話から宇宙の話になり、「もしこの宇宙で生物が存在するのは地球だけだとしたら孤独だよね」という話をして「同じ地球人なんだからみんな仲良くしないとですね」という会話もしました。グローバル感が凄いですね。(笑)
ちなみに、先生の多くはネットフリックスユーザーが多いのでネットフリックスの話題かアニメの話(ジブリと新海誠)や漫画(ワンピース・ナルト・鬼滅の刃)の話はとても盛り上がります。 日本のことを聞かれたり、今まで行った海外旅行の話なんかも良く聞かれます。
まだまだ拙い英語力で単語の一点返しで伝えてしまうこともありますが、極力文章を組み立てながら話そうと努力しています。
最後に...
学習って大体同じような工程だなぁと思っています。よくRPGなどに例えられていますよね。 進め方も攻略も自分次第。 Pythonも鋭意勉強中なのですが、何度も壁にぶつかってやっとほんのり使えるかも。となってきた次第です。また高い壁が見えてます。 道のりは長いですがPythonも英会話もその工程も含めて楽しみながらマスターできればと思います。
ユニファでは保育現場の課題解決のため家族コミュニケーションを豊かにするために一緒に働いてくれる仲間を募集中です!!