「ベトナムオフショア開発で失敗する事例 〜受託側編〜」でも書かせていただいたように、オフショア開発では品質が大きな課題になります。本記事では、品質を担保するために、弊社ではどのような対策を行っているかをご紹介差し上げます。
様々な定義の品質
まず品質の定義ですが、「要件通りに動くバグの無いソフトウェア」だけでなく、ソースコードの可読性や信頼性、セキュリティやユーザビリティまで考慮して納品致します。
前者のプロダクトそのものの品質に関しては、
- なるべく上流工程で認識のすり合わせをする
- テストケース、テスト報告書の作成
- PHPUnitで単体テストコードを記述
- 出来上がったもののフィードバックをなるべく早期にお客様から頂く
というアプローチで品質向上に努めます。
後者のソースコードの品質に関しては、
- ソースコードの静的解析
- ツールでセキュリティテスト
- コードレビューによる官能評価
というアプローチで品質向上に努めます。
なるべく上流工程で認識のすり合わせをする
あらゆるプロジェクトの開始時や、複雑な要件のすり合わせの際には、必ず日本人エンジニアがブリッジとして入ります。その段階で機能要件、非機能要件を出来る限り明確化し、開発者に展開できる段階になってから、開発チームでの検討段階に入ります。この段階で不明点があればQ&Aリストを作成し、不明点は全て潰しておきます。かなり時間を掛けているように感じられるかもしれませんが、ここで認識相違があると、開発が進んだあとの手戻りが発生し、より大きな時間のムダが発生してしまいます。それを極力防ぐために、上流工程はかなり厚いコミュニケーションを取らせていただきます。
PHPUnitで単体テストコードを記述
開発者が機能を実装し終わったあと、弊社では必ずPHPUnitで単体テストコードを書きます。目的としては下記が挙げられます。
- その機能の実装が本当に正しいかを単体テストレベルで確認すること
- 似たようなテストをプログラムで実行可能にする事による効率化
- ある機能の実装が、別の機能への影響を及ぼしていないかの確認
- テストも開発者の責務であることの意識付け(ベトナムでは、テストはテスターがやるもので開発者がやるものではないと思っているエンジニアが非常に多いです。)
ソースコードマージ時には、実装済みのテストコード全てを実行し、全てが通ることを確認します。
弊社では、入社時に行われる受け入れトレーニングにPHPUnitのチュートリアルを入れており、テストコードを書けないと実際のプロジェクトに参加できません。これは、弊社がPHPに特化しているからこそ実現できるトレーニングプランです。
※単体テストコードを書くことにも工数はかかりますので、予算やスケジュールに応じてテストコード量の調整をすることもございます。
※既存のコードにテストコードがない場合は、追加機能に対してもテストコードを書かない場合がございます。
テストケース、テスト報告書の作成
プロジェクト開始時に合意する、弊社からお出しする成果物にもよりますが、テストケース/レポートは基本的に作成します。単純な成果物として作成するだけではあまり意味がありません。主な用途としては、お客様と弊社ブリッジSE、ブリッジSEと開発者間での仕様に関する認識があっているかのすり合わせを意図として作成します。したがって、テストケースを作成したあとのメンバー間のレビューを最も重要視します。
複雑な機能の開発の場合は、テストケースのレビューをお客様にご依頼差し上げることもございます。
出来上がったもののフィードバックをなるべく早期にお客様から頂く
上流工程で極力お客様側と開発チームの認識のすり合わせをしますが、「本当に」認識があっていたか、期待する動作をするアプリケーションが出来ているかの確認は、実際に目で見るのが一番です。
弊社ではいわゆる検収のかなり前の段階から、できるだけ小さい機能単位で開発し、それをテスト環境やステージング環境へデプロイし、お客様の方で早期に現状の動作を確認できるプロセスを適用しています。これにより、認識相違による手戻りを極力小さく出来ます。また、実際動作確認してみて「やはりこういう仕様にしたい」というケースは得てして出てくるものです。そういった軌道修正も早期に対応出来ますので、初期の要件定義に漏れや間違いがあっても、本当に期待するアプリケーションへ着実に進めることが可能です。
ソースコードの静的解析
オフショアでよくあるリスクとして、動作自体は正しいがとんでもなく汚いソースコード、或いは読めないコメントで納品されるというケースがあります。
弊社でもこのような状況を作らないために、定量的に「きれいなソースコード」を定義し、評価し、修正します。弊社では下記の基準でソースコードを静的解析しています。
コーディング規約
特定の規約に則ってソースコードが書かれているかを確認します。PHPにはグローバルに規定された規約のうちPSR-1とPSR-2に則ったコードにするためにphp-cs-fixerを使用して、ソースコードマージ前に整形します。
重複度計測
弊社ではPHPMDを使用して、重複度と循環複雑度と言うものを計測しています。重複度はいわゆるコピペコードがどれくらいあるかを定量化するものです。弊社では3回以上同様の処理を記載する場合は必ず共通関数化し、コピペコードを書かないようにしています。
循環複雑度計測
循環複雑度は長過ぎるメソッド、深すぎるネストの計測です。この数値が大きすぎるとバグが潜む可能性が高まると言われており、弊社ではこの数値が15を越えるメソッドが存在しないようにコントロールしています。
コードレビューによる官能評価
ソースコードを静的解析しても、読みづらいコード、メンテしづらいコードはまだ残ります。わかりづらい変数名、関数名、クラス名、ハードコーディング、正しいクラスに記載されていない処理などです。これらはソースコードレビューで防止するようにしています。プログラムを書いた本人にとっては良くても、他の開発者には分かりづらかったり、もっと良い書き方がある場合はレビュー時にコメントしてもらい、その点を修正してからマージ、デプロイします。
ツールでセキュリティテスト
最後に、セキュリティをツールを使用してチェックしています。弊社では主にvulsでサーバの脆弱性をスキャンし、VAddyでソフトウェアの脆弱性をスキャンしています。機能開発後に行う単体テストや結合テストでもXSSやSQLインジェクションなどの一般的な脆弱性はテストしますが、ツールを使用するとテストをより網羅的に出来ますし、なにより定点観測できるので、どのレベルのセキュリティテストを通過しているかを評価しやすいです。
PHPに特化したCI環境
ソースコードマージ時に、単体テストコードの全スクリプト、ソースコードの静的解析、コードフィクサー、セキュリティーツールが全て自動で実行されます。どれか一つでもパスできないとサーバでデプロイ出来ない仕組みになっています。
また、ソースコードの静的解析、単体コード作成、コードレビューはどれもプログラミング言語に依存する。PHPに特化しているからこそ、その品質を保つプロセスや社員教育が可能になっています。
※CI環境は、お客様の環境に依存します。完全自動化出来ない場合は、上記に上げたツール類のスクリプトを手動実行することで品質を担保しています。