こんにちは。人間中心設計(HCD)専門家のやまぐち(@hiro93n)です。
主にプロダクトマネージャーやQAエンジニアの部署でマネージャーをやっています。キャリア的にはデザインの部署のマネージャーのやりたさもあるのでデザイナーにかかる課題解決などにも首を突っ込んでいます。マネージャーばかりでゲシュタルト崩壊しそうですね。自分はしました。
そんなわけでこの記事はユニファAdvent Calender 2020、22日目の記事です。
続きを読むこんにちは。人間中心設計(HCD)専門家のやまぐち(@hiro93n)です。
主にプロダクトマネージャーやQAエンジニアの部署でマネージャーをやっています。キャリア的にはデザインの部署のマネージャーのやりたさもあるのでデザイナーにかかる課題解決などにも首を突っ込んでいます。マネージャーばかりでゲシュタルト崩壊しそうですね。自分はしました。
そんなわけでこの記事はユニファAdvent Calender 2020、22日目の記事です。
続きを読むこんにちは、データエンジニアリングチームの宮崎です。この記事は、UniFaアドベントカレンダー2020の21日目の記事となります。 最近、文字を自由に編集できるLINEスタンプがあることを知りました。いつの間にか色々進化していますね・・・! そこで今回はDeepLearningのモデルを使って、以下のように写真からLINEスタンプ風画像の自動作成を行ってみたいと思います。
続きを読む
こんにちは!ユニファアドベンドカレンダーをご覧頂きありがとうございます! ユニファQAチームの斉藤です。 このブログは、UniFaアドベントカレンダー 20日目となります。
今年はコロナで大変な1年でしたね。ユニファQAチームも今年の早い時期からフルリモートに切り替えて活動を行ってきました。もともとリモート勤務可能ではありましたが、案件が去年の2倍以上に増えたり、メンバーの入れ替わりがあったりしたので、フルリモート体制で乗り切るには大変な1年だったなぁと感じています。
そんな中ですが、新しい取り組みにもチャレンジしてみました。リスクベースドテストです。 今回はそこから学んだことをふりかえってみたいと思います。
冒頭のごあいさつさらっと記載しましたが、今年はテスト案件が去年に比べて大幅に増えました。
去年までは当時のQAチームメンバーでもなんとか回せる量だったのですが、今年の春頃から数か月規模の案件が並行で走り、秋頃からさらに増えて、現在は多くの案件が並行して動いています。案件が増えることは計画内だったので、今年の春頃から「案件が増えた時にそなえて、テストを考えねば」という話題はチーム内であがっていました。
そこで当時のQAチームリーダーから提案されたのが、リスクベースドテストでした。
では、リスクベースドテストとは何でしょうか。
JSTQB用語集で引くと、以下のような記述が出てきます。
リスクベースドテスト(risk-based testing): プロジェクトの初期段階からプロダクトリスクのレベルを低減させ、ステークホルダにその状態を通知するテストの方法。プロダクトリスクの識別の他、テストプロセスをガイドする際のリスクレベルの活用もこれに含まれる。
プロダクトリスクというものを識別し…テストプロセスをガイドする…なるほどわからん。
私の理解をざっくりいうと、要はプロダクトリスク(そのプロダクトで起きてほしくない事象)の重大度と発生率を整理して定義し、それに基づいてテストする機能やしない機能を選んでいく、というテスト戦略です。
プロダクトリスクのリスクタイプやリスクレベルも、以下のようにリーダーの方で定義して頂いたので「それに基づいてテストする機能やしない機能を選んでいくのだよ」の具体的な方法を、いよいよQAチームメンバーで考えていくことになりました。
ユニファQAチームは、メンバーによってテスト設計から実装までのやり方が少し異なります。このリスクベースドテストを導入しようとしている時は、複数プロダクトにそれぞれメンバーが分かれてアサインされていました。 いつもだと、それぞれのプロダクトに合わせてメンバーがテスト設計をしますが、このリスクベースドテストを導入するなら、複数プロダクト統一したやり方じゃないとレビューがしにくいな~と考えました。
そこで複数プロダクト間である程度、統一できるやり方として、テスト観点を抽象化したリスク設定要素、基本リスクレベル、補正リスクレベルという項目を使ってみようと考えました。
リスク設定要素とはいわゆるテスト観点です。 ユニファQAチームで行うリスクベースドテストでは、このテスト観点をできるだけ抽象化したものをリスク設定要素と名付け、これに重みづけすることで「テストする機能やしない機能を選ぶ」ことをやってみようと考えました。
このリスク設定要素(テスト観点)は、ユニファQAチームメンバーの認識をそろえるため、全員参加でマインドマップを使ってブレストして決定しました。
次に基本リスクレベルです。 基本リスクレベルとは、リスク設定要素の基本的な重みづけです。 リスク設定要素とリスクタイプでマトリクスを作り、QAチーム全員で話し合いながら1~5点の間で点数をふっていきました。(5点がリスクとして一番重い点数です) 全てのリスク設定要素に基本リスクレベルとして点数を設定したら、次にそれを、プロダクトリスクレベルへマッピングを行いました。 リスク設定要素のもつ下限値~上限値を均等にリスクレベルへわりつけ、該当するリスク設定要素をマッピングして、QAチームで眺めてみました。 結果、リスクレベルとリスク設定要素の組合せに違和感はないね!ということで、基本リスクレベルの設定が完了できました。
基本リスクレベルの設定が完了しました。この後のフローとしては、機能・画面ごとにリスク設定要素をあてはめて、QA保証対象以上のリスク設定要素のみに対しテスト設計をしていく、という形にいったん整いました。
ただ機能・画面によっては、リスク設定要素(基本リスクレベル)通りにあてはめてしまうと、具合が悪いというものもあります。 たとえば、リスク設定要素の「バリデーション」や「画面UI」は、QA保証対象外ですが、機能・画面のビジネス的な重要度によっては、QA保証対象とした方がよいこともあります。
これを補うために、補正リスクレベルを使うことにしました。 補正リスクレベルとは「基本リスクレベルを見ると、QA対象もしくは対象外だけど、担当QA判断によってレベルを調整してよい」というものです。
レビュー時にレビューアに対して「ここは重要もしくは重要でないと判断したから、確認してくれ」というアピールとしても使えると考えました。
やってみた結果は以下です。
①工数はあまり削減できなかった
②短期間のテスト実行で、重要度の高いバグが検出できた
①については、もともとリスクベースドテストは「工数削減」が目的ではなく、「少ないリソースで品質を担保するためにテストするしないをプロダクトリスクに基づいて決めていく」やり方なので正しいのですが、今回は「テストしない」と決めた部分についても
という動きをしてしまい、結果、QAチームはQA保証対象外のリスク設定要素についても、なにがしかの形でテスト設計することで工数削減効果はあまりなかった、という結果になりました。
リスクベースドテスト時、工数も適正な量に抑えたいのであれば、QA保証対象外部分については「やらない」という選択をすること、「やらない」代わりに問題発生した時はどのようにするか等をステークホルダーと話し合っておくことが必要そうだな、と感じました。
②はまさに、リスクベースドテストで狙いたいところだったので、満足いく結果でした!
リスクベースドテストをやってみたのは2020年初夏~秋頃のテスト案件なのですが、現在ユニファ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モデル自体もタスク並列処理にピッタリするモデルです。コードの中各ステップの時間:
単位は秒ですが、実質は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はコンロです。
いかがでしょうか。普段の生活からも並列処理に関する知識も潜んでいますね。並列処理が人間の生活をモデルにしたといっても過言ではありませんね。時間があったら、ぜひまわりのことをタスク並列処理で考えてみてください。
最後に、ユニファが一緒に働いてくれるメンバーを募集しています。興味がある方ぜひ見てください。
こんにちは。プロダクトエンジニアリング部の杉本です。
この記事は、UniFaアドベントカレンダー2020 の16日目の記事になります。
(私事ですが、2020年6月にユニファにjoinして半年がたち、初めてのブログ投稿です!)
皆さんは、AWSマネージドサービスに依存する機能を開発する場合、ローカルでどのように動作確認をされていますか?
他にも様々あり、プロジェクトのフェーズや事情によっていずれも選択肢になりえると思います。
でもそれに相まって、多少なりともかかるコスト、誤接続や誤操作によるリスク、動作確認不十分な品質 など課題もでてきますよね。。。
今回は、そんなときにオススメな LocalStackを紹介したいと思います。
続きを読む