$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

CircleCIでJava8 + Gradleプロジェクトのテストを行う

興味本位で自分のアルゴリズム実装repository( https://github.com/shibayu36/algorithms )のテストをCircleCIで動かしてみようと考えた。基本的にCircleCIはcircle.ymlに設定を追加したら終わりなのだけど、何を設定すればいいか少し調べる必要があったのでメモ。

設定

Configuring CircleCI - CircleCI などを見ながら、最終的なcircle.ymlは以下のようになった。Circle CIでJavaを使ってビルドする | さにあらずCircleCIでJUnitの結果を見る - Qiita あたりも参考になった。

machine:
  java:
    version: oraclejdk8
  timezone: Asia/Tokyo
  environment:
    GRADLE_OPTS: -Xmx4G
  post:
    - sudo service mysql stop
    - sudo service postgresql stop

checkout:
  post:
    - chmod +x ./gradlew

dependencies:
  override:
    - ./gradlew testClasses --stacktrace

test:
  override:
    - ./gradlew --full-stacktrace check
  post:
    - mkdir -p $CIRCLE_TEST_REPORTS/junit/
    - find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;

まずmachineセクションでサーバのセットアップをする。

checkoutフェーズではgradlewの実行権限を追加するだけ。

dependenciesフェーズではテストの依存をインストールする。Gradleを使っていれば、./gradlew testClasses --stacktraceだけでOK。

testフェーズでは実際にテストを動かす。

確認

これでテストが実行できるようになった。https://circleci.com/gh/shibayu36/algorithms で確認できた。

冪集合を作るメソッドをジェネリクス対応する

以前 Javaで冪集合を生成する - アルゴリズム学習(その3) - $shibayu36->blog; で冪集合を作るメソッドを実装していた。しかし、以前の実装だとListでしか冪集合を作ることができなかった。最近パーフェクトJavaを読んで、ジェネリクスについて学んだので、試しに冪集合を作るメソッドをジェネリクス対応してみた。コードは ここ においてある。

package org.shibayu36.algorithms;
import java.util.ArrayList;
import java.util.List;

public class PowerSetGenerics {
  public static <T> List<List<T>> make(List<T> data) {
    if (data.size() == 0) {
      List<List<T>> empty = new ArrayList<>();
      empty.add(new ArrayList<>());
      return empty;
    }

    List<List<T>> result = new ArrayList<>();
    for (int i = 0; i < Math.pow(2, data.size()); i++) {

      List<T> set = new ArrayList<>();
      int flags = i;
      for (int j = 0; j < data.size(); j++) {
        int flag = flags % 2;
        if (flag == 1) {
          set.add(data.get(j));
        }
        flags = flags / 2;
      }
      result.add(set);
    }

    return result;
  }
}

前とのdiffはこれだけ。メソッドローカルの型変数を宣言して、Integerの変わりにこれを利用すれば良いだけ。

@@ -3,18 +3,18 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class PowerSet1 {
-  public static List<List<Integer>> make(List<Integer> data) {
+public class PowerSetGenerics {
+  public static <T> List<List<T>> make(List<T> data) {
     if (data.size() == 0) {
-      List<List<Integer>> empty = new ArrayList<>();
+      List<List<T>> empty = new ArrayList<>();
       empty.add(new ArrayList<>());
       return empty;
     }
 
-    List<List<Integer>> result = new ArrayList<>();
+    List<List<T>> result = new ArrayList<>();
     for (int i = 0; i < Math.pow(2, data.size()); i++) {
 
-      List<Integer> set = new ArrayList<>();
+      List<T> set = new ArrayList<>();
       int flags = i;
       for (int j = 0; j < data.size(); j++) {
         int flag = flags % 2;

これで次のように、Integer以外の型でも冪集合を作れるようになった。便利。

List<List<Integer>> integerPowerSet = PowerSetGenerics.make(Arrays.asList(1, 2, 3));
System.out.println(integerPowerSet.toString());

List<List<String>> stringPowerSet = PowerSetGenerics.make(Arrays.asList("hoge", "fuga", "bar"));
System.out.println(stringPowerSet.toString());

// [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
// [[], [hoge], [fuga], [hoge, fuga], [bar], [hoge, bar], [fuga, bar], [hoge, fuga, bar]]


ジェネリクスについては以下の記事が参考になる。

ハッカソン旅行 in 和倉温泉

和倉温泉に旅行に行きました。観光 & プログラミングをしていました。

f:id:shiba_yu36:20170109194244j:plain:h500

AKB丼(甘エビ・カニ・ブリ丼)を食す。
f:id:shiba_yu36:20170109194411j:plain:h500

生卵を買うと、自分で温泉卵に出来る。塩分が強い温泉なので、自然と味がついていた。
f:id:shiba_yu36:20170109194506j:plain:h500

こいつ自分も卵のキャラなくせに、絶対に子供を温泉卵にしようとしていると思う。
f:id:shiba_yu36:20170109194622j:plain:h500

のと鉄道永井豪のラッピング電車にも乗った。
f:id:shiba_yu36:20170109194755j:plain:h500
f:id:shiba_yu36:20170109194800j:plain:h500

途中で降りた西岸駅というところは花咲くいろはの聖地らしい。
f:id:shiba_yu36:20170109194936j:plain:h500
f:id:shiba_yu36:20170109194941j:plain:h500

西岸駅で特にやることはなくてウロウロしていたら、美味しい牡蠣を出してくれる店を偶然発見。営業前だけど入れてもらった。昼前には満席で並ぶ人もいたのでラッキーだった。
f:id:shiba_yu36:20170109195059j:plain:h500f:id:shiba_yu36:20170109195101j:plain:h500f:id:shiba_yu36:20170109195104j:plain:h500

帰りは花咲くいろはのラッピング電車に。
f:id:shiba_yu36:20170109195146j:plain:h500f:id:shiba_yu36:20170109195148j:plain:h500f:id:shiba_yu36:20170109195151j:plain:h500

帰る直前の電車の待ち時間は、「はいだるい」という店で暇を潰していた。「はいだるい」ってなんだよ、営業がだるいのかよって思ってたけど(看板もだるそう)、入って聞いてみたら「はいだるい」というのは方言ということが分かった。新聞記事に「観光客に意味を聞かれれば、そこから会話が生まれる」と書かれていて、実際に聞いて会話が生まれたから、非常に良い名前だなと思った。

f:id:shiba_yu36:20170109195538j:plain:h500f:id:shiba_yu36:20170109195542j:plain:h500f:id:shiba_yu36:20170109195547j:plain:h500

帰りの電車は花嫁のれんという電車に。特に何も知らず適当に予約していたのだけど、観光列車だったようで、普通の電車とは違い、良い体験だった。

f:id:shiba_yu36:20170109195658j:plain:h500f:id:shiba_yu36:20170109195702j:plain:h500f:id:shiba_yu36:20170109195708j:plain:h500f:id:shiba_yu36:20170109195711j:plain:h500f:id:shiba_yu36:20170109195715j:plain:h500f:id:shiba_yu36:20170109195718j:plain:h500

観光計画は全く立てずに行ったのだけど、偶然的にもいろいろ発見があったり、その土地の人と会話できたりして良かった!


ちなみにハッカソンでは、勉強しているアルゴリズムの実装をしたり、ブログを書いたりしていました。成果は以下。

blog.shibayu36.org
blog.shibayu36.org
blog.shibayu36.org
blog.shibayu36.org