リリース用モジュールのチェックツールを作ってみた

# 背景

Webシステムをリリースする際、私が携わっているプロジェクトでは以下の操作を行っています。

1. Gitでdevelopブランチの内容を、releaseブランチにマージ
2. releaseブランチにチェックアウト
3. リリース用の設定がなされていることを確認。
4. warファイルを作成

リリース用の設定がなされていることの確認項目は、10~20個です。たとえば、以下のような項目です。

* DB接続先
* FTPやDBなどのパスワード（テスト環境と本番環境はパスワードを変えている。間違って本番環境にアクセスしないようにするため）
* 画面に「テスト環境」という文字が表示されていない

リリースの頻度は3ヶ月に1回なので、確認自体はそこまで負担ではありません。
目視確認では漏れる恐れもあるため、勉強も兼ねてツールを作ってみました。
まあ、ツールが間違っているという可能性もありますが。。。

# ツールの中身

### 構成
JUnitを使って、正しく設定されていることを確認しました。

### propertiesファイル
`java.util.Properties`クラスを使って、propertiesファイルを読み込みます

```java
    /** 読み込むファイルの絶対パス */
    private static String filePath = Constants.PROJECT_PATH + "sources/system.properties";

    /** プロパティファイルオブジェクト */
    private static Properties prop = null;

    @Rule
    public TestName testname = new TestName();

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        prop = new Properties();
        prop.load(new FileInputStream(filePath));
    }

    @Test
    public void FTPサーバの接続続先確認() throws Exception{
        String key = "ftp.host"; //propertiesファイルのキー
        String actual = prop.getProperty(key); //
        String expected = "127.0.0.1"; //期待結果
        String name = relativeFilePath + ": " + key;
        log.info(name + " = " + actual); //ログに値を出力
        assertThat(name, actual, CoreMatchers.is(expected));
    }
      //テストメソッドを確認する数だけ作成する
 
 ```
    
### JSP/HTMLファイル
org.jsoup.Jsoupを使用して、JSP/HTMLファイルを読み込みます。
JSPのカスタムタグがあっても読み込めます。

```jsp:index.jsp
  <div>
    <span id="version">1.2.3</span>
  </div>
```


```java
    /** 読み込むファイルの絶対パス */
    private static String filePath = Constants.PROJECT_PATH + "webapps/index.jsp";

    /** documentオブジェクト */
    private static Document doc = null;

    @Rule
    public TestName testname = new TestName();

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        doc = Jsoup.parse(new File(filePath), "UTF-8");
    }

    @Test
    public void バージョンの確認() throws Exception{
        String key = "#version";
        Element cell = doc.select(key).get(0);
        String actual = cell.text();
        String expected = "1.2.3";
        String name = relativeFilePath + " : " + key;
        log.info(name + " = " + actual);
        assertThat(name, actual, CoreMatchers.is(expected));
    }
```


### XMLファイル
dom4j.jar の`org.dom4j.io.SAXReader`を使って、XMLファイルを読み込みます。

以下の処理は、web.xmlに記載されたバージョンの確認をしています。

```xml:web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">
         
		  <context-param>
		    <param-name>version</param-name>
		    <param-value>1.2.3</param-value>
		  </context-param>
</web-apps>
```

```java
	/** 読み込むファイルの絶対パス */
	private static String filePath = Constants.PROJECT_PATH + "webapps/WEB-INF/web.xml";

	/** XMLファイルのdocumentオブジェクト */
	private static Document doc = null;

	@Rule
	public TestName testname = new TestName();

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		SAXReader reader = new SAXReader();
        //外部DTDを読み込まない設定（web.xmlではdtdを参照していないが、他のXMLでも読み込めるようにするため、設定する)
        //http://qiita.com/yoshi389111/items/3d0da72b1f2ccd947052
		reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
		doc = reader.read(filePath);
	}

	@Test
	public void versionの確認() throws Exception {
		//<param-value>タグの値を取得するXPath
		String key = "//p:context-param/p:param-name[text()='version']/following-sibling::p:param-value";

		// 名前空間["p"]にデフォルト名前空間を設定する
		BaseXPath xpath = new Dom4jXPath(key);
		xpath.addNamespace("p", ""http://java.sun.com/xml/ns/j2ee");

		String actual = xpath.stringValueOf(doc);
		String expected = "1.2.3";
		String name = relativeFilePath + " : " + key;
		log.info(name + " = " + actual);
		assertThat(name, actual, CoreMatchers.is(expected));
	}
```

### JavaScriptファイル

`javax.script.ScriptEngine`を使用します。

オブジェクトのプロパティ値を`get`メソッドでは取得できません。
一旦`eval`メソッド別のjs変数に代入してから、その変数の値`get`メソッドで取得します。

```js:sample.js
var C = {version: "1.2.3"};
```

```java
engine.eval(new FileReader("sample.js"));
Object a = engine.get("C.version"); //→null
engine.eval("tmp = C.version");
Object b = engine.get("tmp"); //→"1.2.3"
```

jQueryなど外部ライブラリを使うと、以下のようにReferenceErrorが発生します。
リリースチェック対象のJavaScriptファイルは、外部ライブラリを使わない方法がよいかもしれません。
（ReferenceErrorを解決する方法が分かりませんでした）

```
javax.script.ScriptException: ReferenceError: "$" is not defined in <eval> ...(省略)
```