【プログラミング入門】javaでWEBアプリケーションを作ってみよう!【はじめに】
これまで、主に環境構築とプログラミングを行ってきました。
これで実際に物ができたわけですが、本来の仕事の流れだとこの後自分が作成したものがちゃんと動くかどうかテストする必要があります。
システムの品質をあげるためにはテスト工程が必要不可欠で、この工程を省略してしまうと実際に顧客にシステムを納品した後に不具合だらけでシステムが動かないなどたくさん問題が発生していまいます。
それによりどうなるかといいますと請負契約ですと瑕疵責任というものがありまして、納品物が要求したとおりちゃんと動いてないと無償で修正しないといけなくなります。
それだけでなく、一度顧客からの信頼を失うとそれ以降仕事の依頼が来なくなります。
信頼を築くのは時間がかかりますが、失うの一瞬です。
それほどシステムの品質は重要になります。
今回は、java開発でのよくあるテスト手法について学んでいきたいと思います。
では、はじめていきます。
自動テストを理解しよう
今回は自動テストについて学んでいきます。
システム開発をするにあたって、必ずと言っていいほどこの手法の話がでてきます。
まず、自動テストは何かといったところから書いていきます。
自動テストとは
言葉の通り自動でテストを行う環境を作ることです。
具体的にどういったことをするかといいますと、自分が作成したプログラムを動かすプログラムを作成します。
このテストを行うためのプログラムをテストコードと呼びます。
一度、テストコードを作成すれば、今後作成したテストコードを実行するだけで、何度も同じテストが実施できます。
もし、自動テストがない場合は、画面などから自分の手で入力して、自分の目で結果を確認して問題ないか判断する必要があります。
一回確認すればいいし、なんかややこしいテストコード作成しなくても手動でちゃちゃっとやればいいのでは?と思われる方もおられるかもしれませんが、一度作成してからそれ以降そのプログラムを二度と修正しないのであればそれでいいかもしれません。
しかし、テストしていく中で不具合を見つけて修正したり、顧客からの要望で仕様の変更が入ったりと修正する機会がたくさん発生します。
その場合、もう一度そのプログラムをテストしなおす必要があります。
その時に自動テストのテストコードをあらかじめ作成しておけばすぐにテストを実施できるというわけです。
ただし、自動テストも良いことばかりではないのでメリットデメリットを書いていきます。
自動テストのメリット
・一度テストコードを作成すれば、何回でもテストの実施が容易にできる
・修正箇所以外のところも問題ないかデグレードの確認が容易
・カバレッジの取得もできるので自身のプログラムがすべて処理されたか確認ができる
自動テストのデメリット
・テストコードを作成する必要があるため、テスト実施までに時間がかかる
・すべての分岐を網羅させておく必要があり、適当に作成すると価値が激減する
上記記載の通り、それなりに時間がかかります。あと、適当に作成すると自動テストの意味があまりないです。
不完全なテストを何回しても、品質はあがりません。
ただ、プロジェクトによっては納期までの期間がない場合があり、時間の関係上自動テストをしない場合もあります。
自動テストを実施してみよう
では、実際に自動テストを行ってみたいと思います。
今回は、javaの自動テストライブラリとして有名なJUnitを使用していきます。
テスト対象は、以下の記事で作成したプログラムで行います。
【プログラミング入門】javaでWEBアプリケーションを作ってみよう!【プログラミング編】
上記、記事通り行っていれば、以下のファイル構成になっているかと思います。
まず、このTest.javaのファイル名を変更します。
※Test.javaのままでもいいですが、これからテストコードを作成する上で名前がややこしくなるので変更します。はじめから意識しておけばよかったです。もうしわけありません。
Test.javaを右クリックして、「リファクタリング」→「名前変更」とクリックしてください。
すると名前変更ダイアログが開くかと思いますので、名前を「Test」から「Sample」に変更してください。
変更したら「Sample.java」に変わったかと思います。
実際のソースの中身が以下のようにクラスの名前も変わっていることを確認してください。
テストコードの作成
では、テストコードを作成していきます。
まず、テストコードのjavaファイルの作成を行います。
以下のように「src/test/java」にapiパッケージを作成してjavaファイルを作成してください。
今回は「SampleTest.java」というファイル名で作成しました。
SampleTest.javaを以下のように実装してください。
package com.example.demo.api; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class SampleTest { @Autowired Sample sample; @Test public void test_01() { String result = sample.get(); Assert.assertEquals("{\"test\": \"APIの練習です\"}", result); } }
上記を作成した後、赤線でコードのエラーが発生するかと思います。
その場合、以下のようにビルドパスを追加してください。
簡単に実装内容を説明していきます。
まず、「@RunWith(SpringRunner.class)」と「@SpringBootTest」はSpringのフレームワークを使って動かしますよっていう宣言です。
「Sample sample;」はテスト対象のDIです。テスト対象を動かすための事前準備と思って頂ければと思います。
「@Test」は実際にテストを実行するメソッドの宣言です。今は一つしかありませんが、@Testを付けたメソッドが上から順に実行されていくイメージです。
「String result = sample.get();」で作成したプログラムを実行しています。結果をresultの変数に格納しています。
最後に「Assert.assertEquals(“{\”test\”: \”APIの練習です\”}”, result);」で結果が正しいかの検証を行っています。
今回は実行した結果が「{“test”: “APIの練習です”}」の文字列と同じであればOKという確認です。
第一引数が期待する値、第二引数が実際の値をいれます。
assertEqualsメソッドが引数同士が同じであればOKとするメソッドです。
ほかにも等しくなければOKとする「assertNotEquals」や結果がnullならOKとする「assertNull」などがあります。
状況によって使い分けましょう。
テストコードの実行
では、さっそく作成したテストコードを実行してみましょう。
以下のように作成したテストコードを右クリックして、「JUnitテスト」をクリックしましょう。
※もし、JUnit5のテストが見つかりませんというメッセージが出た場合は、「実行の構成」をクリックして、テストランナーを「JUnit4」に変更して実行しましょう。
実行すると以下の表示が出てくるかと思います。
緑色で表示されている場合はテストがOKだったということになります。
試しにわざと失敗させてみましょう。
テストコードのassertEqualsの文字列を変えてみて実行してみます。
すると緑色から赤色になったかと思います。この状態はテストNGを指します。
下部のウィンドウになぜNGだったか詳細がでます。
最後に
今回は簡単な自動テストを行いました。
他にも以下のようなことができたりします。
・処理実行後のDBのデータと想定結果のデータをCSVなどで比較ができる
・Mockという機能があり、一部のメソッドを一時的に置き換えることができる
csvファイルなどを用意しておけば、テストコード実行時にデータベースにデータを入れる処理とかもできたりします。
データベースに接続する処理によく使用しますので、頭の片隅にこういったこともできるということを置いておいて頂けたらと思います。
後、自動テストするときに必ずといっていいほど登場するMockと呼ばれるものがあります。
これは対象のあるメソッドを置き換えるといった処理です。
一見、意味が分からないかもしれませんが、単体テストする際は対象のソース単体のテストを行います。
もし、そのソースが他のプログラムを呼び出す処理を書いてあったとしましょう。
その呼び出すプログラムを一時的に置き換えることができます。
利点は、その呼び出すプログラムが不具合で動作していなくても影響がないというところです。
単体テストの目的はテスト対象コードが正しく動作しているかどうかなので、基本的に呼び出し先のことは意識しません。
しかし、置き換えずにそのまま使用してテストをした場合、呼び出し先が動いていないと本来テストしたいことができなくなります。
他にも例外エラーを発生させたい場合にも使用したりします。基本的に発生しないエラーですが、もし発生した場合でもテスト対象のプログラムが問題なく対処しているかの確認をする必要があります。
といったように自動テストにもいろいろ手法があり、覚えることもたくさんあります。
機会があれば、もう少し深い内容にも触れていけたらと思います。
コメント