Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

エラスティックリーダーシップ読書会 修了レポート

新卒入社三年目の小野です。校務チームで生徒を登録する機能の開発を行っています。 先日、弊社で新卒オンボーディングチームに所属されている @igaiga555 さんが主催するエラスティックリーダーシップ読書会を修了しました。会の概要や感想を書かせていただきます。

開催されるまでの流れ

新卒オンボーディングチームで、新卒メンバーにチーム開発時に知っておくべき知識を身につけて欲しい、という課題感があったようです。オンボーディングチームの方が、知識を身につけるには社内メンバーによく読まれている本を読むと良いのではと考えて、プロダクト開発部の雑談・相談チャンネルでマネジメントや組織についてのおすすめの本を募りました。結果、エラスティックリーダーシップ が最多得票しました。さらに、エラスティックリーダーシップについて、フロントエンドエキスパートチームの @lacolaco さんが「必読書で良いのでは」と強く勧めたことから、エラスティックリーダーシップ読書会をやろう、という動きが新卒オンボーディングチーム内で活性化したようです。その後、@igaiga555 さんが以下の呼びかけを行って、読書会が開催されることとなりました。

f:id:yukoono01:20211115154812p:plain

私は新卒入社の1人として必須参加だったこともありますが、社内で複数人の方がこの本を勧められていたのを見ていたため、本の内容に興味を持って参加しました。

読書会でやったこと

読書会は月曜日の1時間を使って行われていました。会の流れは以下です。

  • 参加者が集まるまで雑談する。(2分程度)
  • あらかじめ指定されていた章を各自で読みながら、感想をJamboardに書く。(人数により変動。だいたい25分)
  • 残りの時間でJamboardを見ながら、参加者が1人ずつ感想を読み上げていき、他のメンバーはコメントしたり、質問などをして議論する。

感想は最初の1回目はJamboardではなくesaに各自で書く形式でしたが、@kiryuanzu さんの提案により2回目以降はJamboardを使うようになりました。各自違う色の付箋を使うことでコメントを書いたのが誰かすぐ分かるようになり、リアルタイムな議論がしやすくなりました。

f:id:yukoono01:20211116180234p:plain
Jamboardを用いた議論の例

印象に残った章

私個人として一番印象に残ったのは、4.2.1節「必要なゆとり時間はどれくらいか」の一節である、「学習時間の生産性が通常の生産性よりも10倍も低い」です。目の前の仕事に追われるサバイバルモードから、スキルを伸ばせる学習モードにチームを導いていくべきであり、またモードを移行するにはゆとり時間が必要であるという説明の一部としてこの一節が書かれています。当時、私はフロントエンドにページビューを取るためのタグを埋め込むという全く経験のないタスクを任され、進捗が思うように上げられずにいました。この一節から、経験がないことを学習しながら進めることは、時間が10倍かかるのだから大変でも当然である、という気付きを得ました。もっとも、5章において学習のためには逆境に飛び込む必要があることが述べられており、学習が決して易しいことではないことも書かれています。

次に印象に残ったのは、6章の「コミットメント言語」です。コミットメント言語とは、相手に言質を与える言い方のことです(ex: 今週中までに終わらせます、毎日何時間ずつタスクに取り組みます、など)。逆にコミットメント言語でない言葉は、実現できない余地を残します(ex: ○○する必要がありますね、できるだけ早くやろうと思います、など)。コミットメント言語を使い個人のコミットメントが明確になることで、目標達成を阻害する要因を見つけることに役立ちます。 印象に残ったポイントとしては、私自身がコミットメント言語でない言い方を使いがちであったことや、コミットメント言語を習得すること自体が不快なものである、と感じたことです。話し相手が聞きたいことを言ってしまった結果、コミットメント言語ではない言い方を使ってしまう傾向があると気付いたので、今ではコミットメント言語を使うよう心がけています。コミットメント言語を習得することの不快さは、6.6節「どうやって取り組みに彼らを乗せるか」、8章「自己組織化を促進させるためにクリアリングミーティングを行う」を読んで感じました。チームでコミットメント言語を習得するためには、自分がお手本になってコミットメント言語を使うことや、相手がコミットメント言語でない言い方をした場合は言葉を直していくことが必要になると述べられています。これはやる側にとっても、やられる側にとっても不快な取り組みであると感じますが、新しいことを学び、安全地帯から出る時には不快になることは必要であると述べられています。何かを学ぶ際には不快になることを避けるべきではない、ということが、5章~8章での主要なメッセージであると読んでいて感じました。

感想

まず本の内容については、具体的な手法については応用できそうだと思えた一方で、この本ではリーダーに対して極めて高い技術力とコミュニケーション力、飽くなき向上心を求めていると感じたので、「こんなに凄いリーダーになるのは難しい」とも感じました。しかし、本の内容で同意できるところはいくつもありましたし、良いチームを作るためにリーダーがどう動くべきかを理解して、さらにリーダーを補佐できるチームメンバーになるためには、リーダーシップについての知識は必要だと感じました。実際に目の前の問題をどう解決するか?チームでどのように振る舞っていくか?については、読書会の他の参加者や先輩と議論しつつ、チームを良い方向に導いていけたらと思います。

読書会としては、新卒メンバーが書いた本の感想に対して @igaiga555 さんからさらに考えの深まるコメントを返していただくなど、和やかながら学びのある時間でした。議論が盛り上がる一幕もあり、特に評価制度について、「学習に時間を使えるようになるためには、評価制度に工夫が必要なのではないか」という観点で話が盛り上がりました。

読書会を通して学んだ、”コミットメント言語” を使うといった点を普段のチーム開発で心がけたところ、「できないことをできないとしっかり言ってくれるから仕事がしやすかった」とディレクターの方からフィードバック頂きました。今後も読書会への参加や、本を読むことは継続しつつ、得た知識を仕事で使っていくことも欠かさず取り組みます。

iOSDC2021でアンケートを取らせて頂いたので結果を公開します!

はじめに

こんにちは!

Classi 株式会社でiOSエンジニアをしている横田です。

先日開催されたiOSDC2021、弊社もスポンサーとして協賛させて頂きました。
当日はメンバー数名も参加してセッションを見て、リアルタイムチャットで感想を共有したり補足し合ったりして、とてもよい時間を過ごすことができました。

今年は2度目のオンライン開催で、運営もパワーアップしとてもスムーズに進行されていて、気持ちよくセッションを見ることが出来ました。運営のみなさまに感謝です!

来年以降はオフラインでの開催になるかもしれませんが、並行してオンラインでの開催もぜひお願いしたいところです。
というのも個人的には、沖縄県出身ということもあり、地方からの参加は旅費交通費のハードルが高いので、地方のエンジニアのためにもぜひご検討頂きたいです。

ただ、運用も例年以上に大変になってしまうと思うので、来年と言わず、将来的に実現してもらえれば嬉しいですね。

今年のiOSDC2021のセッションの内容も非常に有用なセッションが多かったのですが、個人的に印象に残ったのは、リファクタリングやサービスクローズの話、SwiftUIやGraphQLの話です。

iOSDC2021でのアンケートの結果について

弊社は、去年のiOSDC2020からスポンサーとして協賛させて頂いておりますが、今回、参加者のみなさまに向けてアンケートを取らせて頂きました。

参加されたみなさまには運営を通じてメールをお送りさせて頂きましたが、その中に弊社からのアンケートが含まれていますので、まだの方は今からでも遅くないのでぜひご回答頂けると嬉しいです。

既にアンケートにご回答頂いたみなさまについては、ご協力頂き本当にありがとうございました!

アンケートを取らせて頂いた目的としては、さまざまな会社や開発者からの運用の知見を集めて、まとめ記事のような形でご紹介することが出来れば、iOSのコミュニティなどに有益で面白そうな記事になるかなという狙いがありました。

その意味でこのアンケートの回答期限は設けておりません。いつでも構いませんので、ぜひアンケートにご協力いただければと思います。

アンケートはこちら forms.gle

アンケートの結果は以下のような興味深いものになりました。
※複数回答のパーセンテージは、回答者数に対するパーセンテージになります。

f:id:apla:20211115212508p:plain

5人以下の人数が半数以上という結果が出ました。

f:id:apla:20211115211956p:plain

GitHubが一番多いという結果になりました。コードレビューがしやすいからでしょうか?
その他の回答の中には、Google DocsやNotionといったツールを使っているという回答もありました。

f:id:apla:20211115212307p:plain

モックサーバーが簡単に立てられるからでしょうか、Swaggerが多いという結果になりました。
その他の回答の中には、GraphQLを使っているという回答もありました。

f:id:apla:20211115212310p:plain

Figmaが多いですね。
デザインツールに関連がある記事を見ていると、最近はFigmaを採用してるところがよく見受けられるのですが、思った以上に勢いがあるなと感じました。
その他の中にはZeplinも多く、中には手書きという回答もありました。

f:id:apla:20211115212313p:plain

ほとんどの回答者がコード品質を高める方法としてSwiftLintを利用しているという回答でした。Dangerも半数いるので、どのように運用されているか参考にしたいところです。

f:id:apla:20211115212316p:plain

テスト用アプリの配信・テスト実行・AppStoreへのアップロードでCIを活用しているという回答が多いですね。AppStoreの掲載情報更新は、弊社も取り入れたいところではあります。

f:id:apla:20211115212320p:plain

意外と定期リリースは行っていないところが多いですね。

f:id:apla:20211115212323p:plain

弊社だと学校単位での導入となるのでアプリのインストール数はコントロールできません。
そのため監視するデータとしてあまり見ることはないのですが、アンケート結果を見るとアプリのインストールを監視するというところは多いですね。
また、AppStoreのレビューは弊社だと非常にたくさんのコメントを頂いていますが、その中でもサービス利用に関する重要なレビューがないかどうかを監視しています。

f:id:apla:20211115212326p:plain

開発者がQAも行うところが多いですね。QA部門がない会社が多いのかなと推測できそうです。
その他の中には「開発者がおおよそのテスト仕様書を作成し、それに基づいて企画チームがQAを行う」といった意見も見られました。

アンケートの最後に「クオリティの高いモバイルアプリを安定して提供し続けるために開発チームに必要だと思われることがあれば教えてください」という質問をさせて頂きました。

この質問の回答には、以下のようにご意見も頂きました。

  • 自動テストを増やしていくことと、テストがちゃんとパスすること、壊れたらすぐに直すをキープし続けること
  • チーム内のフラットな関係性、PO, エンジニアのデザイン理解度
  • リファクタリング可能な状態を保つこと、コミュニケーションをとりやすい組織になるように努力すること

この質問に対して頂いたご意見をまとめてみると、以下を備えているチームならクオリティの高いiOSアプリを安定して提供できるのではないか?と感じました。

  • コミュニケーション
    意識や意思の統一や設計などの共通認識を揃えること
  • 技術力や人材
    ユーザーへの価値提供を実現できる技術力や、価値を届けるための自己研鑽を続けることができる人材
  • ユーザーファースト
    プロダクトがユーザーを幸せにするかどうかを基準にする

iOSDC2021でのアンケートの結果をうけて

今回のiOSDC2021でアンケートを取らせて頂いたのですが、いろいろと弊社の運用改善にも活かせそうなものも多く、あらためてご回答頂いたみなさまには感謝です。

今回、iOSDC2021でのアンケートの結果を受けて、開発者ですぐに導入できそうなものとしてまずはDangerの導入を検討しようと思っています。

理由としては、社内でもコードレビューの質を高めて品質向上を計る取り組みが検討されているので、より効率よくレビューが行えるように機械的な指摘はなるべくDangerに任せたいと思ったからです。

例えば、レビューの際のルールに以下のようなルールがあります。

  • PRの説明文にチケットへのリンクを貼る
  • 1つのPRに対して変更が多いときは、なるべくPRを分ける

これらに対する指摘は、機械的にDangerで指摘できればよさそうです。

もちろん、Danger のみでコードレビューにおけるすべての問題を解決することはできません。
機械的に判断できる点をDangerにてチェックし、人間の目が必要な観点にフォーカスしてメンバーでコードレビューを行う。それによりコードレビューの質が上がり、ひいてはコード自体の質が上がることを期待し、検証を続けてまいります。

まとめ

今年のiOSDC2021は参加者のみなさまからアンケートを取らせて頂けたこともあり、個人的にも会社的にも、よい学びがありました。
今後は、iOSDC2021で学んだことや得た知識をもって、Classiのアプリの運用に活用させて頂だくことはもちろん、iOSのコミュニティなどへも貢献できるような活動ができればと考えています。

Python Conference JP 2021で登壇してきました!!

こんにちは、データAI部でPythonエンジニアをしている平田(@JesseTetsuya)です。普段は、PoCとデータをもってくる、というところ以外全部やる、というスタンスで開発業務を行っています。

今回は、PyCon JP 2021で登壇してきましたのでそちらの登壇ブログになります。 いままで一人で世界中のPyConで毎年登壇してきました。今年は、三年目になります。

いままでの登壇歴

PyCon US 2019 at US(オフライン開催) Lighting Talk:"How to Transform Research Oriented Code into Machine Learning APIs w/ Python"

PyCon TW 2019 at Taiwan(オフライン開催) Talk: "How to Transform Research Oriented Code into Machine Learning APIs with Python"

PyCon JP 2019 at Japan(オフライン開催) Poster: "Hybrid Keyword Extraction Automated by Python With Cloud Speech To Text API and Video API"

PyCon HK 2020 at 香港(オンライン開催) Talk: "How to Transform Research Oriented Code into Machine Learning APIs w/ Python"

PyCon JP 2020 at 日本(オンライン開催) Talk: "How to Transform Research Oriented Code into Machine Learning APIs with Python"

PyCon Taiwan 2020 at 台湾(オンラインとオフライン開催) Tutorial: "How to develop ML APIs with Python from Online Learning Dataset"

PyCon APAC 2020 at アジア太平洋(オンライン開催) Panel Discussion: "ML/DL on Edge Computing"

PyData Global 2020 at 世界(オンライン開催) Talk: "Transformation from Research Oriented Code into Machine Learning APIs with Python"


また、Classiは去年に引き続き、今年もシルバースポンサーをしています!

さらに、データAI部にPythonエンジニアが一人増え、今年からやっと一緒に参加してくれる仲間が増えたので、記事を書いていきます。

今回の発表内容について工藤さんの初参加レポートを当記事に書いていきます。

発表内容

今年、発表したタイトルは、"Flask 2.0 vs FastAPI in REST API developments" です。

FlaskとFastAPIは、Pythonのマイクロフレームワークを選ぶ際に、よく選択肢として上がってくるマイクロフレームワークのうちの2つになります。

この2つを比較するのは、人によっては挑発的なタイトルだと思わせてしまうかもしれません。

Flaskが良いという内容であれば、FastAPIユーザを攻撃することに、FastAPIが良いという内容になれば、Flaskユーザを攻撃することなりかねない内容です。

ただ、結論から言うと、両方ともいいとこがありますよ、という内容です。 内容が全て英語なので、日本語で軽く補足していきます。

f:id:JesseTetsuya:20211102132947p:plain

JetBrains社の調査結果によると、PythonフレームワークのなかでFlaskが一番人気のようです。

f:id:JesseTetsuya:20211102133032p:plain

下記、4つのクライテリアを設定して、それぞれの軸で評価していきます。

  1. フレームワークの機能性や拡張性
  2. パフォーマンス(スピードと安定性)
  3. REST API設計の柔軟性
  4. 学習コスト

ここで、Flask 2.0としているのは、今年の5月にメジャーversion upがあり、大きく変更点がありましたので、比較するFlask のversionを2.0としています。詳細は、こちらのClassi開発者ブログ記事のFlask 2.0.xのアップデート項目紹介をご覧ください。

f:id:JesseTetsuya:20211102133046p:plain

フレームワークの機能性や拡張性という点において、FlaskもFastAPIでの大きさ差分はなく、あるとしたらFlaskのApplication ContextとRequest Contextの実装は、ユニークなのではないか、また、拡張性においてFlaskの方が多くの拡張モジュールがあるという意味で、Flaskのほうが多少フレームワークの機能性や拡張性があるという結論にしました。

f:id:JesseTetsuya:20211102133057p:plain

パフォーマンス(スピードと安定性) については、私が軽く実施した負荷試験や他の性能計測サイトでの確認によるとFastAPIの方が良いという結論です。これは、アーキテクチャや負荷試験の仕方によって異なってくる場合があります。負荷試験をどのコードをつかって、どう実施したかについては、スライドの中身を御覧ください。

REST API設計の柔軟性は、ディレクトリ構成の柔軟性という意味です。FlaskもFastAPIも似たようなディレクトリ構成が可能なので、どちらが良いかという判断はできない、と結論になりました。

f:id:JesseTetsuya:20211102133117p:plain

ここで学習コストをはかる指標として、書き方の難しさ書き方を知りやすいかという指標をおきました。

書き方の難しさの点において、両方とも簡潔な書き方ができるフレームワークです。また、Flask2.0とFastAPIの間では、書き方に殆ど差分がないと言ってもいいでしょう。

書き方の知りやすさに関しては、Flaskが2010年に作られ、FastAPIが2018年に作られたということもあり、Flaskの方が学習リソースは多いです。

そのため、Flaskの方が学びやすいだろうと結論づけました。

f:id:JesseTetsuya:20211102133300p:plain

総評として、Flaskの方が少し強みがあるのかなという結論になりました。これは、FastAPIの歴史がまだ浅いのが影響しているかと思います。

また、FastAPIは、未だにPEPになっていないASGI準拠のフレームワークです。

PythonコミュニティでのコンセンサスがとれているPEPにあるか否かは、Pythonコミュニティでの認知度や信頼度、開発スピードにも影響しているかと思います。

また、近年の技術進化の早さにより、どれだけ早くキャッチアップできるかキャッチアップしやすいか、という観点が技術選択において、大事です。

フレームワークの機能性や拡張性は、パッケージをインストールするか、モジュールを実装すれば済む話ですし、パフォーマンス(スピードと安定性)は、フレームワーク以外の部分、例えば、CPythonでかいたり、ロードバランサーを置くなり、インスタンスサイズをあげるなどの部分で補うことができます。

そのため、上記4つのクライテリアの中では、学習コストが一番大事な要素になると思います。

f:id:JesseTetsuya:20211102133234p:plain

最後にFlaskとFastAPIへの今後の期待を込めてのスライドを追加しました。FlaskとFastAPIの日本語でかかれた学習リソースが未だに少ないです。

学習リソースの量が増えれば、とくに書籍が増えると、学習者が増え、コミュニティのサイズも大きくなっていくと思います。

とは言いつつ、自分からアクションをしていかないと気がすみません。

そこで、来年度、Flaskについての書籍を出版します!楽しみにしていてください!

今回の発表や当記事をきっかけにFlaskとFastAPIへの興味を持っていただき、学習者が増え、みんなで学び合いができたら良いなと思っています。

PyCon JP 2021に初参加したミニレポート(工藤さん)

こんにちは、データAI部でPythonエンジニアをしている工藤( id: irisu-inwl )です。

今回はPyCon JP 2021に初めて参加したので、個人的に興味深かった講演について紹介します!

Vertex Pipelines ではじめるサーバーレス機械学習パイプライン

Sugiyama Asei さんの Google Cloud の Vertex Pipeline を使った機械学習パイプライン構築についての講演です。 公演詳細リンク

Vertex Pipelines は Kubeflow Pipelines SDK, TensorFlow Extended を利用したパイプライン実行できる ML パイプラインサービスです。

元々、Google Cloud には AI Platform Pipeline というKubeflow Pipelinesのマネージドサービスがありましたが、Vertex AI という AI Platform が GA となり、サーバーレスな MLパイプラインサービスとして Vertex Pipeline がリリースされました。

発表で下記のことを知ることができました。

  • fullstack Kubeflowと比較して、Vertex Pipelines の良いところとして、管理が楽 (Data Scientist には k8s を管理しながらは辛い)

  • 実際に弊社でもアプリケーション基盤として GKE の standard mode を運用していますが、バージョン管理戦略や、ノードの管理、スケーリングの設定など、諸々を考えなくては運用が難しいので、運用負荷が高いことは容易に想像ができました。

  • Kubeflow Pipelines を使った パイプライン構築の例

  • コンポーネント実行順序のプラクティス

  • Kubeflow上での GPU 利用などの計算リソースを設定する方法

弊社のデータAI部でも Vertex AI の様々な機能を MLプロダクト開発に活用していこうと考えているので、非常に参考となりました。

実装で知るasyncio -イベントループの正体とは-

REI SUYAMAさんのasyncioの生成処理部分を解説した講演です。 公演詳細リンク

こちらの講演に興味を持った理由は以下です。

  • データAI部で平田さんが FastAPI と Flask の性能比較などしていることもあり、asyncio は FastAPI を使っていく上で、理解を避けて通れません。

  • データAI部の勉強会で CPython Internals の Multiprocessing の章を読んでいたので、内部実装が気になったためです。

講演では、asyncio の具体的な処理の解説と、理解する上で必要な CPython の coroutine について解説されてます。

まず、generator の特徴を解説し、その次にcoroutine と generator の類似について説明することで coroutine を説明するアプローチがされてました。特にバイトコードでの処理の比較があったのは非常に理解しやすかったです。

Pythonでのコードの例と、実際に asyncio の内部挙動をシークエンス図として示しており、 EventLoop が Task を作ってから send で実行し、Future に結果を格納するまでの流れが詳細に分かりました。

参加してみた所感

今回、PyCon JP に初めて参加しましたが、最近の動向を知ることや、様々な Python Engineer の方の知見を得るいい機会となりました。

PyCon JP の会自体が円滑に運営されており、discordのチャットやボイスチャンネルの雰囲気も良く、楽しく参加することができました。

今回はオンラインでの参加となりましたが、是非今後はオンサイトでの参加や、スピーカーとしての登壇をしていきたいと思っております!


最後に、Pythonエンジニアの募集を引き続き行っています。

下記URLを確認していただきカジュアル面談の応募お待ちしています!

hrmos.co

インターン体験記

こんにちは。滋賀大学大学院データサイエンス研究科の白瀧 豪(しらたき ごう)です。 この度2021年9、10月の2ヶ月間、データサイエンティストのインターン生としてjoinさせていただきました。 このインターン期間の振り返りと学びなど書いていこうと思います。

インターン参加の背景

今回のインターンは、来年度の新卒入社に向けての準備という位置付けにあります。 そのため私はClassiという会社の雰囲気・業務の流れなど、自分がClassiで働くことのイメージをする機会と捉えて参加しました。

主な業務内容

私が所属した部署はデータAI部で、チームはコミュニケーションチーム(校内グループ・アンケート・コンテンツボックス・欠席連絡などのコミュニケーション機能を担当しているチーム)でした。

インターン期間には主に以下の3つの業務を行いました。

  • データAI部が関わっているプロジェクトのキャッチアップ
  • コミュニケーションチームでのダッシュボード作成タスク
  • Classiのデータを用いた探索的データ分析*1

最終週には、「Classiのデータを用いた探索的データ分析」の結果を中心にインターン期間の成果発表を行いました。

探索的データ分析を通しての学び

Classiのデータを用いた探索的データ分析を進めていく中で学びを

  • テーマ設定
  • 仮説の設計
  • 発表後のフィードバック

の3つの段階に分けて書いていきます。

テーマ設定

Classiのデータを用いた探索的データ分析がこのインターン期間でのメインのタスクでした。 このタスクはテーマ設定などもなく、自由に分析してほしいとのことでした。 これまで私が経験した過去のインターンやデータ分析コンペでは、テーマやデータが与えられた状態からスタートでした。 そのため、何から手をつけたら良いのかわからず戸惑いました。しかしそれと同時に分析テーマを見つけるのが最も大事な仕事ということにも気付きました。

そこでまずは、サービスの理解・過去行っている分析内容・自分の興味はどこかを整理しました。 最終的には、

  • 最も使われている機能は校内グループであること
  • 先生ごとに活用レベルが大きく違うこと
  • 入社の志望動機である「学校の先生をサポートしたい」だったこと

この3つを組み合わせて「校内グループにおける先生の活用レベルでの違いに関する分析」をテーマとして設定して分析を進めました。 (ここまでに1ヶ月ほどかかってしまった…)

f:id:ClassiJP:20211101162154p:plain

仮説の設計

テーマ設定ができたので、探索的にデータ分析をするといろんな傾向が見えてきました。 しかし仮説を設定していなかったため、背景や目的がわからず、分析結果に対しても「へぇー」という感想にしかなりませんでした。 ここで仮説を立てて、その仮説を検証することの重要性に気付きました。

仮説ベースで分析を進めることができたかというと、あまり実現できなかったかなという印象です。 知識としては知っていたり、頭でわかっていてもそれを実行することの難しさを痛感しました。 この部分が自分の今後の課題かなと感じました。

発表後のフィードバック

私の成果発表に35名ほどの方に参加していただきました。(たくさんの方が参加してくれてびっくりしました…笑) 発表後にデータAI部以外にもいろんな部の方から質問・コメントをいただきました。

ユーザーストーリーをもう少し考えることができれば、より良い分析ができたのかなという気づきができました。 その他にも、資料の作成方法・テクニックや伝え方などの基本的なところから丁寧にアドバイスをいただけて大きな学びになりました。 これらのフィードバックを整理していく中で、入社後に挑戦してみたいことがいくつか思いついたのでとても良い経験・機会になったと思います。

全体を通して感じたこと

インターン期間の最初にClassiのサービスを実際に触ってみました。そこで、サービスの機能についてや使い方について疑問に思ったことをドキュメントにまとめたところ、とても反響が大きく驚きました。

f:id:ClassiJP:20211101162251p:plain

「Classiのサービスをずっと触っていると気付けないから参考になる」や「実際に使い始めた先生は同じことを感じるはずだ」というコメントをしていただいて、吸収する雰囲気が社内全体にありました。 こういう雰囲気が発言しやすい環境に繋がっているのかな、と強く感じましたし、ClassiのValueにもなっているUnlearn & LearnやLove Diffenreceとはこういうことでもあるのかなと思いました。

さいごに

このインターンを通してClassiについて知ることができ、自分がClassiで働くことのイメージをつけることができた良い機会になりました。 それもメンターの方をはじめ、データAI部やコミュニケーションチームのメンバーのサポートがあったおかげだと思います。 本当に感謝しています。

これから大学院の研究に戻りますが、 研究を進める中でデータサイエンスの専門的な知識やドキュメント力などレベルアップして来年4月にClassiに戻って来たいと思います。

*1:探索的データ分析(EDA:Exploratory Data Analysis)とは、データの特徴を探索的に分析し、構造を理解することを目的とした最初に行う作業を指す

RubyKaigi Takeout 2021 参加レポート

はじめに

Classi 株式会社 開発本部です。

先日開催された RubyKaigi Takeout 2021、弊社もスポンサーとして後援したりメンバ数名が参加してセッションを見たりして盛り上がりました。
毎日の開発で日常的に使いつつもどんな人がどのように作っているかをあまり意識していない Ruby そのものについて色々なことが知れる刺激的な Kaigi だったと思います。

以下、参加したメンバの印象に残ったセッションの感想になります。

Ractorをワーカーとして使うアプリケーションサーバの課題

1年前に新卒入社したWebtestチームの@minhquangです。 Classiのおかげで、初めてのRubyKaigiに楽しく参加できました。 私にとってほぼ未知の世界なので、様々なセッションを見てみました。
今回は一番興味があった tagomoris さんRactor's speed is not light-speedに関するお話を紹介します。

Ractor は 笹田さんから2016年に紹介されて、CPUのコアを並列で実行できる仕組みとしてRuby 3.0に導入されました。 (※ Ractorの仕様を詳しく知りたいなら、Ruby repository の資料をご覧ください)

Ractor間でオブジェクトはメッセージとして共有されるのですが、以下のオブジェクト以外は共有禁止されています。

  • Module, Classes
  • Application Code (Proc)
  • Definitions (constants), Settings/Configurations (frozen objects)

Ractor間でオブジェクトを共有するには、オブジェクトにshareableをマークする必要があります。

# Usual Proc
x = 1
p1 = ->() { x + 2 }

p p1.call #=> 3

x = 5
p p1.call #=> 7


# Isolated Proc
x = 1
p2 = ->() { x + 2 }
p Ractor.shareable?(p2)
# false
Ractor.make_shareable(p2)
p Ractor.shareable?(p2)
# true
# p2 is isolated

p p2.call #=> 3

x = 5
p p2.call #=> 3 (!)

このようにマークすると、Proc自体はisolatedになって共有できるようになります。

けど、Procの中で共有できないオブジェクトがある場合はもうちょっと深くisolated化にする必要があります。

s1 = "Yaaaaaaay"
p3 = ->(){ s1.upcase }
p Ractor.shareable?(p3)
=> false
Ractor.make_shareable(p3)
# <internal:ractor>:816:in `make_shareable': can not make shareable Proc because it can refer unshareable object "Yaaaaaaay" from variable `s1' (Ractor::IsolationError)

s2 = "Boooooooo".freeze
p4 = ->(){ s2.upcase }
Ractor.make_shareable(p4)
# OK

なお、この辺の面倒なのを避けるために Ruby 3.0 には凄く便利なマジックコメントが追加されているみたいです

# shareable_constant_value: literal

TABLE = {a: 'ko1', b: 'ko2', c: 'ko3'}
#=> Same as: TABLE = Ractor.make_shareable( {a: 'ko1', b: 'ko2', c: 'ko3'} )

(セッションの中でもこういうマジックコメントほしい!と tagomoris さんが言ってましたが既にあったようです。ブログでもフォローされていました)

Ractorを使ってどのようにWebアプリケーションのパフォーマンスを向上させるか、4コアなら4倍になるのか、 tagomoris さんはRactorをワーカーとして使うアプリケーションサーバのright_speed を作りました。

私も tagomoris さんの作ったデモで実験してみました。

Rackサーバで起動してみると以下のエラーが発生しました (Bug #18024)。また、 RailsとSinatraを起動してみたところエラーもたくさん発生しました。

# Rackサーバーを4つのworkerで起動する
> right_speed -c config.ru -p 8080 --workers 4
# wrkでベンチマークテストする
> wrk git:(master) ./wrk  -t12 -c100 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
  12 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     8.67ms    1.69ms  13.77ms   71.14%
    Req/Sec   328.83    105.85   484.00     66.67%
  797 requests in 30.04s, 51.37KB read
  Socket errors: connect 0, read 796, write 0, timeout 0
Requests/sec:     26.53
Transfer/sec:      1.71KB
# Rackサーバーでエラーが発生した

7fff90200000-7fff90400000 rw- /usr/lib/dyld
7fff90400000-7fffc0000000 r-- /usr/lib/dyld
7fffc0000000-7fffffe00000 r-- /usr/lib/dyld
7fffffe00000-7fffffe01000 r-- /usr/lib/dyld
7ffffff3f000-7ffffff40000 r-x /usr/lib/dyld
[IMPORTANT]
Don't forget to include the Crash Report log file under
DiagnosticReports directory in bug reports.

[1]    27965 abort      right_speed -c config.ru -p 8080 --workers 4
# 同じようにSinatraでもエラーが発生します
[2021-10-05 22:17:05 +0900] ERROR Unexpected error: can not access instance variables of classes/modules from non-main Ractors

確かに上記の説明と同じように Rack/Rails/Sinatraの中に unshareableが多すぎて問題が発生しました。 unshareableオブジェクトはRactor間で共有できないため、オブジェクトをshareableにマークしたり、オブジェクトの中にもデフォルトインスタンスや frozenなどもdeepに指定したりしなければなりません。

Ractorはまだまだ新しいものですし、既存のプロダクトに導入するには対応しなければならないことが多くありそうに思いました。しかし、Ractorで動くアプリケーションの未来は面白いと感じますし、対応が大変だからこそ Contributionチャンスになります。自分も出来る限り、この未来に力を入れたいと思います。

Ruby開発の実情を聞いて背筋がピンとした話

こんにちは。プロダクト開発部 webtestチームに所属している中村(真)@s_nakamuraです。今回RubyKaigi Takeout 2021に参加しました。オンライン開催ということで雰囲気はどうなるのか楽しみでしたが、実際想像していた以上にオンラインでも以前参加したRubyKaigiと同じような熱気を感じることが出来ました。
さて私は今回一番印象に残った「How to develop the Standard Libraries of Ruby?」について紹介したいと思います。 このセッションではRubyの開発がどのような観点を持って進めているのか話されていました。

最初にRuby3.0についてです。RubyはStandard LibrariesとDefault Gemsで構成されていて、必ず含まれていなくても良いものはBundled Gemsとされています。
このような構成にすることでセキュリティ対応の時にアップデートが必要な箇所だけアップデートすれば良いというのは、理にかなっていると思いました。各機能が適切に分割されて作られていれば、問題があった箇所だけ入れ替えることで確認すべき範囲を絞り込むことが出来ます。使う側としては確認する作業に変わりはないですが。

次に3.1についての話もありました。それによるとRuby3.1からdefault gemに含まれていたライブラリを幾つかRubyのリポジトリから外した物がありました。その一方で外せなかったものもあったというのが興味深かったです。例えばEnglishというgemは外したかったがrubocopの方で推奨されるなど影響度が広いためdefault gemsから外せなかったとの事でした。何をdefault gemsとして入れるか判断するのに現在の状況や他のgemの挙動/世の中への影響度も考慮に入れて判断しているというのが、言語開発という世の中に大きな影響を与えているプロジェクトの苦労するポイントなのかと思いました。

そして一番これは大変だと思ったのがRuby開発者それぞれが開発したコードをマージしていく作業についてです。ある程度までは自動チェック出来るそうですが、自動でチェック出来ないところは「手動による心温まる手作業」との事です。
普段業務でたまにconflictが発生することがありますが、それを解消するのも割と神経を使う作業ですし骨が折れるときもあります。それが開発言語の開発で発生した場合に手作業でマージする作業が如何に神経を使う繊細な作業か・・・・。開発人数が多くなったり、規模が大きくなるとそういう部分の苦労もある、今Rubyが使えているのは日々言語開発者の方々の繊細で緻密な作業の結果なのだと再認識し背筋がピンとのびました。

その他

あとセッションの内容とは直接関係ないのですが、gitではリポジトリが違ってもcherry-pickが出来るというのが勉強不足で知りませんでした。どんな感じで出来るのか、試しに自分のプライベートで使っているリポジトリで試してみました。試してみたことはまずリポジトリAでhoge.txtというファイルを追加しcommit & pushします。次に同じ修正をリポジトリBに入れるというのを試します。

$ git add hoge.txt
$ git commit -m'hoge.txtを新規に作成'
$ git push origin HEAD
$ git log
commit f863xxxxxxxxxxxxxxxxxxxxxxx (HEAD -> master, origin/master, origin/HEAD)
Author: nakaearth <shinichiro.nakamura@classi.jp>
Date:   Wed Jul 10 15:29:29 2019 +0900
次にリポジトリBで先ほどリポジトリAでした修正をcherry pickする。
最初にリポジトリBに移動する
$ cd repo_b
git remote add でリポジトリAを追加する
$ git remote add add_hoge https:://github.com/nakaearth/repo_a
add_hogeをfetchしcherry-pick
$ git fetch add_hoge
$ git cherry-pick add_hoge

cherry-pickした後に実際リポジトリAで行なった作業がリポジトリBにも反映されていることが確認できました。今回は簡単に1ファイルだけでしたが、これが複数のファイルで更にコンフリクトが発生した場合、これもまた繊細な作業になると思いました。

以上が「How to develop the Standard Libraries of Ruby?」についての私のレポートになります

RubyにおけるDSLの短所を克服するための静的解析支援

新卒入社3年目の@willsmileです。アプリチームでサーバサイドの開発・運用を担当しています。
会社からもらったスポンサーチケットで、今年のRubyKaigiにも参加できて、3年前初めて参加する時の印象と変わらず、セッション内容の多様性に富んでいると感じています。それに参加することを通じて気づいたことを言語化し、他の人に紹介する経験は、自身の技術者のロールモデルの形成と更新にとても役に立つと自覚しました。このような経験学習において自身のモチベーションを高めるために、今回は技術ブログの執筆に担当させてもらいました。

紹介したい発表は、@paracycleさんのDemystifying DSLs for better analysis and understandingです。以下でこの発表の内容を自分の言葉で説明してみます。

  • DSL 1 の特徴
    • 長所:複数の場所で繰り返されるボイラープレートコードを無しにできること(No boilerplate)と、シンプルな表現でAPIを定義できること(Natural API)
    • 短所:Static Analysisが難しくなり、Code Readabilityが低下する恐れがある
  • 問題定義
    • Rubyで構築されたDSLを、RBI・RBSのような静的型解析にも対応できれば、上記の短所を乗り越えられるのではないか
  • 解決方法
    • DSLにより動的定義されたメソッドに対応して、RBIを自動生成するライブラリーtapiocaを開発した 2

手元で簡単な Rails app を作成し(要件:UserがArticleを作成・編集・一覧・削除でき、1件のArticleに複数個のTagを付けることが可能)、 tapiocaのREADME.mdを見ながら、手元で各モデルのRBIを作成してみました。モデルの定義と生成されたRBIのファイルは以下の具体例で示しています。 3

# article.rb

class Article < ApplicationRecord
  belongs_to :user
  has_many :article_tags
  has_many :tags, through: :article_tags, dependent: :destroy

  enum status: {archived: 0, wip: 1, published: 2}, _prefix: true
end
> bundle exec tapioca init
> bundle exec tapioca dsl Article
# article.rbi

# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Article`.
# Please instead update this file by running `bin/tapioca dsl Article`.

# typed: true

class Article
  include GeneratedAssociationMethods
  include GeneratedAttributeMethods
  include EnumMethodsModule
  extend GeneratedRelationMethods

  sig { returns(T::Hash[T.any(String, Symbol), Integer]) }
  def self.statuses; end

  module EnumMethodsModule
    sig { void }
    def status_archived!; end

    sig { returns(T::Boolean) }
    def status_archived?; end
    #...
    #量が多いため、一部コードを略する
  end

  module GeneratedAssociationMethods
    sig { returns(::ActiveRecord::Associations::CollectionProxy[::Tag]) }
    def tags; end

    sig { params(value: T::Enumerable[::Tag]).void }
    def tags=(value); end

    sig { returns(T.nilable(::User)) }
    def user; end

    sig { params(value: T.nilable(::User)).void }
    def user=(value); end
    #...
    #量が多いため、一部コードを略する
  end

  module GeneratedAttributeMethods
    sig { returns(T.untyped) }
    def status; end

    sig { params(value: T.untyped).returns(T.untyped) }
    def status=(value); end

    sig { returns(T::Boolean) }
    def status?; end

    sig { returns(T::Boolean) }
    def status_changed?; end

    sig { returns(T.nilable(T.untyped)) }
    def status_was; end
    #...
    #量が多いため、一部コードを略する
  end

  module GeneratedRelationMethods
    sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
    def not_status_published(*args, &blk); end

    sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
    def status_published(*args, &blk); end
    #...
    #量が多いため、一部コードを略する
  end
end

生成されたRBIファイルを眺めてみて、以下のことを気づきました。

  • Railsの仕組みにより、DSLとして自動生成されたメソッドには以下のような分類がある。
    1. GeneratedAssociationMethods:アソシエーション(ActiveRecord::Associations)により定義されたされたインスタンスメソッド
    2. GeneratedRelationMethods:クエリインターフェイス(ActiveRecord::Relation)により定義されたクラスメソッド
    3. EnumMethods:Enum(ActiveRecord::Enum)の定義により定義されたインスタンスメソッド
    4. GeneratedAttributeMethods:属性(ActiveModel::Attributes)により定義されたされたインスタンスメソッド
  • GeneratedAttributeMethodsで定義されたstatus_changed?status_wasなどActiveModel::Dirtyにより定義されたメソッドは初めて知った
  • specific_instance_of_article.tagsの戻り値のタイプがActiveRecord::Associations::CollectionProxyであることに“なるほど”と思った

今回の試みを全体的に振り返ってみると、業務の中でtapiocaを実際に使う機会が少ないかもしれないが、Railsで定義された便利なメソッドを網羅的に知るきっかけになったと思います。冒頭でも述べたように、RubyKaigiではいろいろな“面白い”発表があります。その面白さは、人によって捉え方が違います。人(発表者)がどのような問題定義・解決方法を考えているのかを考えてみること、自分が少し試して気づいたことを話してみることは良い学び方かなと考えて、お勧めします。

参考文献

Fowler, M. (2010). Domain-Specific Languages. Pearson Education, p28.

Ruby3.1 から irb が進化するみたいなのでさわってみた

今年Classiにエンジニアとして新卒入社しました北村です。
今回私もRubyKaigi Takeout 2021 に参加し、初めて RubyKaigi を体験しました。運営の方、発表者の方、視聴されている方、全ての方から Ruby への熱い思いが溢れ出るこのイベントでまさに「Ruby 漬け」な三日間を過ごすことができたのは、とても貴重な経験になりました。

そんな RubyKaigi Takeout 2021への参加レポートとして、私からは @aycabta さんによるセッション「Graphical Terminal User Interface of Ruby 3.1」で発表された irb の新機能について、その内容と実際に使ってみた時のログを書きたいと思います。

セッション要点

Ruby3.1 から irb において以下の二点が新機能として追加されると発表されました。

  • 自動補完を実現する dialog window 機能
  • dialog window 内での RDoc 参照機能

dialog window 機能についてはもともと @aycabta さんが reline という gem の中でこれまで実装されてきた機能で、それが Ruby3.1 の irb で採用されるということでした。
RDoc の dialog window 内での参照機能については、元々 RDoc の参照機能自体がすでにリリースされた irb で実現されていた機能ではあったものの、その使用体験に問題意識を感じた@aycabta さんが dialog window 内で RDoc を参照できるように実装されたということでした。

やってみた

今回発表された新機能は、 Ruby3.1 が出るのを待たずしても prerelease 版の irb をインストールすればいますぐ使えるということだったので試しに触ってみました。

準備

(今回は Ruby 3.0.2 で検証しました。)

  • gem install irb --pre を実行
    • reline と irb の prerelease 版がインストールされました
  • irb -v でバージョンを確認
  • f:id:ClassiJP:20211011181204p:plain:w500

確認

まずは dialog window の表示してみる

irb を起動してみてどういう感じに dialog window が表示されるのかを見てみました。
セッション内の demo では String クラスが例として使用されていたので、ここでは Array クラスを見てみようと思います。

  • irb を起動しA とタイプ

    • f:id:ClassiJP:20211011181124p:plain:w500
  • tab キーを押して dialog window 内の Array を選択する

    • f:id:ClassiJP:20211011181039p:plain:w500

ちゃんと dialog window が出て自動補完が効いていること、そして RDoc も dialog window 内に出ていることが確認できました。(Alt+d を押せば対象のドキュメントを全て表示することもできます)

処理中に挟んだ binding.irb の場合どうなるの?

ここまでやってみて、ふと「binding.irb などを使って処理の途中で irb を実行した場合についても、処理に関わるクラスやそのメソッド、変数などについて自動補完機能を利用できるのでは?」ということを感じたので、それについても試してみました。

  • サンプルコード
class Book
  def initialize(title)
    @title = title
  end  

  def title
    @title
  end
end

book = Book.new("title")
binding.irb
  • コードを実行し止まったところでメソッドや変数の自動補完が出るか確認
    • bと打った時点で book が候補の中に表示される
      • f:id:ClassiJP:20211011180827p:plain:w500
    • tabキー押下で book まで打ち込める。そこから、. を打つと title と表示される。再び tabキー押下で title まで打ち込める
      • f:id:ClassiJP:20211011180541p:plain:w500
      • f:id:ClassiJP:20211011180501p:plain:w500

自動補完機能はこのような使用用途でもきちんと使うことができそうです。
これなら irb の使用中にクラス名やメソッド名がわからずにいちいちコードを見にいって確認する、などの手間が省けそうで開発者にとっては嬉しい限りですね。

そしてこの検証をした後に気づいたのですが、実はこの内容、 Rails を背景としたお話ではありましたがセッション中に @aycabta さんがきちんと言及されていました。

Now you can use the rails console without worrying about adding many classes and methods to your business code.
(aycabta/RubyKaigi2021_daihon.md より)

rails console は内部で irb を使用しているということで、rails での開発体験についてもかなり向上が見込めそうです。

実際Classiでも「たくさんのクラスやメソッドが定義された rails コード」が多数存在します。もし rails console 上でクラス名やメソッド名が自動補完されるようになれば、 debug の際などに非常に嬉しいはずです。今後の日常の開発でもどんどん使っていこうと思いました。(なお、使用用途によっては debug gem を使用していくのが良い場合もありそうです)

以上、「Graphical Terminal User Interface of Ruby 3.1」セッションに関するレポートでした。

Rails app に RBS 導入試してみた!

開発本部所属エンジニアの匿名希望です。

今回見たセッションでは @pocke さんの The newsletter of RBS updates がよかったです。

※セッションの内容については公開されてる動画を見るのが早いと思うので割愛します

Ruby の型関連、気になってはいたのでたまにブログ記事とか見てへ〜みたいになりつつも導入までは至ってなかったんですが、このセッションで rbs collection っていうのを使うと始めやすいっぽい!と知れたのでせっかくだしちょっと触ってみよ〜ってなりました。

早速業務コードで……と思ったのですが、まずは簡単にお試し。

以下で試したサンプルはこちら:

rails scaffold で簡単なアプリ作って→ライブラリ等の設定をして→以下の型定義を作って、

# 引数を取らずに string を返すよ
def id_string: () -> String

型定義に合わないように実装ミスをして、

def id_string
  # 型定義では String を返すことになっているが Integer を返す
  id
end

型検査をしてみると、

> bundle exec steep check

app/models/task.rb:2:6: [error] Cannot allow method body have type `::Integer` because declared as type `::String`
│   ::Integer <: ::String
│     ::Numeric <: ::String
│       ::Object <: ::String
│         ::BasicObject <: ::String
│
│ Diagnostic ID: Ruby::MethodBodyTypeMismatch
│
└   def id_string
        ~~~~~~~~~

ちゃんと怒られた!うれしい!

やってみた感想は、rbs collection 最高〜!こんな導入簡単でいいの?です。 今回試す前に rbs で検索して出てきた他の方が書いた過去のブログとかも見て予習していたのですが、git submodule したり長いコマンドとか打ち込んでてめっちょ大変そう〜って思ってたので、シュッと終わって正直拍子抜けでした。

ってわけで業務コードにも導入!……と思ったのですが、年代物のコードだとあれこれ出てしまってすんなりはいかなそうでした🙃 とまれ、簡単なアプリで試して勘所を軽く掴んだ気がするので引き続きやっていこうと思います〜。

終わりに

個人的にオンラインの Kaigi に参加したのは初めてだったのですが、セッションごとのチャットで講演者に質問して盛り上がったり、社内の Slack で実況中継したりオンラインならではの楽しみ方ができてとてもよかったです。

素晴らしい Kaigi を開催してくれた運営チームの皆さんに感謝です!


  1. DSLとは、Domain Specific Languageの略語で、特定のドメインでのタスクのために設計・実装されたプログラミング言語です。Martin Fowler氏はその実装方式によりDSLをExternal DSL、Internal DSL、Language Workbenchという3つのタイプに分類しました(Fowler, 2010)。今回紹介する発表でのDSLは、Rubyのメタプログラミングの特徴を生かして構築されたinternal DSLのことを指しています。

  2. 実現する原理・方法は、発表ビデオの16分~20分の間に説明されたので、興味がある方は詳細をご覧ください。

  3. サンプルコードは、ruby 2.7.4、rails 6.1.4.1、tapioca 0.4.27により作成しました。

QAチームが取り組む「品質の見える化」への挑戦

こんにちは、QAチームの牛木です。

QAチームでは今期「品質の見える化」に挑戦しています。 この記事では、QAチームが取り組む「品質の見える化」の歩みをお話します。

なぜ「品質の見える化」をやるのか

昨今のソフトウェア開発手法の主流が「ウォーターフォール開発」から「アジャイル開発」(アジャイル開発の中でもスクラム開発)へ変化しつつあります。

アジャイル開発においてもテスト業務は依然として必要ですが、包括的なドキュメントではなく、動くソフトウェアや対話の中でのテスト設計、開発サイクル全体を見通した素早いテスト実施、開発から運用まで含めたプロセスの中での継続的なフィードバックの獲得も求められます。 こういった体制を「DevOps」とも捉えていますが、QAが継続的なテスト、継続的なフィードバックを提供する足掛かりとして「品質の見える化」に取り組んでいます。

「品質の見える化」とは何か

「見える化」とは、”「可視化」された対象を「モニタリング(監視)」し、「課題を抽出・分析」、フィードバックに基く「改善活動を行う」ことである” とQAチームでは考えます。 「見える化」という言葉は、トヨタ自動車による業務改善の観点において初めて登場した言葉です。

可視化の対象となる「品質」は、現在以下のデータに絞っています。

  • QAチームが検出した不具合データ
  • QAチームが担当したテスト業務データ

ソフトウェアにおける「品質」の定義は、企業によって多種多様であり、品質の対象もさまざまです。

品質の定義から、ISO/IEC9126の品質特製(プロセス品質、内部品質、外部品質、利用時の品質)を思い浮かべる人もいれば、狩野モデルの品質要素(魅力品質、一元的品質、当たり前品質)を思い浮かべる人もいるのではないのでしょうか。 この全ての品質をスコープとすると膨大なデータと、そのデータを蓄積するための運用整備が必要となります。そのため、まずはミニマムスコープとしてQAチームの管理下で蓄積・運用されているデータを対象としています。

 今何をやっているのか

「品質の見える化」のプロセスとして、以下ステップを目標に活動を進めています。

  1. 品質データの”蓄積”
  2. 品質データの”可視化”
  3. 品質”課題抽出・分析”
  4. 品質”フィードバック”
  5. 1~4のサイクルの”運用”
  6. 他チームへの横展開

f:id:cku0301:20210913164859p:plain
社内に展開した「品質の見える化」のサイクル

上記ステップのうち、1”蓄積”と2”可視化”に現在取り組んでいます。 その活動の詳細についてお話しします。

 1. 品質データの蓄積

前述した品質データは、タスク管理ツール「Asana」を使い、QAチームがチケット管理をしています。 各データには以下のようなラベリングをしています。

  • 不具合データ:不具合分類、不具合レベル、不具合混入工程、不具合見逃し理由、不具合検出手法など
  • テスト業務データ:案件名、開発チーム、テスト工程、テスト項目数、実績工数など
    f:id:cku0301:20210913165114p:plain
    QAチームが管理するAsana

各チケット(データ)はQAチームが各プロダクトチーム統括でClose作業をしており、ラベルの未入力チェックや、不具合のステータスチェック(例えば、案件がCloseしているのにも関わらず、案件に紐づく不具合がOpen中である場合には確認を入れる等)のチェック運用を行っています。

 2. 品質データの可視化

BIツール「Tableau」を使い、「Asana」に蓄積された品質データのダッシュボードを作成し、社内に展開しています。 社内の役割によって気になる観点が異なるため、「全社向け」と「プロダクトチーム向け」に分けてダッシュボードを作成しています。

「全社向け」では、Classiサービスの品質状態が良いのか悪いのかを端的に伝えるために、Classiサービス全体の平均不具合件数や不具合密度の推移、不具合の改修状況などを表示しています。

f:id:cku0301:20210913165238p:plainf:id:cku0301:20210913165324p:plain
全社向けのダッシュボード一部抜粋

「プロダクトチーム向け」には、機能毎に不具合データのラベリング別の割合や、推移を載せています。各チームが、不具合の傾向から原因や課題を拾いやすくすることを目的としています。

f:id:cku0301:20210913165646p:plainf:id:cku0301:20210913165655p:plain
プロダクトチーム向けのダッシュボード一部抜粋

現在取り組んでいるステップとして「1.品質データの蓄積」と「2.品質データの可視化」をお伝えしました。

可視化のステップは次に見据えている”品質課題抽出・分析”のための活動でしたが、可視化をして最初に見えてきた課題は蓄積ステップの運用課題でした。 例えば、ステータスの中で新規起票状態のチケットが多いことが分かったのですが、これは実際に新規起票チケットが多いのではなく、ステータス更新が適切に行われていないことが原因でした。 他にも不具合レベルがあるレベルに偏っておりレベルの細分化・再定義が必要であったり、ある項目の未入力が多くフローがうまく機能がされていないことが判明したりと、可視化をすることで前ステップの改善にも繋げることができました。

蓄積されたデータが正確でなければ品質課題の抽出もできません。蓄積と可視化を反復しながら品質データが適切に蓄積されることが見える化における初めの一歩になると思います。

 今後何をやるのか

今後のステップとして、蓄積/可視化の管理・運用を推進しつつ、「3.品質課題抽出・分析」と「4.品質フィードバック」の取り組みを開始しています。

品質データの「蓄積」「可視化」では、品質データの対象をQA管理下のデータに絞り込んだこともあり、QAチーム主体で活動を進めることができました。 しかし、品質「課題抽出・分析」「フィードバック」では、プロダクトチームを巻き込んだ活動でないと価値を出すことは難しいと考えています。

というのも、Classiのプロダクトチームは複数存在しており、チーム毎に開発スタイル、リリースサイクル、人数、担当機能などが異なります。チームによってデータ結果の背景・原因は異なりますし、重視している観点も異なります。

「可視化」したところで...

  • 可視化したデータをそもそも見てもらえない
  • データを見ても、「それで?」となる
  • データ結果が実際の業務と紐付けられない
  • なぜこのような結果になっているのかの根本的な背景や原因が分からないから活用できない

などなど...

Classiサービス全体としてデータの結果を表示できても、チームに寄り添った分析とフィードバックを行えなければ、「見える化」できているとは言えません。

そこで現在は、プロダクトチームに参画し、品質データを生かしたフィードバックをどう推進していくのが有効か?の情報収集をしている段階です。他チームへの展開も視野に入れて、まずは特定チームで「品質の見える化」のサイクルを確立することを目指して活動をしています。

 おわりに

「QA」と聞くと「テスト業務」が連想されると思いますが、QAはQuality Assuranceであり、「品質保証」業務全般を差します。最近はQAの担当領域も広がってきましたが、品質目標やQAが担う領域は、企業によってさまざまであると感じています。わたしも勉強中の身ですが、Classiにおける「品質保証とは?」をつきつめられるように精進していきます。

Classi QAの品質向上への道

こんにちは、Classi QAチームの竹林です。 Classi QAチームでは、単にテストをするだけのチームではなく品質向上をミッションとするチームとして、品質向上に向けた施策を実施してきました。

この記事は、Classi QAチームの品質向上に向けた歩みの共有になりますので、QAの進め方について検討している方の参考になれば嬉しいです。

「品質の見える化」で始める

Classi QAの品質向上に向けた取り組みは「品質の見える化」から始めています。 品質向上のための課題抽出や施策提案を、現状に最適な優先度や内容で進めるために、まずは現状を把握する必要性があるから、との考えからです。 また現状把握だけの利用でなく、今後の品質向上PDCAサイクルなど、QAの中長期的な取り組みのベースにすることを想定しています。

「品質の見える化」の実装は、バグなどの不具合発生時に「どんな事象が?」「どこで混入した?」「なぜ混入した?」などの情報を残していく方式で進めました。 この方式は、開発者の協力がないと成り立たないのですが、Classiの開発メンバーは品質意識が高くとても協力してくれるので、スムーズに進めることができました。(改めてこの場で感謝します。)

f:id:classi_qa:20210913141816p:plain

     

「品質データの活用(第一弾)」を始める

「品質の見える化」で見えてきた品質データは、「テスト結果レポート」を作るために活用しています。 「テスト結果レポート」は、テストから得られた情報を基にしてリリースリスクを把握できるため、「リリース品質の向上」に繋げることが期待できます。   

  • 【リリースリスクを把握するための、テスト結果レポートの項目(例)】
    • テストの進捗状況
    • 不具合の発生・収束状況
    • 不具合の内訳(バグ?デグレード?仕様?など)
    • 不具合の対応状況・残存状況など
    • リリース見解(総合的なリスク判断)

f:id:classi_qa:20210913141902p:plain

     

「開発とテストの専業化」をトライアル

「開発作業と検証作業を専業化するかどうか」は意見の別れる事案ですが、Classi開発では「専業化」をトライアルでスタートしています。 開発スピードが企業戦略的にも重要な要素になっている現在では、専任メンバーがテストを専業することで得られる「開発メンバーの負担軽減」は大きなメリットです。

一方で、専業化によるデメリットとして「開発者のテスト意識やテストスキルが低下する懸念」などがあり、今後はメリットとデメリットのバランスを観察しながら、随時ブラッシュアップしていく予定です。

f:id:classi_qa:20210913141956p:plain

     

「QA効果の最大化」を始める

「上流でのバグ検出」を目的として導入されることが多い「QAの上流参加(仕様レビューなど)」ですが、Classi QAでも始めています。 「上流でのバグ検出」を目的とする理由は、「品質のV字モデル」で提唱されるように開発後期(下流工程)で検出したバグは手戻りが多いため、できるだけ開発前期(上流工程)で検出したいとの考えからです。

f:id:classi_qa:20210913142009p:plain

     

「テストの自動化」を始める

開発スピードがUPしたりリリース頻度が高まることで懸念されるのがデグレード発生リスクですが、その対策として利用されているのがテストの自動化で、Classi QAでも導入を開始しています。 かなり以前(10年以上前)からある自動化施策ですが、ここ数年は特に盛り上がりを感じており、多くの開発現場でデグレードに苦労していることが分かります。

f:id:classi_qa:20210913142028p:plain

     

「品質データの活用(第二弾)」を始める

品質データの活用(第一弾)では『リリース品質の向上』に活用しましたが、(第二弾)では課題や改善のヒントなどの見えた情報を開発工程にフィードバックして、『開発品質の向上』に活用します。

この(第二弾)は非常に難しい施策で、本施策の実現に必須となるPDCAサイクルを「継続運用できている」という事例を私はあまり聞いたことがありませんが、Classi QAでは挑戦を始めています。

本施策については、当開発者ブログの別記事【QAチームが取り組む「品質の見える化」への挑戦】に投稿を予定していますので、併せてお読みいただけると嬉しいです。

f:id:classi_qa:20210913142048p:plain tech.classi.jp    

おわりに

Classi QAチームの品質向上施策をフェーズ分けすると、現在は後期に入ったあたりです。

f:id:classi_qa:20210913142109p:plain

     

ただ、後期フェーズに入ったとはいえ、やることが少なくなったわけではありません。

今後更にスピードアップが求められるソフトウェア開発や、日々進化する開発技術に対応するために、新しい施策の提案や実施済みの施策のブラッシュアップなど、タスクは尽きません。

今後もClassi QAチームの品質向上への道は続きます。

© 2020 Classi Corp.