Embed Tomcat＋JUnit＋Selenium＋DBUnit + Antで自動テストする。


# 自動テスト
自動テストしてますか？
アプリケーションは運用されて行くと共に使う人に合わせて形を変え、洗練させていかなければなりません。

ソフトウェアは常にメンテナンスしていかないと劣化していきます。
技術革新やデザインの流行が変わっていく中で、アプリをほっておくと、どんどん過去のモノになっていきます。
また、それは、環境、スマートフォンアプリであれば、OSやデバイスのバージョンアップ、
Webアプリであれば、ブラウザのバージョンアップなどで、アプリが動かなくなってしまうこともあります。

ただし、機能が増えていけば増えていくほど、メンテナンスは難しくなります。
それはアプリケーションの見通しが悪くなり、全体を見るのに時間がかかるようになるからです。
そうなると、全体を見るためにITのを使うことがよいです。その使い方の一つが自動テストです。

ここでは、JavaのWebアプリケーションを自動テストする方法をご紹介します。
Java以外でも、アーキテクチャは代わりません。各対応するプロダクトに読み替えてご参考ください。

# Embed Tomcat＋JUnit＋Selenium＋DBUnit + Antで自動テストする。
Embed Tomcat、JUnit、Selenium、DBUnit、Antをご存知でしょうか？
* [Embed Tomcat](https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/startup/Tomcat.html) Tomcat7から実装された、Javaアプリケーションから起動できるTomcatです。
* [Selenium](http://docs.seleniumhq.org/) Webブラウザを操作することができるライブラリです。
* [DBUnit](http://dbunit.sourceforge.net/) データベースの内容をテスト用に設定することのできるライブラリです。
* [Ant](http://ant.apache.org/) プロセス実行のためのツールです。今回はビルド、テスト実行のために利用します。
今回はこれらのプロダクトを使って、Webアプリケーションをテストします。

## セットアップ
Java、Antは適切にセットアップしてください。AntはEclipseに内蔵されているものでも大丈夫です。
https://github.com/ukiuni/OpenReport/tree/master/test/libs にあるライブラリにパスを通してください。各プロダクトのサイトからもダウンロードできます。

## サンプル
### Tomcatの起動
Tomcatの起動は数行でできます。

```java:Embed&nbsp;Tomcatの起動ソース（抜粋）
Tomcat tomcat = new Tomcat();
tomcat.setPort(PORT);
tomcat.setBaseDir("./test/server");
context = tomcat.addWebapp("/" + APPLICATION_NAME, new File("./WebContent").getAbsolutePath());

tomcat.start();
server = tomcat.getServer();
```


tomcat.setBaseDirで、Tomcatの実行ディレクトリを指定しています。
tomcat.addWebappで、Webアプリケーションのルートディレクトリを指定しています。

tomcat.start();で、Tomcatが起動します。


JUnitの実行前に起動するようにするとよいでしょう。
ソースの全体は[こちら](https://github.com/ukiuni/OpenReport/blob/master/test/src/integration/test/org/ukiuni/report/IntegrationTest.java)です。

### Seleniumでのブラウザ操作
ブラウザでURLを起動し、ブラウザ上に表示されるElementにデータ入出力をすることができます。


```java:Seleniumでのブラウザ操作ソース（抜粋）
WebDriver driver = new FirefoxDriver();
driver.get(“http://localhost/testtarget");
String name = "myCreateAccountName";
String password = "myCreateAccountPassword";
String mail = "myCreateAccount@example.com";
WebElement loginForm = driver.findElement(By.name("accountCreateForm"));
WebElement nameForm = loginForm.findElement(By.name("name"));
WebElement passwordForm = loginForm.findElement(By.name("password"));
WebElement mailForm = loginForm.findElement(By.name("mail"));
WebElement loginButton = loginForm.findElement(By.className("btn"));
nameForm.sendKeys(name);
passwordForm.sendKeys(password);
mailForm.sendKeys(mail);
loginButton.click();
```

ソースの全体は[こちら](https://github.com/ukiuni/OpenReport/blob/master/test/src/integration/test/org/ukiuni/report/IntegrationTest.java)です。

### DBUnitでのテスト用データのセットアップ
DBUnitを使って、テスト用のデータをDBに投入します。

```java:DBUnitを使ってのデータ投入
Connection dbConection = DriverManager.getConnection("jdbc:h2:file:./test/db/" + mode + ".db", "test", "test");
IDatabaseConnection connection = getConnection(mode);
DatabaseOperation.CLEAN_INSERT.execute(connection, getDataSet("./test/cause/basicData.xml"));
connection.close();
```

データ本体はXMLで定義します。XMLは[このように]記述できます。

また、DBの中身をXMLにエクスポートすることもできます。


```java:DBUnitを使ってのデータのエクスポート
Connection dbConection = DriverManager.getConnection("jdbc:h2:file:./test/db/" + mode + ".db", "test", "test");
IDatabaseConnection con = new DatabaseConnection(dbConection);
IDataSet dataset = con.createDataSet();
FlatXmlDataSet.write(dataset, new FileOutputStream("./test/cause/export.xml"));
```

エクスポートしたデータを編集して、テスト用のデータを作成することもよいでしょう。
ソースコードの全体は[こちら](https://github.com/ukiuni/OpenReport/blob/master/test/src/test/org/ukiuni/report/tools/DBTestUtil.java)です。


### Antでのテスト実行
JUnitにテストを記載し、Antで実行します。

```xml:Antのテスト起動部（抜粋）
<target depends="buildTest" name="IntegrationTest">
  <mkdir dir="${junit.output.dir}" />
  <junit fork="yes" printsummary="withOutAndErr">
    <formatter type="xml" />
    <test name="integration.test.org.ukiuni.report.AllTests" todir="${junit.output.dir}" />
    <classpath refid="CMS.test.classpath" />
  </junit>
</target>
```

ビルドスクリプトの全体は[こちら](https://github.com/ukiuni/OpenReport/blob/master/build.xml)です。

## 実行
JUnitでIntegrationTest.javaを実行するか、Antコマンドを実行すれば、テストが実施されます。

```shell-session
$ ant IntegrationTest
```

## CIでの自動テスト
コミットイベントをフックして、Antを実行するようにすれば、自動テストが完成です。

# 実際に動くサンプル
本稿では、トピックとして抜粋した要素をお見せしましたが、ここで紹介した技術は[Open Reports](http://openreport.ukiuni.cloudbees.net/)で利用されているものです。
[![openreports_title.png](https://qiita-image-store.s3.amazonaws.com/0/25176/cb997bf5-58af-1b21-f79f-b84c2bcaa1ef.png)](http://qiita.com/ukiuni@github/items/27e54c15081da983dce3)


ソースコードはすべてgithubにて公開していますので、実際に動かして見たい場合は、[こちら](https://github.com/ukiuni/OpenReport/releases)からダウンロードして下さい。