ソフトウェアテストスキルは新人エンジニアが即戦力になるための最短の方法で最長の技術である

　ソフトウェアテストアドベントカレンダーの10日目です。
　本記事では、未経験からRailsエンジニアになり、入社３ヶ月で決済や請求書発行などお金に関係する実装を任された経験を元に、新人エンジニアに送る即戦力になるための最短の方法としてソフトウェアテストのスキルの重要性について記述します。
　ソフトウェアエンジニアに必要なスキルとは何でしょうか。私は、主に３つを考えています。

 1. 技術力
 2. 業務の理解力
 3. トラブル時の対応力

　1.の技術力とは使っている技術に対してどこまで深い理解があるか、保守性の高い実装ができるか、高負荷にならないような実装は何かなど、技術に関するスキルです。これは経験がものをいう分野でもあるので、ベテランエンジニアと比較して、新人エンジニアが一番劣っている部分だと思います。

　今回のテーマであるソフトウェアテストに関するスキルは、2の「業務の理解力」の全ておよび、3の「トラブル時の対応力」の一部に関わってくると思っています。ソフトウェアテストをするためには業務の理解が必要不可欠ですし、業務を理解していればトラブル時の対応もスムーズにできます。

　そこで、本記事では業務の理解の仕方から、実際にエンジニアが自分の実装を自動テストで担保するまでの概観を記述したいと思います。

## 業務を理解しょう

　すでにあるシステムの業務を理解するためには、大まかには以下の手順を踏めば良いでしょう。

1. 仕様書を熟読する
2. コードリーディングをした上で実際に動かして見て挙動を把握する
3. 不明点や違和感がある場合は、業務がわかる人（エンジニアだけでなく、営業やCS、ディレクターなど）に聞く

　まず、仕様書の熟読ですが、SIerなどの従来型のシステム開発などで仕様書が整備されている場合は、要件定義書、外部設計書、内部設計書などが存在すると思いますので、それを熟読します。基本的には上流の工程から読んでいけばいいと思います。概要を掴んで全体像を理解した上で細かなところを理解することで自分のタスクの意義が明確になり、設計書の不備を指摘しやすくなります。

　Web系のスタートアップですと、仕様書が存在しない場合もあるでしょう。そういう場合でもサービスの概要を記載したスライド程度はあると思いますので、それを読んでサービスを理解することから始めます。検証環境（ステージング）などがあって、自由に操作できる場合は、実際に自分で触ってみるのがいいと思います。ありとあらゆるボタンをクリックし、フォームがある場合は入力し、条件分岐がある場合は試していきます。チーム参画当初は比較的時間に余裕があると思いますので、早い段階でサービスの全容を把握することが重要です。

　特に新人エンジニアの場合、技術力がないことに焦りを感じている人も多く、技術力（主に知識）の習得に時間を使いがちですが、その組織で早い段階でValuableな人材となるためには、技術力よりも仕様の把握力の方が重要度は高いです。仕様を把握できている人ほど、仕事が任されやすく、仕事が任されれば実装して行く中で技術力は自ずと向上するからです。

　仕様の把握ができたら次に行うのが次にコードリーディングです。コードリーディングでは、仕様書や触って見るだけでは読み解けなかった条件分岐や、一見して不思議に思う仕様などを発見することができます。例えば、ある商品の申し込み機能があるのであれば、実際に申し込みを行うところから、オペレータが申し込みの処理をして、商品が発送され消し込みが行われるまでの一連の業務がソースコード上でどう実装されているかを追ってみましょう。その中には、Web上だけでは完結しない、バッチ処理もあるでしょう。データベースは同じでも違うアプリケーションになっているかもしれません。そういうのを一つ一つ追っていき、一つ一つの分岐をチェックしていきます。

　私の経験上、コードリーディングがきちんとできる新人エンジニアは非常に少ないです。これは、会社に入るまで、すでにあるシステムをメンテナンスしてきた経験がないからだと思います。学校では主に新規にアプリケーションを作ることを学ぶことが多く、既存のアプリケーションへの対峙の仕方などは学ばないのでしょう。しかし、現場では、既存のシステムを修正することも多いです。
「プログラマはコードを書く時間よりも、読む時間の方が長い」とは言い尽くされた言葉です。自分が書いたコードじゃないから分からないとは決して言わないようにしましょう。優秀なエンジニアは他人が書いたコードを読み、理解することができます。

　こうして仕様書を読んだり、実際に動かしてみたり、コードを読んだりして一人でできうるありとあらゆる手段を使って仕様を把握していきます。それでも仕様が不明なところや、違和感を感じるということは良くあります。そういう時は業務がわかる人に聞くしかありません。そのためには、その業務に長く携わっているエンジニアやディレクター、営業、CS、経理などそのシステムを利用している人が誰かを把握しておくことが必要です。

## テスト設計をしよう
　さて、このようにして業務を理解したら次はテスト設計です。本記事では、詳細なテスト設計技法について述べることはしません。本格的にテストを学びたい人は、ソフトウェアテストに関する専門書を読んでください。ここでは、簡単に概略だけ紹介します。

　私はテスト設計に重要なのはいかにケースを網羅できるかということに尽きると思っています。　私は電力関係のシステムを作った経験がありますが、電気の申込みフォームのWebシステムをイメージしてみましょう。

　電力にはエリアという概念があり、北海道から沖縄まで１０個のエリアがあります。エリアという視点では１０個のケースがあるということになります。さらに、各エリアには低圧ですと、従量電灯A、従量電灯B、従量電灯C、低圧電力（動力）、低圧高負荷などのプランがあり、プランという視点では５つになります[^1]。まずは、こうしたケースを抜け漏れなく列挙できるかというのがファーストステップだと思います。

[^1]: 電力に詳しい人からはツッコミを受けるかもしれません。

　勘のいい方はお気づきだと思いますが、ケースを考えだすとキリがありません。契約アンペアであれば10アンペアから60アンペアまでありますし、今契約している電気の切り替えなのか、引越し先の申込み[^2]なのかなど考えるべきことはいくつもあります。エリアとプランを考慮しただけでも掛け算して50個のパターンが考えられるわけです。

[^2]: 電力業界では再点と呼びます。

　ソフトウェアテストの世界では、ここでいう電力エリアやプラン（項目）を因子、北海道電力エリア・東北電力エリア・・・や従量電灯A、従量電灯B・・・（値）を水準と言ったりします。ここで全ての因子の全ての水準に対してテストをすることは現実的ではありません。因子が増えれば増えるほど、水準が増えれば増えるほど、テストケースの数は指数関数的に増大していきます。そこで、ソフトウェアテストの世界では、ペアワイズ法や直交表などを利用してテストケースの数を減らしていきます。そのためのツールも存在します[^3]。ペアワイズ法に関する詳細は「[テストの数を減らそう！プリキュアで学ぶPICT](https://qiita.com/greymd/items/ad18aa44d4159067a627)」が詳しいですのでそちらをお読みください。

[^3]: MicrosoftのPICTなど。

　ソフトウェアテストについての全体像を学びたい方は、「[知識ゼロから学ぶソフトウェアテスト【改訂版】](https://www.shoeisha.co.jp/book/detail/9784798130606)」もおすすめです。また、ソフトウェアテストアドベントカレンダーの[17日目](http://nihonbuson.hatenadiary.jp/entry/2018/12/17/234153)で紹介されていた[JSTQB TA テスト技法の紹介](https://www.slideshare.net/kauji0522/wacate2018-winter-jstqbalta)のスライドも大変勉強になります。

　私は、開発者の観点からのテスト設計はひとまずはテストケースの洗い出しまででいいと思っています。結果の期待値まではこの段階では考える必要はないでしょう。なぜなら、開発者であれば自動テスト（JUnit、RSpec、unittestなど）を必ず書くことになります。期待値はテストを書きながら考えても遅くはないでしょう。もし自分が洗い出したテストケースに自信がない場合は、本当に十分かどうかをこのタイミングで先輩エンジニアにレビューしてもらうと良いでしょう。

## 自動テストを書こう
　このようにしてテスト設計（テストケースの洗い出し）ができたら、あとは、自動テストを書くだけです。私は普段Railsを使っているので、RSpecを書きますが、現場のフレームワークに合わせたテスティングフレームワークを利用すればいいと思います。

　一部のエンジニアにとってテストを書くことに対して億劫に感じるかもしれません。テストはエンジニアたる自分がやるべきことではないと思う人もいるようです。しかし、エンジニアとはいえ人間ですから、実装に間違いはあるものです。社会人になる前、学校のテストで満点しかとったことない人は皆無でしょう。答えが明確にわかっている学校のテストですら間違うのですから、より複雑怪奇な業務の焼き写しであるシステムを実装して間違わないわけはありません。自動テストは言ってみれば学校のテストの見直しにあたります。見直しをするとケアレスミスに気付けたり、時間をおいて改めて考えることで最初に解いた時には気づかなかったことに気づくことができます。自動テストも同じです。自動テストをするためには、時には事前にデータを用意しないといけないことがあります。データを用意する過程で、想定していなかったデータが入ってくることもあるでしょう。テストケースをきちんと書き出しておくことで、実装時に気付けなかった実装漏れも気付けるかもしれません。

　そして、もっと大事なのは、自動テストを書いておくことで、後から見た人がそのコードがどのような挙動を想定しているのかをより理解しやすくなります。私は、エンジニアにとって大切なことの一つは思いやりだと思っていますが、自動テストを書くことは思いやりの一つだと思います。

## ソフトウェアテストスキルはいつの時代も必要とされる技術
　最後に、ソフトウェアテストのスキルというのはいつの時代も色褪せないスキルだということです。この世にシステムがある以上、テストをせずに世に出すことはありません。程度の差こそあれ、必ずテストをしてからリリースされるでしょう。つまり、ソフトウェアテストのスキルはいつの時代も必要とされると言うことです。

　エンジニアをしていると、どんどん新しい技術が出てきて、あれも学ばなければ行けない、これも学ばなければいけないと言う強迫観念に襲われる時があります。新しい技術は面白いので学んでいくのは良いことだと思いますが、同時に、息の長い技術を学ぶことでエンジニアとしての土台ができると思います。今回のメインテーマであるソフトウェアテストもそうですし、例えばリレーショナルデータベースもそうでしょう。

　エンジニアとしては、テストを書くことを嫌がらずに書き続けることで堅牢なシステムをつくれますし、その結果、周りからの信頼も得ることができます。これは、新人エンジニアでも今すぐに始められることです。そして驚くべきことに、ベテランのエンジニアであってもソフトウェアテストに関する理解がないという方もいます。そういうエンジニアと同じチームになれば、ソフトウェアテストは新人エンジニアがリードしていける分野となりえます。

## 最後に
　　本記事では、会社に新人エンジニアが入ってきた時に伝えたことを改めて文字に起こして見ました。テストに関しては私も勉強中の日々です。バグも生み出してしまいます。エンジニアとして仕事をしていると失敗ばかりの方が多く感じます。何事もなく動くのが当たり前という世界だからです。私の地元出身の野球選手（投手）に金田正一さんという方がいます。金田さんは通算で400勝していますが、同時に298敗もしています。43%も失敗しているのです。バグを生み出してしまったときには毎回これを思い出し、自分が今まで開発してきたシステムも、時折不具合は見つかるけど、きちんと稼働して、お金を生み出している。十分に勝ち越してると思って日々精進していこうと思います。

　この記事を書き終えてから、前日の担当の @hiroyuki3gou さんが[システムを把握する3つのコツ](http://devtest.hatenablog.com/entry/2018/12/09/225456)というタイトルで業務理解について記事を書かれていました。テストを行うにあたっての業務理解の重要だということの現れなのではないかと思います。