ローカルで通るテストが Travis 通らない問題

最近覚えた Travis を使って、GitHub にあるプロジェクトを Travis で回してみる。
するとどうでしょう。

ローカルで通っていたはずのテストが通らない...
何故だ??

失敗するのは Java8 で追加された Date-Time API を学習するために用意したテストケース。
API である Calendar と新 API である LocalDateTime との相互比較。
Calendar で出来てたことを、新しい API だとどうするのか?というのの学習テスト。

で、今回失敗するのは以下のケース。
"時間" の比較で失敗している。

@Test
public void LocalDateTimeから旧Dateクラスへ変換が行われること() {
    LocalDateTime dateTime = LocalDateTime.of(2014, 4, 20, 21, 46, 9);
    ZonedDateTime date = ZonedDateTime.of(dateTime, ZoneId.of("Asia/Tokyo"));
    Instant instant = Instant.from(date);
    Date oldDate = Date.from(instant);

    // 検証用に変換(--> Calender)
    Calendar oldCal = DateUtils.toCalendar(oldDate);
    assertThat(oldCal.get(Calendar.YEAR), is(dateTime.getYear()));
    assertThat(oldCal.get(Calendar.MONTH) + 1, is(dateTime.getMonthValue()));
    assertThat(oldCal.get(Calendar.DAY_OF_MONTH), is(dateTime.getDayOfMonth()));
    assertThat(oldCal.get(Calendar.HOUR_OF_DAY), is(dateTime.getHour()));  // ココで失敗する
    assertThat(oldCal.get(Calendar.MINUTE), is(dateTime.getMinute()));
    assertThat(oldCal.get(Calendar.SECOND), is(dateTime.getSecond()));
}

テスト結果は

Expected: is <21>
     but: was <12>

これが Travis だと失敗する。
う〜ん〜ローカルで実行すると成功するのに何故だ〜???

この結果の差を見てみると「9時間」...

...

もしやタイムゾーンが怪しい?

ということで ZonedDateTime と同じタイムゾーンを、変換した Calendar クラスにも設定してあげる。

Calendar oldCal = DateUtils.toCalendar(oldDate);

// 以下追加
TimeZone asiaZone = TimeZone.getTimeZone("Asia/Tokyo");
oldCal.setTimeZone(asiaZone);

ほんでもって再実行。

...

成功!!

恐らくだけど、Travis が実行されている環境 (サーバ?) のタイムゾーンが Asia/Tokyo じゃなかったから、そこで差が出たんだと思われる。
いや〜Japan で実行しているうちは気付かないところだな。
そもそもちゃんとタイムゾーンを設定してあげろよって話か。ハイ、スイマセン。

https://github.com/naotawool/learning_java/blob/master/src/test/java/naotake/learning/java8/DateTest.java