システム開発やプログラミングにおけるとバグの種類と、バグを防ぐための考え方について

新人エンジニア応援記事の、第二弾です。前回は、DBについて書きました。

テーブル設計やSQLを学びながら、速いデータベースの作り方について考えてみる - このすみろぐ

今回は、システム開発やプログラミングにおける、バグについて語ってみます。

仕様バグ/要件バグ

まず大前提として、バグはプログラミング工程だけで発生するものではありません。矛盾した仕様、無茶苦茶な要件、この時点で既にバグは起こっていると考えた方が良いです。

仕様や要件の不具合は、プログラミングをどんなに頑張ったとしてもカバーするには限界があります。もし、あなたがシステム開発担当だったとしたら、可能な限り仕様や要件策定にも関わるようにしましょう。

また、既に仕様が決まっているシステム開発だったとしても、少しでも不明瞭な事があったら先輩を質問攻めにした方が良いです。

設計バグ

設計バグは、仕様の理解不足や勘違いなどによって発生します。特に、アジャイルをドキュメントを作らないシステム開発と勘違いしているようなプロジェクトでは、起きやすいバグであると言えます。

仕様を勘違いして理解すると、それが勘違いしたまま設計に起こされます。私のおすすめは、いきなりプログラミングに時間をかけるよりも、設計に時間をかけることです。

アジャイルにおけるスクラム開発という手法でも、スプリントプランニング(計画策定)には時間をかけた方が良いとされています。プログラミングでも計画が重要です。

自分が作る機能では、何を実現する必要があるのか、それを先輩と認識合わせした上で設計に入りましょう。尚、ここで言う設計には「どの画面で何をするのかという画面設計」や「どのテーブルに何を保存するのかというデータベース設計」などが含まれます。

出来れば、設計をした段階で、設計レビューをしてもらうと尚良いかもしれません。

f:id:konosumi:20180502135036j:plain

考慮漏れバグ

プログラミングには、大きく分けて正常系と異常系があります。

  • 正常系:ユーザが入力した内容に特にエラーもなく、正常に動作が完了するようなケース
  • 異常系:ユーザが入力した内容が正しくなかった場合や、データベース上にデータが存在しないなど、何らかの不正によってエラーが発生するようなケース

正常系・異常系 - Qiita

ここで重要なのは、異常系のケースです。プログラミングにおいて、正常系のコードは5割くらいで、残りは異常系のためにコードを書いていると言っても過言ではありません。

「自分が開発している機能では、どのような異常系が想定されるのか?」これをどれだけカバーできるのかが重要です。ここで考慮が漏れてしまった異常系において、考慮漏れバグは発生します。

また、プログラミングにおいても、異常系を捕捉しやすい書き方をすることをおすすめします。具体的には、Try-Catchなどです。

<?php
try {
    // ユーザデータを取得する
    $user = User::retrieve($id);
    if (!$user) {
        throw new UserNotFoundException('User not found. id='.$id);
    }
} catch (UserNotFoundException $e) {
    // 見つかるはずのユーザが見つからなかったとログに記録する
    Log::error($e->getMessage());
}

上記はただのイメージですが、異常系を途中で弾きながら本線を進めていき、異常系があれば捕捉してログにエラーを書き込みます。これが基本的な考え方です。

また、プログラミングレベルにおいては、異常系から無理やり正常系に復帰させようなどは、あまり考えない方が良いです。異常を察知したらエラーを記録した上で処理を終了させ、被害を拡大させないのが、原則であると私は考えています。

セキュリティバグ

セキュリティバグは、暗号化されるはずのパスワードが暗号化されていないであったりとか、閉じているはずのポートが開いてしまっているなど、様々な局面で起こりえます。

安全なウェブサイトの作り方:IPA 独立行政法人 情報処理推進機構

IPAが発行している「安全なウェブサイトの作り方」などは、基本ですのでぜひ読みましょう。セキュリティの不具合は、サーバレベルでの不正アクセスなどによって起こると思われがちですが、プログラミングレベルであっても十分に発生します。

セキュリティバグを防ぐためには、まず原則と過去の事例を知ることが重要です。知識がつけば、自ずとどのようなセキュリティテストが必要なのかが分かります。

例えば、入力フォームにSQLを入力してみるであったりとか、テストのバリエーションを増やして工夫してみましょう。

パフォーマンスバグ

パフォーマンスバグは、動作はするけれどもサーバに負荷が掛かるようなプログラムにおいて発生します。

具体的には「時間のかかる無駄の多いSQL」や「再帰的な処理で計算量が無駄に多いプログラム」などを指します。そのため、私の場合はパフォーマンスにおいては、以下のような規準を持っています。

  • 緑:100ms以内でページの読み込みが完了する
  • 黄:ページの読み込みに500msかかる
  • 赤:ページの読み込みに1秒かかる

1秒と聞くと、現実世界では早いと思われがちですが、プログラミングの世界ではかなり遅い部類です。

上記の規準はあくまで私の考えですが、いずれにせよ、パフォーマンスにおいても規準は絶対に持っておいた方が良いです。パフォーマンスは、サーバ負荷のみならずユーザビリティにも影響します。

ちなみに、私が新人エンジニアの頃に開発していた某ECサイトでは、商品ページの読み込みに3秒かかっていたため、それがユーザ体験やSEO対策にも悪影響を与えてました。パフォーマンスは、意外と様々なところに波及するんですよね。。

さいごに

バグの量は、単純にプログラミング能力に依存すると思われがちですが、意外とそう単純な話でもありません。

病気も予防が大事であると言いますが、バグも予防が重要です。プログラミングを始めるまでに、防げそうなバグは予め防いでおくを推奨します。