読者です 読者をやめる 読者になる 読者になる

kivantium活動日記

プログラムを使っていろいろやります

Travis CIによるC言語プログラムの自動テスト

自動テストはエンジニアの必須スキル!という話を最近よく聞くのですが、テストをやったことがなかったのでTravis CIで試してみました。

Travis CIとは

Travis CIは自動テスト実行サービスで、GitHubと連携してpushした際に自動でテストを行ってくれるところが特徴です。

GitHubと連携できる継続的インテグレーションツール「Travis CI」入門 - さくらのナレッジに従って登録等を行いました。

設定ファイルの記述

Travis CIの設定はリポジトリのルートディレクトリに.travis.ymlというファイルを置くことで行います。

Travis CIはテストのたびに仮想マシンを立ち上げてその中でテストが走るのですが、.travis.ymlにはマシンの環境設定に関する事項と、実際にテストする内容をステップごとに記述していきます。

  • installステップ: テストに必要な環境構築について記述します。apt-getなどが使えます。
  • scriptステップ: 実際に行うテストの内容を記述します。

重要なのはこの2つのステップです。この他にはbefore_install, before_script, after_script, after_success, after_failure, before_deploy, deploy, after_deployなどがあるらしいですが今回は使いませんでした。

テストの例

GitHubで適当なレポジトリを作ってTravis CIのAccountsから連携設定をONにします。kivantium/Travis-test · GitHubというリポジトリを作りました。

ここではフィボナッチ数列を求める以下のプログラムのテストを例にします。src/main.cで保存しました。

#include <stdio.h>

int fib(int n) {
    if(n == 0) return 0;
    if(n == 1) return 1;

    return fib(n-1)+fib(n-2);
}

int main(void) {
    for(int i=0; i<20; ++i) printf("%d\n", fib(i));
}

期待される出力は

0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181

です。これをtest/answer.txtとして保存しました。

今回使った.travis.ymlは以下の通りです。

language: c     # 言語をC言語に設定 
compiler:       # clangとgccの両方でテストするよう設定
  - clang
  - gcc
script:         # テストの内容
    make && make test

script:以下で実行するプログラムのexit codeが0ならテスト成功、0でなければテスト失敗です。

make testでビルド結果の出力output.txtが期待される出力test/answer.txtと一致するかどうかを判定するようなMakefileを書きました。

CC = gcc
CFLAGS = -std=c99
TARGET = fib

$(TARGET): src/main.c
    $(CC) $(CFLAGS) $^ -o $(@)

test: $(TARGET)
    @./fib > output.txt
    @if diff output.txt test/answer.txt > /dev/null; then echo "test: OK"; else echo "test: NG"; exit 1; fi

clean:
    rm -f output.txt $(TARGET)

README.mdに現在のテスト結果を表示するためにTravis CIのサイトからStatus Imageへのリンクを取得します(表示されているそれっぽい画像をクリックすると表示されます)。

[![Build Status](https://travis-ci.org/kivantium/Travis-test.svg?branch=master)](https://travis-ci.org/kivantium/Travis-test)

のように書きました。

以上をcommitしてリポジトリにpushするとテストが走ります。 f:id:kivantium:20160923162250p:plain:w800 やったぜ。

test/answer.txtを適当に書き換えるとテストに失敗します。 f:id:kivantium:20160923162859p:plain:w800

exit codeが0になるかならないかだけ制御すればどんなコードでもテストに使えるというのが学びでした。