はじめに
今更ながら継続的インテグレーション(CI)環境を整え、自動単体テストのための仕掛けを用意しましたので、 本エントリに実施した事項をまとめます。
以降では、先日紹介したroomba_clientプロジェクトを対象に説明します。
テストコードの実装
次のようなテストコードを用意します。 今回は単にテストを動かすことが目的なので詳細は説明しませんが、 RoombaControllerTests::index()では"/"にアクセスした際のページ遷移先や、Viewに渡すデータが期待通りに設定されていることを確認しています。 RoombaControllerTests::addCommand()では"/invoke?add="へのPOST要求でDBへの行挿入のメソッドが呼び出されていることを確認しています。
@RunWith(SpringRunner.class) @WebMvcTest(RoombaController.class) public class RoombaControllerTests { @Autowired private MockMvc mvc; @MockBean private MyDataRepository repo; @MockBean private Settings settings; @MockBean private Roomba roomba; private Command c1 = new Command("c1", "seq1"); private Command c2 = new Command("c2", "seq2"); private Map<String, String> selectItems = new HashMap<String, String>() { private static final long serialVersionUID = 1L; { put("foo", "fooVal"); put("bar", "barVal"); } }; @Before public void before() { given(this.roomba.connect("192.168.0.20", 9001)).willReturn(true); given(this.roomba.send("128")).willReturn(true); given(this.roomba.disconnect()).willReturn(true); } @Test public void index() throws Exception { List<Command> commandList = new ArrayList<Command>(); commandList.add(c1); commandList.add(c2); given(this.settings.getSequences()).willReturn(selectItems); given(this.repo.findAll()).willReturn(commandList); MvcResult mvcResult = this.mvc.perform(get("/")).andDo(print()).andExpect(status().isOk()) .andExpect(view().name("index")).andExpect(model().attributeExists("userInput")) .andExpect(model().attribute("dataTable", commandList)).andReturn(); ModelMap modelMap = mvcResult.getModelAndView().getModelMap(); Object uio = modelMap.get("userInput"); assertThat(uio, is(not(nullValue()))); assertThat(uio, is(instanceOf(UserInput.class))); UserInput ui = (UserInput) uio; assertThat(ui.getSelectItems(), is(selectItems)); } @Test public void addCommand() throws Exception { this.mvc.perform(post("/invoke?add=").param("name", "command_name").param("selectedSequence", "") .param("arbitrarySequence", "128 131")).andDo(print()).andExpect(redirectedUrl("/")) .andExpect(model().hasNoErrors()); verify(repo).saveAndFlush(Mockito.any(Command.class)); }
Travis-CIの設定
続けてTravis-CI(https://travis-ci.org/)の設定です。
試験対象プロジェクトのリポジトリと連携した後、
.travis.ymlをGitリポジトリのルートに配置します。
今回はSpring bootアプリなのでlanguageにはjavaを設定し、jdkを指定します。
.travis.yml
language: java jdk: - oraclejdk8
以上でリモートリポジトリにPushする度に自動的にビルド(テスト含む)が実行されるようになりました。
Coverallsプラグインの追加
Travis-CIで実行されたテストのカバレッジレポートを確認できるようにするため、Coveralls(https://coveralls.io)と連携します。 カバレッジレポートはJacocoプラグインで出力します。
まず、build.gradleにjacocoとcoveralls-gradle-pluginを追加します。 jacocoTestReportにはレポートの出力形式を指定できますが、どうやらCoverallsはXML形式のレポートが必要なようなので xml.enabled = trueを設定します。
build.gradle
buildscript { ext { springBootVersion = '1.5.7.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath("org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'jacoco' apply plugin: 'com.github.kt3k.coveralls' jacocoTestReport { reports { xml.enabled = true //coveralls plugin depends on xml format report html.enabled = true } }
続けて、Travis-CIでビルド後にCoverallsにカバレッジ情報を転送するための設定です。
.travis.ymlのafter_successに次の設定を追記します。
.travis.yml
language: java jdk: - oraclejdk8 after_success: - ./gradlew test jacocoTestReport coveralls
カバレッジレポートの確認
以上の設定により、GitにPushするとCoverallsで単体テストの結果が確認できるようになります。
GithubのREADMEにバッジを追加
最後にGitのREADME.mdにビルド結果とカバレッジ率を示すバッジを貼り付ければ完成です。