🌊

ソフトウェアの品質向上のためにやること・意識すべきことを書いてみる

2023/05/28に公開

品質は、多用な捉え方がある

ソフトウェア品質 - Wikipedia
ISO/IEC 9126 - Wikipedia
ソフトウェア品質とは - SHIFT ASIA -ソフトウェア品質保証のプロフェッショナル-

ソフトウェアの品質について、ちょっと調べただけでも各ページ、挙げている品質特性が違うことが分かる。
品質についてどういう態度で挑むのかは、案件の内容により、柔軟に考えていく必要があると思う。

タスク

テストを意識して、タスク洗い出し・タスク分解・設計する

V字モデルは、ウォーターフォールと関連して語られることが多いです。しかし、アジャイルだからといって設計をしないわけではないので、この考え方がアジャイルでも全く通用しないわけではないです。
アジャイル開発は、いきあたりばったりの「あ、じゃ、要る」開発とは違います。

要件定義・設計とテストの対応関係を意識すれば、テストの適切な範囲がわかります。

テスト実施する機能の範囲を考えることで、タスク洗い出しを行う。
タスク分解は、実装をする際の取っ掛かりができるぐらいには分解を行う。
テストを書くとしたら、どのようなテストを書くか?を意識して、設計を行う。テストを書くということは、網羅性を意識しないといけない。これにより、設計の考慮漏れを防ぐことができる。

似たようなことを言っている記事を見つけましたので、貼っておきます。
テストをイメージできない設計は、必ず品質が低下する|Takashi Suda / かんた

タスク洗い出し・タスク分解・設計を意識して、テストする

今度は逆に、タスク分解・設計で関わった箇所をテスト対象とすることで、テスト漏れがある程度防げる。
これにより、タスクとしては「作業なし」で終わったものでも、テスト対象となる場合もあり、そういったタイプのデグレも防ぐことができる。

属人化させない

属人的になってしまっていると、他人の作業による影響に気づけず、改修によって思わぬところでデグレが発生してしまうことになりかねないため。
また、タスクとしては存在するが、調査作業のみで「影響なしにより改修無し」で終了するタスクも中にはあると思う。が、そういった成果物が無いようなタスクは、開発の運用上レビューがされないでタスクが終了してしまい、チームメンバーに認知されないケースもあると思う。
レビューは、属人化を防ぐためにもあるので、そういったケースでも、チームメンバーへ認知してもらう仕組みがあったほうが良い。

実装

メンバーがついていける言語やフレームワーク・ライブラリを選定する。またはついていく。

使いこなせない場合、作業上のボトルネックが常に技術的な問題になってしまい、動くという最低限の状態へもっていくまでに苦労を必要とする。こうなると、他の問題に向き合う機会が無くなる可能性があり、全体的な品質も低下する場合がある。
メンバー全員が使いこなせる状態にある必要は無いものの、困った際に聞ける人が居る状態が好ましいと思います。

ぼくの場合、暇さえあれば、Javaの標準ライブラリのJavadocには、目を通すようにしていましたので、パフォーマンス上の問題に立ち向かう際に、適切な標準ライブラリを使うことができたり、ライブラリの中身でなにか問題があって且つエラーメッセージが不親切な場合でも対処ができました。
自分が作ったわけでもないフレームワークやライブラリの中をデバッグしないと問題の原因が分からないようなものを扱う際は、そういった技術力が求められることを意識しておく必要がある。そういった技術力がないのであれば、エラーメッセージを見れば分かるようなもの、またはエラーメッセージをググれば何かしら対処法が見つかるような使っている人が多いフレームワーク・ライブラリを使うのが良いと思う。

きれいなコード・きれいな設計とはなに?という疑問

ソフトウェアの品質を向上させるために、「きれいなコード」にするのであって、きれいなコードのためにソフトウェアの品質を犠牲にするのは間違っている。むしろ、もし、汚いコードになったとしても、トレードオフを考慮した結果ソフトウェアの品質を向上できると判断できるのであれば、そういったコードを選択することを好みます。
というか、「きれいなコード/汚いコード」ってなんだ?良いコード/悪いコードで学ぶ設計がどうのこうのって本が、最近流行ってるらしいが…まあいいや。

ネットかどこかで見たり聞いたりした知識や過去の経験だけを使って物事を考えるのは、今向かうべき問題に対して適切なアプローチを行っていない可能性がある。
ある設計のパターン自体が「良い」とされる設計だったとしても、それが適用できる具体的なものがイメージする能力がない、今の問題に対しても解決できるかどうかについて判断ができないのであれば、もうちょっと考え直したほうが良いと思う(そして、今、技術的中二病というワードが浮かんだ…)。実際に発生するメリットとデメリット、何も又はほぼデメリットがないかを判断できればなおよし。
こういった判断軸が無いまま設計やコードについて語り合っても、平行線になるだけだと思う。実装に限らず、具体的なものをイメージできない抽象概念や抽象概念と合致していない(具体的な)実態は、疑ったほうが良い。

お茶を濁さず、複雑度合い・バグりやすさが分かるコードにする

例えば、複雑な仕様が短く書かれていて、その時はそれで良かったけど、あるとき、仕様が拡張されて拡張性を意識したコードになるとコードの量は多くなる(ちなみに、それを、「シンプルでは無くなった」と言うのはナンセンスだと思う)。コード量が多くなるのを防いだりするなどして、複雑度を隠すような(お茶を濁すような)実装をする必要はない。
拡張性を意識したコードになると、どの程度複雑なのか、バグるとしたらどこかがイメージしやすいと思う。

ログをちゃんと出してバグ早期発見

  • 分岐で想定外と思われるデータパターンが来た場合、WARNログを出すことを検討する
  • WARN的なものをERRORにして、ERRORログまみれにしない

参考:ログ設計指針 - Qiita

テスト

テストの穴を見つける

テストを作ったら、作業の過程で仕込みうるバグのなかで、テストを貫通させることのできるバグを考えてみる。
クラックするかのような姿勢で、テストのレビューをする。
たまに単体テストをやらない代わりに、結合テストをやるといった考え方をする人というのが、まれによく居るが、観点が違うので、単体テストを結合テストで代替することは間違っている。
テストとは、とてもエンジニア的な作業だと思う。単体テストは、実装を見て、ホワイトボックス的にテストするのにとても役に立つ。こういったことはとてもエンジニアリング的である。

複数の観点のテストを複合させる

一人が、あるたった一つの工程において見落として、バグがそのままリリースされる…ということはあまり良くなく、考えうる限り且つ限られた時間の中で、いろいろな観点でのテストを複合してテストを作成して、バグを潰すと良いと思う。

複雑なロジックを持つテストコードを書かない

テストそのものにバグを作り込まないため。テストのテストを書かないといけない状況は避けたいため。
どうしても、もし、複雑なロジックを持つテストコードを書かないといけないのであれば、少し観点を変えたテストも複合させて、保険を作っておく。
まずは、DRYを捨てる方向性で書いてみる。が、テストコードのメンテナンスコストも上がるので、トレードオフは考える必要はある。

レビュー

レビューしすぎない、レビューの方向性を間違わない

コードは、たった1文字間違うだけで不具合が発生するので、レビューによる品質向上はある程度必要なものの、品質向上につながらないレビューをたくさん行って、レビューを作業上のボトルネックにする必要はないと思う。その意味でレビューしすぎない。
ぼくの場合、「個人の好みだろ」「細かすぎるだろ」「それでなんの品質が上がるの?」と思っても、受け入れたほうがめんどくさくないと思い、指摘通りに直してしまうクセがあるので、直したいところ。

ところで、いい記事を見つけました。

レビューしてるのに品質が低い理由|Takashi Suda / かんた

個人のエゴを持ち込む人はレビュアーに向かない

とのタイトルで、「あらかじめチェックリストを作る」との解決法が紹介されています。
「このチェックリストを作成する過程で、有識者の観点を取り込む」ことが真髄のようです。
このチェックリスト作成のタイミングで、「それってあなたのエゴですよね」的なものを客観的な視点で見直し、レビュー指摘内容のブラッシュアップができるといいですね(これからがんばります)。

人材

SI出身者は、貴重な存在

SIで働いてた人は、品質に対する意識や仕事の進め方についての意識が高い人が多いと思うので(たぶん)、そのあたりは、いきあたりばったりでなんとかなってた又はなんともなってなかった系エンジニアより強い。もちろん、小さな改修であれば、計画も何もなしにいきなり作業に取り掛かったほうが速いので、そのさじ加減の調節をする必要はあります。
品質を上げるための引き出しが、SI出身の人にはフルセットである。そのため、改修の規模が少しでも大きくなったら、多数の人が、うまくやれないところをうまくこなせる。例えば、以下のようなことを防げる。タスク分解ができなくて困る、後から機能が足りていことに気づく、計画通りにいかず又は無計画にやることで、スケジュール通りにいかないことで、心理的に焦ってしまい判断を誤るといったこと。

とはいいつつも、優先順位を決めて、やらないことを決める。細かくリリースして、次のアクションへのフィードバックを得るといったアジャイルとしての活動には慣れていない人が多いため、そのあたりは慣れる必要はあるものの、慣れて、さじ加減を調節できるようになれば、SI出身者は、貴重且つ有能な存在になると思う。

関連する良い体験談もありましたので貼っておきます。

「SIでの開発経験は事業会社で通用しない」は勘違い~元SE4名の実体験に学ぶ、働き方をフィットさせる方法 - エンジニアtype | 転職type

実装が得意な人も貴重な存在

たった1文字を間違えただけで、不具合が発生するので、実装が得意な人がいいに越したことはないと思う。しかし、それ以上の理由も考えられる。
ぼくが新人だったころ、上司から「下流工程での痛みを知らないと上流工程は務まらない」といった話をされた。アジャイルだろうと同じようなことは起きているようだ。細かいところを想像できていないのに、薄っぺらい妄想だけで設計すると、後から不都合があることに気づいて、手戻りが発生してしまう。実装が得意であれば、どの程度実装への影響が及ぶかを意識して設計できる。

地道な人も貴重な存在

細かな違いで、不具合が起きたり起きなかったりするので、そういった細かな違いを集中力を切らさずに見逃さない人というのは貴重だし、尊敬します。ただし、全体の最適化を考えずに間違った方向に「事細か」な人もときどきいるので注意が必要です。

GitHubで編集を提案
InnoScouter(イノスカウター)Tech Blog

Discussion