Why Quality Assurance?

この記事はAkerun Advent Calendar 12日目の記事です。

はじめまして。株式会社フォトシンスでQAエンジニアに従事しているyohei_oka - Qiitaと申します。
早速ですが、QAエンジニアという職種をみなさんはご存知でしょうか?
私はQAエンジニアからIT業界をスタートし、これまでに様々なプロダクトのQAに携わってきました。
その中で私が学んだこと、培ったことを元に、私がQAについて考えていることを少しお話したいと思います。

1.QA(Quality Assurance/品質保証)エンジニアの役割とは

一般的にQAエンジニアというと「品質を向上させる役割」というイメージを持たれているかもしれません。
単刀直入にお伝えします。我々QAエンジニアがいても、品質は向上しません。
もちろん間接的には寄与しますが、我々の存在だけでは品質を向上させることはできない、という意味です。
我々ができるのは「品質の可視化」です。品質状況を可視化し、その品質が合格水準に達しているかどうかの判定をするのが、我々の本来の役割です。
では、品質を向上させるのは誰の役割なのでしょうか?

2.品質とは何を指すのか

品質向上について考える前に、そもそも品質とは何を指すのか考えたいと思います。
我々が品質について考える時、実はそこには二種類の品質が存在します。

  1. プロダクトの品質
  2. プロジェクトの品質

一般的には、1のプロダクトの品質に着目されがちですが、実は2のプロジェクトの品質も同じくらい重要です。
プロダクトの品質は、顧客の満足度に直結します。逆に言えば、顧客満足度の最大化をミッションとし、我々はプロダクトの品質を考えます。
これに対し、プロジェクトの品質というのは、開発効率を意味します(広い意味での効率と捉えてください)。開発効率の最大化が、プロジェクト品質を考える上でのミッションです。

エンジニアは誰しも、品質の悪いものを作ろう、とは当然思いません。
しかし、それでも完成したプロダクトの品質が悪かった時、それは、プロジェクトのどこかに何らかの問題があった、ということになります。
逆に言えば、プロジェクト品質の向上なくして、プロダクト品質の向上はありません。

つまり、品質を向上させるのはプロジェクト全体の役割である、ということです。
マネージャーはもちろんのこと、エンジニア含むプロジェクトメンバー全員の意識が品質に向いて、初めて品質は向上していきます。
二つの品質向上にアプローチするための要となるという点で、QAエンジニアは重要な役割を担っていると考えています。

3.QAとは技術ではなく思想である

QAエンジニアにできるのは「品質の可視化」である、というのは前述した通りです。
しかしながら、それだけで良い、とは私も思っておりません。

これからのQAに求められるのは、その一歩先。可視化されたデータを元にプロダクト/プロジェクトの課題を見抜き、それらを解決していく、その活動の先頭に立つことです。
プロダクトに不具合が発生したならば、不具合の原因は何なのか、という直接的な原因はもちろんのこと、そもそもなぜ不具合が発生してしまったのか、という根本的な原因も究明し、可視化させなくてはいけません。可視化したデータを元に、プロジェクトにフィードバックし、双方の品質改善にアプローチしていくのが、これからのQAエンジニアの役割です。

だからこそ私は、QAとは技術ではなく思想であると思っています。
極端な話、QAエンジニアがこれでいいと思ったところまでしか、品質は上がりません。
基準を低く設定してしまえば、それ以上を目指そうとは誰も思わないからです。
逆にQAエンジニアが志を持って高い基準を目指せば、その分だけ品質は上がっていきます。
だからこそ、必要なのは姿勢であり、思想である、と私は考えます。

そんな志を持ったQAエンジニア、これからの時代にいかがでしょうか?


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com

脆弱性対応情報データベース (MyJVN API) の API を使って OSS の脆弱性を見てみる

この記事は Akerun Advent Calendar 2020 - Qiita の 11 日目の記事です。

今週 2 回目の登場です。 AkiAbe - Qiita です。
前回は、スプリント開発の話でマネジメント寄りの話でした。 akerun.hateblo.jp

今回は、少しテック寄りにしようと思います。

OSS脆弱性の情報確認

この記事読むようなかたは、Open Source Software (OSS) については把握していますね。
意識の高いエンジニアのみなさんとしては、自分が使っている開発環境の OSS脆弱性がどんなものあるか把握しておきたいですよね。

OSS脆弱性はデータベース化されています。
jvndb.jvn.jp

たとえば、debian 系 OS で、sudo コマンドの脆弱性はどのようなものがあるか調べてみましょう。

JVN iPedia - 脆弱性対策情報データベース
JVNDB-2019-014477 - JVN iPedia - 脆弱性対策情報データベース

JVNDB-2019-014477
Sudo における境界外書き込みに関する脆弱性

という指摘がでてきました。

こんな感じで、自分の環境のどのパッケージにどんな脆弱性があるかを調べることができます。

API を利用して、まとめて調べたい

ひとつずつパッケージ名入れて検索するの面倒ですよね。
MyJVN API という API が公開されているのでそれを利用してまとめて調べられないか試してみます。

私は試しに手元のラズパイでやってみます。
これから使うラズパイの OS 情報です。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.13 (stretch)
Release:    9.13
Codename:   stretch

$ uname -a
Linux rpiTester 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux

ためしに、前述した sudo コマンドを API を叩いて調べてみます。
JVNDB-2019-014477 の指摘が得られます。 (それ以外のも得られます)

$ curl -G -d "method=getVulnOverviewList" -d "feed=hnd"  -d "keyword=sudo" -d "datePublicStartY=2019" -d "rangeDatePublished=n" -d "rangeDateFirstPublished=n"  https://jvndb.jvn.jp/myjvn

<?xml version="1.0" encoding="UTF-8" ?>   
<rdf:RDF 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://purl.org/rss/1.0/" 
xmlns:rss="http://purl.org/rss/1.0/" 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
xmlns:dc="http://purl.org/dc/elements/1.1/" 
xmlns:dcterms="http://purl.org/dc/terms/" 
xmlns:sec="http://jvn.jp/rss/mod_sec/3.0/" 
xmlns:marking="http://data-marking.mitre.org/Marking-1" 
xmlns:tlpMarking="http://data-marking.mitre.org/extensions/MarkingStructure#TLP-1" 
xmlns:status="http://jvndb.jvn.jp/myjvn/Status" 
xsi:schemaLocation="http://purl.org/rss/1.0/ https://jvndb.jvn.jp/schema/jvnrss_3.2.xsd http://jvndb.jvn.jp/myjvn/Status https://jvndb.jvn.jp/schema/status_3.3.xsd" 
xml:lang="ja">
    <channel rdf:about="https://jvndb.jvn.jp/apis/myjvn">
      <title>JVNDB 脆弱性対策情報</title>
      <link>https://jvndb.jvn.jp/apis/myjvn</link>
      <description>JVNDB 脆弱性対策情報</description>
      <dc:date>2020-12-07T17:58:27+09:00</dc:date>
      <dcterms:issued/>
      <dcterms:modified>2020-12-07T17:58:27+09:00</dcterms:modified>
      <sec:handling>
        <marking:Marking>
          <marking:Marking_Structure xsi:type="tlpMarking:TLPMarkingStructureType" marking_model_name="TLP" marking_model_ref="http://www.us-cert.gov/tlp/" color="WHITE"/>
        </marking:Marking>
      </sec:handling>
      <items>
        <rdf:Seq>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-014477.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-013632.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-013631.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-011719.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-011096.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-010626.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-007171.html"/>
          <rdf:li rdf:resource="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-005598.html"/>
        </rdf:Seq>
      </items>
    </channel>
    <item rdf:about="https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-014477.html">
      <title>Sudo における境界外書き込みに関する脆弱性</title>
      <link>https://jvndb.jvn.jp/ja/contents/2019/JVNDB-2019-014477.html</link>
      <description>Sudo には、境界外書き込みに関する脆弱性が存在します。</description>
      <dc:creator>Information-technology Promotion Agency, Japan</dc:creator>
      <sec:identifier>JVNDB-2019-014477</sec:identifier>
    .....
    .....
    以後、省略

スクリプト

dpkg -l で、入っているパッケージ一覧がとれるので、それで取得できるパッケージに対して、上記の API脆弱性を確認してみます。

$ dpkg -l 

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                            Version                           Architecture Description
+++-===============================-=================================-============-===============================================================================
ii  adduser                         3.115                             all          add and remove users and groups
ii  adwaita-icon-theme              3.22.0-1+deb9u1                   all          default icon theme of GNOME
ii  alsa-utils                      1.1.3-1                           armhf        Utilities for configuring and using ALSA
ii  apt                             1.4.10                            armhf        commandline package manager

    .....
    .....
    以後、省略

check.sh とかいう名前で以下のようなスクリプト作成します。
結構力技で書いてます... ^^;

#! /bin/bash

FEED="feed=hnd&"
MET1="method=getVulnOverviewList&"
URL="https://jvndb.jvn.jp/myjvn?"

# 2015 年以降で指摘があったパッケージを検索
START="datePublicStartY=2015&"
RANGEP="rangeDatePublished=n&"
RANGEF="rangeDateFirstPublished=n&"


RES_TMP_FILE="res_tmp.txt"

# 最初にみつけた指摘だけ出力する
res_check () {
    res_flg=1
    html_list=""
    
    while read str; do
    if [ "`echo $str | grep '該当する脆弱性対策情報はありません'`" ]; then
        res_flg=0
        break
    fi
    if [ "`echo $str | grep html`" ]; then
        html_list=$str
        break
    fi
    done < $RES_TMP_FILE

    echo $res_flg $html_list
    return
}



# パッケージリスト取得して、不要な文字列消す             
FILE_NAME="hoge.txt"
NEW_FILE="oss_list.txt"

dpkg -l > $FILE_NAME
sed -e 's/ii  //g' $FILE_NAME > $NEW_FILE


# package 名で web api 叩いて確認
while read Line; do

    # package 名抽出
    CHECK_PKG=` echo $Line | awk '{sub(" .*", "");print $0;}' `

    # "|" とか "||" とかの行をはぶく  
    if [[ $CHECK_PKG =~ ^[a-z].*$ ]]; then

        # keyword にパッケージ名指定して web api たたく 
        KEYWORD="keyword=${CHECK_PKG}&"
        curl -s ${URL}${MET1}${FEED}${KEYWORD}${START}${RANGEP}${RANGEF} > $RES_TMP_FILE

        # 返答解析する                                                                                                         
        ret=$(res_check)
        flg=`echo $ret | cut -c 1`

        if [ $flg -eq 0 ]; then
            echo "${CHECK_PKG}, 脆弱性報告なし "
        else
            tmp_url=`echo $ret | grep -oE 'http(s?)://[0-9a-zA-Z?=#+_&:/.%-]+'`
            echo "${CHECK_PKG}, 脆弱性あり (詳細確認してください), ${tmp_url}"
        fi
    fi


    
done < $NEW_FILE

rm -fr $FILE_NAME
rm -fr $NEW_FILE

実行してみる。

$  ./check.sh  

adduser, 脆弱性あり (詳細確認してください), https://jvndb.jvn.jp/ja/contents/2016/JVNDB-2016-006807.html
adwaita-icon-theme, 脆弱性報告なし 
alsa-utils, 脆弱性報告なし 
apt, 脆弱性あり (詳細確認してください), https://jvndb.jvn.jp/ja/contents/2020/JVNDB-2020-005502.html

    .....
    .....
    以後、省略

まとめ

上述のスクリプトは文字列でひっかけただけなので、意図してない指摘*1も含まれてしまいます。
うまいやり方は他にもありそうですが、見るものを絞ることはできた感じですね。
気になるパッケージの脆弱性があれば、自分でパッチを当てましょう。


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com

*1: https://jvndb.jvn.jp/ja/contents/2016/JVNDB-2016-006807.html なんかだと adduser パッケージ自体の指摘ではない

新卒エンジニアの学びと叫びと反省

この記事は Akerun Advent Calendar 2020 - Qiita の10日目の記事です。

はじめに

こんにちは、 私は今年の1月にPhotosynth初の新卒として入社しました。
普段はWebエンジニアとして開発を行っています。
初のAdvent Calendarなので、イケイケな技術を投稿!
といきたかったのですが何も思いつきませんでした...。

なので今回は1年弱を通して「学」んだことや「叫」びたいこと、「反省」したことを書きたいと思います。

学: 先輩エンジニアの行動は真似る

上達への近道は真似ることだと思います。
例えば

  • 議事録の取り方
  • ミーティングの進め方
  • コードレビューの仕方
  • コードの書き方

などなど、挙げればキリがないですね。
そんな学びを得た私ですが、真似る際に一点注意したことがあります。
それは 最初からコツを聞かない ということです。

取りあえず真似てみて、自分に合うかどうかを分析することは大切だと思います。
そしてコツを得るための思考や経験は間違いなく成長です。

観察する → 真似る → 試行錯誤する → コツを聞く → 試行錯誤する
→ 自分なりにアレンジする → 自分のものにする

今の私は上のフローがとてもしっくりきています。
皆さんも自分なりのやり方を見つけてみてください。

一点だけ補足ですが、「絶対に最初からコツは聞くな!」と言ってるわけではないです。
「真似するにしても難しい」と思った時は遠慮なく聞いてください。
大抵の人は聞かれてちょっと嬉しいと思います。

叫: Slackのスタンプは想像以上に嬉しい

入社一年目は不安も多く、常に焦りながら仕事をしています。
Slackに投稿する内容が無茶苦茶だったり、論点がズレていたり・・・。
ちょっとした謝罪の投稿に対してノーリアクションだと死ぬほど辛いです。
「がんばれ」のスタンプをくれるだけでとても救われます。
リリースした時も同様ですね。
リリースしたのにノーリアクションだと複雑な気持ちになります。
「おつかれ」スタンプの効果は偉大です。
リモートワークが基本になって直接会話をする機会が減ったからこそ、大事にしたいと思いました。
(スタンプをください!!!!)

反省: イエスマンになってしまっていた

ほとんどの新卒生は期待に応えようと必死に仕事をしていると思います。
私は期待に応えようとするあまり、取りあえず「はい!」と言ってしまっていました。

  • 相手の言っていることがイマイチ伝わってないのに「はい、わかりました」
  • 出来そうにないのに「はい、できます」

これは 「期待に応える」ではなく、「期待させている」 のです。
後になって「わかってないじゃん!」とか「出来てないじゃん!」と裏切ることになります。
なので、

  • わからないことは「ちょっと伝わらなかったので、もう一度説明してくれますか?」
  • 出来そうにないことは「出来ません」

とはっきり伝えましょう。
どこまで相手に期待するかは人によって様々ですが、私は「言われたことは全て期待されている」と思い込みイエスマンになっていた気がします。
今となっては自分の意思をはっきり伝えることも、実は期待されていたんだなと思います。

さいごに

同じく新卒生の方や、就職間近でドキドキしている学生さんの助けになれば幸いです。
来年はイケイケな技術について投稿するぞ!

株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com

リモートワークで IoT 機器がなくてもスムーズに開発できるように簡素なエミュレータを作った話

この記事は Akerun Advent Calendar 2020 - Qiita の9日目の記事です。

はじめまして、 Web エンジニアの meriy100 です。

私は今年の3月に入社してすぐに10月にリリースされた Akerun ConnectAPI とフロントエンドの開発にアサインされました。

しかし、 コロナの影響ですぐにフルリモートとなり自宅で開発することになったのですが、 開発が進むととある問題に直面しました。

開発用の Akerun が自宅に無いので Akerun Connect から施錠解錠操作をしても結果が返って来ないのです (開発用の Akerun は セキュリティの都合上自宅で環境を整えるのが大変で、 ハードウェアチーム優先になっていました)。

結果が返って来ないと結果の表示を実装するためにいくつか手間な作業が入ってしまい、 開発効率が落ちてしまいます。 開発環境で使える Akerun がすぐに使えない状況では困るということで、 当時の Akerun Connect 開発チームで簡単なエミュレータを作ることにしました。

なにをつくるか

前提として、 Akerun Connect の開発チームは全員Webエンジニアで Akerun のハードウェアの仕様や実装は完全には把握していません。 また、 プロダクト開発の真っ只中なのであまり大きなものを開発する余裕もありませんでした。 なのでまずは壮大な構想は描かずに、 以下のような Akerun Connect の開発に必要な最低限のエミュレータを実装することとしました。

  1. 施錠解錠、 Akerun 状態取得等の Akerun Connect で行える Akerun の操作ができる。
  2. Akerun Connect と Akerun のやり取りの部分のみを模倣し、 Akerun ハードウェア群の処理は考えない。
  3. 最終的な Akerun とのつなぎ込みのテストは 開発用のAkerun がある会社でまとめて行う。

f:id:photosynth-inc:20201207170549p:plain

どうやったか

開発すると言っても、 Akerun Connect の開発もあるのでなるべく影響が出ないように毎日1時間だけエミュレータの開発に時間をさくようにしました。 また、 この手の開発を一人でやっていると気持ちが滅入ってしまいがち (私だけかも?) なので、 その1時間はペアプロで開発します。

具体的には、 1日目をAさんと Bさんでペアプロしたら2日目は BさんとCさん、 3日目は CさんとDさん といった感じに前回の実装者の内一人と新しい人一人のペアで回します。 特に前回やったことの詳細なレポートを書くのも大変なので、 前回やったことは簡単なメモと前回参加した実装者から共有する形とし、 開発以外の余計な作業が発生しないように調整しました。

結果

開発は10日ほどで終了し、 無事自宅の開発環境でも Akerun の施錠解錠操作等の結果が返って来るようになりました。 具体的には Akerun Connect の開発環境のサーバーからローカルで立ち上げた MQTT サーバーを経由し、Ruby で実装されたスクリプトで施錠解錠結果と同じ情報を開発環境サーバーに HTTP でリクエストするというものです。

実装してしまえば大したことはなかったのですが、 それまでは Akerun のエミュレータを作るならハードウェアの仕様、 実装を完全に模倣しないといけないからコストが掛かる、 と思われていました。実は必要なものはローカルの MQTT サーバーと総計600行程度の簡単なスクリプトのみでした。

できたもの以外の部分で良かったこと

持ち回りでペアプロしたことで、 普段のアプリケーション開発では使わないような RubyAPI や MQTT の仕様などをチームで手を動かしながら共有できたのがよかったですね。 あとは、 フルリーモートが続いて人と話す機会が減ったので1時間のペアプロは良い気分転換になりました。 コロナで息苦しい世の中になってしまいましたが、 誰かと一緒になにかやるのはいつでも楽しいですね!

株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com

E2E テスト CodeceptJS を日本語対応した Docker 環境でサクッと動かす

この記事は Akerun Advent Calendar 2020 - Qiita の 8 日目の記事です。

こんにちわ。わたくしは 2020 年 10 月にできたての SRE チームに入社しました。

私の座席の目の前には QA チームの皆様がいらっしゃいます。

WEB ブラウザのポチポチの日々から解放すべく

E2E テスト自動化の CodeceptJS の導入に至りました。

github.com

そのような CodeceptJS の導入をしてみようという皆様のお役に立てますと幸いです。

さて困った

本家のリポジトリの Dockerfile で起動し CodeceptJS を実行するや否や、日本語対応していませんでした。

f:id:photosynth-inc:20201202195402j:plain

日本語のフォントなどを導入する必要がありそうです。

そこで、日本語に対応した Dockerfile を作りました。

https://github.com/Photosynth-inc/CodeceptJS

実行手順

以下をローカル環境で実行するとテストが実施できます。

HOME ディレクトリ以下の work 配下で実施します。

$ cd mkdir ~/work && cd work

Docker 環境を構築します。

$ git clone git@github.com:Photosynth-inc/CodeceptJS.git
$ cd CodeceptJS
$ docker build --no-cache  . -t codeceptjs 

設定ファイルを作成します。

$ mkdir ~/work/e2e && cd ~/work/e2e
$ vi codecept.conf.js
exports.config = {
  tests: './*_test.js',
  output: './output',
  helpers: {
    Nightmare: {
    }
  },
  plugins: {
    allure: {
       enabled: true
    },
    stepByStepReport: {
      enabled: true,
      deleteSuccessful: false,
      fullPageScreenshots: true,
    },
    retryFailedStep: {
       enabled: true
    },
  },
}

テストコードを作成します。

$ vi sample_test.js
Feature('サンプル');

Scenario('Akerun', ({ I }) => {
   I.amOnPage('https://connect.akerun.com/');
   I.click('利用規約');
   I.see('あいうえお');
});

テストコードを実行します(失敗例)

$ docker run -v $PWD:/tests codeceptjs codeceptjs run --steps
CodeceptJS v3.0.2
Using test root "/tests"

サンプル --
  Akerun
    I am on page "https://connect.akerun.com/"
    I click "利用規約"
    I see "あいうえお"
  ✖ FAILED in 9026ms

失敗すると outputs ディレクトリに失敗したスクリーンショット画像が保存されます。

おまけ

さらに、allure を利用すればもっと可視化され便利になります。

allure によるレポートを生成します。

$ docker run -v $PWD:/tests codeceptjs allure generate /tests/output --clean --output allure-report
Report successfully generated to allure-report

表示には WEB サーバが必要なので、ローカルで一時的に以下のようにサービスを立ち上げます。

$ cd allure-report/

$ sudo python -m SimpleHTTPServer 8000
Serving HTTP on 0.0.0.0 port 8000 ...

WEB ブラウザから http://localhost:8000 にアクセスすると以下のようなレポートを参照することができます。

f:id:photosynth-inc:20201202203013p:plain

いかがでしたでしょうか?

そんな、株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。

hrmos.co

またお会いましょう。

ベンチャー転職後 SRE で実施した3つの即効施策

この記事は Akerun Advent Calendar 2020 - Qiita の 7 日目の記事です。

はじめまして。わたくしは 2020 年 10 月にできたての SRE チームに入社しました。

ベンチャー企業に転職すると、自由とともに多くのやるべくことに溢れ、目先のことに翻弄されがちです。

そのような中でも、何とかしたいけど何からやればいいか困っているという皆様にお役に立てば幸いです。

この記事では、2ヶ月間で実施して効果があった3つの施策を紹介させていただきます。

当施策は、AWS クラウド環境を前提としていますのでご了承ください。

何からやるか?

困っていることをヒアリングし、課題・タスク・依頼に分類することです。

その上で、緊急度・重要度・解決の難易度を数値化し優先度を決定します。

あとは、優先度順にカンバン方式で上から順にこなしていくだけです。

この課題抽出によって、以下の3つの施策を実施しました。

1)コスト削減

改善施策には何かとお金が必要です。後者の施策を実施するためにも、お金を節約します。

AWS 環境で実施した施策は以下の通りです。

  1. Cost Explorer によるコストの分類

  2. Savings Plan と Reserved Instance の適用

  3. CloudWatch Events による営業時間外のサーバ停止

  4. サーバの棚卸しと削除

たったこれだけで、10 %のコストを減らすことができました。

2)可視化

サーバは動いているのか?何が重いのか?クラウド環境は大丈夫なのか?というケースがありました。

お客様の方が、先にサービスの異常に気付くようでは機会損失になります。

そこで、以下のツールを導入しました。

  1. Pingdom: Web サイトにヘルスチェックを実施しサービス監視します。

    大手クラウドサービスあるようなサービス稼働率のポータルを誰でも参照可能な URL で自動的に生成することができます。

    f:id:photosynth-inc:20201202183531p:plain
    Pingdom

  2. PagetDuty: 監視システムなどのアラートを受けインシデント発生をエスカレーションに基づき電話通知するサービスです。

  3. AWS Config: 自社の AWS の設定をセキュリティ分析し世にあるベストプラクティス(CIS や PCIDSS など)との差異がわかります

    f:id:photosynth-inc:20201202183139p:plain
    AWS Config

  4. NewRelic: アプリケーションのパフォーマンスやボトルネックを可視化します。

これら施策によって、機会損失の最小化と、問題を解く鍵が揃いました。

3)パフォーマンス改善

開発環境や本番環境のボトルネックを把握し、改善施策を実施します。

開発環境がよくなれば開発スピードが向上し売上にも貢献できます。

NewRelic を利用すれば、各分野の達人に頼らなくてもある程度のアタリがつきます。

WEB ブラウザ上から、どのレイヤーのどの処理が遅いのか分かります。遅いクエリーも分かります。

f:id:photosynth-inc:20201202184936p:plain
Newrelic

f:id:photosynth-inc:20201202184958p:plain
NewRelic

いかがでしたでしょうか?

指標の可視化による共通認識の醸成や、効果的な施策による信用貯金を得ましたね。

変革を起こす準備が整いました。

そんな、株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。

hrmos.co

またお会いしましょう。

組込み開発にスプリント開発を取り入れた話

この記事は Akerun Advent Calendar 2020 - Qiita の 6 日目の記事です。

はじめまして、AkiAbe - Qiita です。
(まさか、初記事を誕生日に合わせて書くことになるとは思いもしませんでした。)

私は、2020/9 から Photosynth にジョインした新参者です。
2020/11 から弊社の組込みエンジニアチームでは スプリント開発を取り入れています。
ということで「組込み x スプリント開発」の話を書きます。

導入のきっかけ、背景

入社して一ヶ月くらい状況をみて感じたことを一言でいうと
「みんな、自分の作業 (主担当のデバイス) 以外のことに興味なさそう。チームとして機能していないなぁ。」
という印象をうけました。 (二言になっちゃったw)

以下、それぞれ文字にするとこんな感じです。
おそらく、どこの開発現場でもあるような気はします。

  • スケジュール全体の期間が大きい (クォーター単位とかでの管理)
    メンバー全員が、途中途中で「プロダクトのあるべき姿」を共有できていない。
    スケジュール完了にむけて、1 ヶ月後にどうなっているべきか? 2 週間後はどうか?の認識に差異がある

  • 属人性が高すぎる
    バイスごとに担当者が固定になっていて、リーダー以外はフォローできない。
    このご時世なので誰かが長期休んだり、特定のデバイスに機能追加が集中したら
    一気にボトルネックとなりそう。
    しかもチケットは切っているが中身が何も書かれてないものがほとんど。。

  • 作業進捗の遅れの検知が遅い
    リーダーと担当者しか作業の内容や方針を把握できていない。
    そのため、デイリーなどで進捗報告を聞いても
    「本当に大丈夫?」「こういうことは考慮しなくていい?」
    などのツッコミが、リーダー以外からできない。
    しかもチケットは切っているが中身が何も書かれてないものがほとんど。。(再掲)

  • レビューのタイミングが遅い
    設計レビューの明示的なタイミングがない。
    コードレビューで設計内容をみるような形 になっていて
    何か問題がおきると手戻りが大きくなりすぎる。

  • 機能品質と性能品質 (機能要件/非機能要件) がごっちゃになっている
    機能を作りこむタスクで、性能面にベクトルが向いてしまうことがある。
    一つのタスクの中でいろんな作業を混ぜ込んでしまい、完了時期がうやむやになってしまう。

改善したいこと

チームとして機能する状況をつくりたい。

全員が 1 ヶ月後、2 週間後、1 週間後、プロダクトがどうあるべきかを理解し
全員が 1 週間後のあるべき姿にもっていくために全力で取り組める環境にする
必要があると感じたため、スプリント開発を取り入れてみました。

決めたこと

スプリント開発に向けていくつか決め事をしました。
走りながら改善をする前提ですが、何もルールがないと始められないので
まずは以下のように定義しました。

スプリント期間

1 スプリント 1 週間 とします。

  • 毎週木曜からはじまって、水曜の午前中までが一つの区切り
  • 木、金の 2 日働いて、土、日でしっかり休んで、月、火の 2 日で終わらせる

というサイクルを目指します。

チームとして過去にもスプリント開発をしようとしたことがあるそうですが、当時はうまくいかなかったそう。
スプリント期間を短くして体に染み込ませられないかなぁと思い、短く設定しました。

定常的な会議の時間

以下の 3 つの会議を設定しました。

  • デイリースクラム (月、火、木、金で 15min )
    • 話す内容は以下の通り。込み入った話になりそうな時は、気づいた人が勇気をもって「別でやりましょう」という。
      • 昨日やったこと、それにどのくらい時間をつかったか
      • 本日やること
      • 困っていること
  • 次スプリントに向けたタスク分割 (火曜午後、各担当者 30min を目処)
    • 計画会議に向けた準備をする
    • 各自メインで知見のある担当デバイスが異なるため、ある程度の細分化は担当者とスクラムマスターで実施
    • その結果をもとに翌日の計画会議でタスクの説明をし、ポイントをつけるような流れとしてみた
  • スプリントの振り返りと計画会議 (水曜午後、max 2h を目処)
    • 振り返り内容
      • 予定通りスプリント内のタスクが完遂できたかの確認
      • 工数予実の可視化と確認 (見積もり精度を上げていくために)
      • KPT での振り返り
    • 計画会議の内容
      • タスクの説明会 (すでにキックオフで大きく分割して何をすべきかの全体象は全員理解しているので、やる事だけにフォーカス)
      • タスクへのポイント設定 (プランニングポーカー)
      • チームのポイントと、優先順位と相談して、やりきるタスクを選別

ポイントの決め方

後述するようにタスク粒度をちょっと粗めに定義しているので 1pt を 4h とする。
1 人あたりの 1 スプリントの稼働時間が 4.5 日で、各自事務作業や割り込み時間があることを想定して 1 日 7.5h 稼働できる という前提でポイントの計算をする。
また、次スプリントを計画する段階で目に見えた割り込み (例えば過去機種の障害調査の依頼がきている) なども考慮して チームの総ポイントを決定します。

タスクの粒度

1 タスク、最長 2 日としています。
1 タスク、1 日 or 半日で終わる粒度にもっていけるのが今の自分の理想。

作業管理ツール

backlog を使います。
というのも、弊社は組込み開発チームと横並びで、ハードウェア開発チームも存在していて
私がジョインする前から、両チームのタスクをまとめて backlog で 1 つのプロジェクトとして管理しています。

ハード開発側は backlog で、組込み開発側は redmine で、とツールをばらけて管理すると 統括のマネージャーが発狂してしまいますw
ので、本プロジェクトでは backlog をそのまま使い続ける決断をしました。

backlog の運用方法

backlog の使い方もある程度ルール決めました。

  • スプリント期間の進捗を管理するための、専用のマイルストーンを用意
  • 作業中に気づいたタスク (障害含む) はそのマイルストーンではチケット発行しない
    • 要は、「計画されてない作業はやらない」というのが基本スタンス
    • 作業中に発見した不具合などは、次スプリントに回す
    • (ただし、他チームが関わるような内容の作業の割り込みは容認する)
  • 振り返りが終わった時点で、完了になったタスクのマイルストーンから外す
    • これにより、毎週マイルストーンが「1 週間でやるべきもの」でリフレッシュされる仕組み

管理の側面 (苦労話含む)

ここからは管理側の側面から。

まず言葉の定義

ストーリー、タスクなどの意味合いもチーム内でズレないように定義します。
今回は、一般的な定義をそのまま踏襲させてもらっています。

IoT デバイス開発にかかわらず、基本的な開発の流れってこんな感じですよね。

  • A ということがしたい (ユーザストーリー : ステークホルダーの要望の単位)
  • じゃあ B 、C、D みたいな振る舞いがいるね (ストーリー : プロダクトオーナーの考える分割できる機能の単位)
  • B を実現するためには、X, Y , Z という手順でやらなきゃね (タスク : 開発者が作業する単位)

それをスプリント単位で考えると、GUI 系の開発を例とすると

  • スプリント 1 では画面だけ作ってリリースしますね。
  • スプリント 2 では、このボタンの動作をリリースしますね。

みたいな流れですね。
組込みで言うと

  • スプリント 1 では LED やディスプレイ使えるようにします
  • スプリント 2 では BLE 通信してその状態を LED の変色で通知します

みたいな感じで分割ですかね。

ストーリーの管理

弊社では、ハードウェア開発と組込み開発を並行して走らせており
ハード/組込みの開発スケジュールをミックスして管理しています。
そこで定義されてるソフトウェアの 1 機能を 1 ストーリーとしました。

また、上述のものは大枠のスケジュールとなるため実際にその機能を作るのに
どれくらい時間がかかるかは考慮されないことが多々あります。
( イメージしやすくするために少し乱暴に書くと 「X 月までにはこの機能できてないと困る」みたいな感じのスケジュール。)

そのため、一番最初に各ストーリーを、プロダクトオーナー、スクラムマスター、開発リーダーで粗めのタスクに分割して
「ざっくりと 1 スプリントでこのあたりまでやる必要がある」
というのを決める (ゴールを共有する) 作業をする必要がありました。

この作業を進めていくと
「ストーリー A は 3 スプリントくらいかかりそうだな。」
などが見えてきます。

こうやって、

・各ストーリーは実際のところどのくらいの期間をみればいいのか
・そもそも期間内に全部のストーリーの完遂が可能なのか

を具体化するところからはじめました。

このように洗い出しをした後に、プロダクトオーナーとステークホルダーとで
納期や優先度の調整をしなければなりません。
これができないと
できない約束 (もしくはデスマーチをして作る約束)
を、してしまうことになります。

そのため、「規模感を改めて開発チーム内で見積もる」を丁寧にやることが
とても大事なことだと感じています。

「できないことをできない」と言うことは悪いことではなく
「やりきれないことをやります」という約束をするのが一番悪いこと
だと、私は思っています。

タスクの管理

スプレットシートでストーリーとそのタスク、さらにスプリントの状況をまとめています。
次の項目と同じシートをつかって

  • タスク分解は開発者とスクラムマスターが個別に
  • 分解内容の共有とポイント付けはチーム全員で
  • スプリント終了前に、状況まとめをスクラムマスターが

というような流れでやっています。

スプリント内で、見積もり超過しているような作業があれば、デイリースクラム
backlog のチケットを開きながら、状況確認をするようにしています。

IoT 開発ならではの問題点

既出ですが、弊社はハードとファームを並行して開発しています。
そのため

  • メカのこの部品を変えたいから、それに合わせた試作ファームを作って欲しい
  • 回路のここがちょっと怪しいので、こういう評価できるようなファームを作って欲しい

などなど、ハード設計 FIX に向けて緊急で対応しなきゃいけないことを
お願いされることがしばしばあります。
製品開発上、必要な作業なので対応必須なのですが、そうすると当初の
スプリント計画が崩れて、スプリントの積み残しが増えてきます。

このあたりの割り込みを予想したうえでスプリント計画を立てるのに なかなか難しさを感じています。
ベストプラクティスは見つかっておらず、余裕を持ったスプリント計画にして
対応をしていますが、そうすると、全ストーリーの完遂が難しくなるという
あっちを叩けばこっちが出てくるような状態。。

1 ヶ月たった現状はどうなったか

もう 12 月になるのでスプリント開発に取り組んで 1 ヶ月が経過しました。
状況的には 、このあたりは改善傾向にありそうです。

  • メンバが自分の担当外の作業の状況も気にするようになった
  • チケットへの記載も丁寧になってきたため、情報の蓄積も共有も進んだ

まだまだ改善すべきこともたくさんあるので、これからも改善を繰り返して
よりよい製品をつくるために、よりよいチームビルディングができればなと思っています。


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com