Fitnesseを試した

参加しているプロジェクトでテストの自動化が課題になっている。
実践アジャイルテストという本に出てきたFitnesseを試してみた。

環境
javaが古いけど試せたから気にしない

$ cat /etc/issue
CentOS release 6.2 (Final)
Kernel r on an m/

$ java -version
java version “1.6.0_22”
OpenJDK Runtime Environment (IcedTea6 1.10.4) (rhel-1.41.1.10.4.el6-i386)
OpenJDK Client VM (build 20.0-b11, mixed mode)
[nobuatsu@localhost fitnesse]$ cat /etc/centos-release
CentOS release 6.2 (Final)


ダウンロードとインストールは下記に書いてある通り
http://fitnesse.org/FitNesse.UserGuide.DownloadingAndInstallingFitNesse

fitnesseをダウンロード
http://fitnesse.org/FrontPage.FitNesseDevelopment.DownLoad

適当な場所にjarを置いて、
java -jar fitnesse.jar

ポートが使用中だったら、別のポートを使う
java -jar fitnesse.jar -p 8080

起動時の表示。

FitNesse (v20111026) Started…
port: 8080
root page: fitnesse.wiki.FileSystemPage at ./FitNesseRoot
logger: none
authenticator: fitnesse.authentication.PromiscuousAuthenticator
html page factory: fitnesse.html.HtmlPageFactory
page version expiration set to 14 days.

ブラウザからを開く。FrontPageが表示されればOK。

アクセスできないときは、firewallの設定を確認
CentOSだったら、/etc/sysconfig/iptables に、以下を追加(portに8080を使う場合)

-A INPUT -m state –state NEW -m tcp -p tcp –dport 8080 -j ACCEPT

サンプルのテストを実行してみる。
FrontPage のリンクから A Two-Minute Example を開き、左上の Test をクリックして、”5 right, 1 wrong, 0 ignored, 0 exceptions” になればOK。
実行後には、テストケースのtableが、緑と赤になる。


テストを実行するためには、何をすればよいか。
fitnessの仕組みは、下記ページの下の方にある図でざっくりとわかる。
http://fitnesse.org/FitNesse.UserGuide.OneMinuteDescription
・オレンジ色の部分を作る必要がある。
・TestCases は、wikiで編集
・Custom Fixtures は、TEST_SYSTEM に合った言語で作成
・Test API Calls は、Fixtures が呼び出すAPI。python の os.system や commands.getoutput を使ってみる。
・SUTとは、System Under Test?
・緑色の部分はインストールした時点で使えるようになっている。

C++のターゲットをテストしたいけど、CSlimはよくわからなかったので、pythonから呼ぶことに。

PyFitをインストール
PyFIT-0.8a2.zip をダウンロードして unzip
http://pypi.python.org/pypi/PyFIT/0.8a2

rootになって、インストールすると、エラー

$ python setup.py install
Traceback (most recent call last):
File “setup.py”, line 72, in
fixLineEndings(“fit/FitFilter.py”)
File “setup.py”, line 57, in fixLineEndings
inFile = open(path, “rb”)
IOError: [Errno 2] No such file or directory: ‘/home/nobuatsu/fitnesse/PyFIT-0.8a2/fit/FitFilter.py’

FitFilter.py を使っている行を削除する。
(Yahoo Groups 参照 http://tech.groups.yahoo.com/group/fitnesse/message/8375 )

で、インストール成功。


テストを作って、実行してみる。
(参考 http://agiletesting.blogspot.jp/2004/11/writing-fitnesse-tests-in-python.html )

まずは、テストページの作成
FronPage の Edit をクリックして、WikiWordを追加。(大文字を2つ以上含む英字なので、 FirstTrialWithPython とした。)

追加したページの Edit をクリックして、TestTable を書く。

!define TEST_SYSTEM (fit)
!define COMMAND_PATTERN {python -v %m %p}
!define TEST_RUNNER {/usr/lib/python2.6/site-packages/fit/FitServer.py}
!path ${HOME}/fitnesse/fixtures/

!contents -R2 -g -p -f -h

pythonで作ったFixtureをテスト

|test_1|
|input0|input1|output?|
|1|2|3|
|4|5|9|

cで作ったa.outをテスト

|test_2|
|input0|input1|resultcode?|output?|
|1|2|0|3|

SUTを作ってデプロイ(今回はお試しなので簡単に)

add.c

#include 
#include 

int main(int argc, char** argv) {
  if (argc != 3) {
    return (-1);
  }

  if (( atoi(argv[1]) < 0) || (atoi(argv[2]) < 0) ) {
    return (-1);
  }

  printf("%dn", ( atoi(argv[1]) + atoi(argv[2]) ));
  return 0;
}

$ cc add.c
$ cp a.out /opt/SUT/

Fixture を作る。

test_1.py

from fit.ColumnFixture import ColumnFixture

class test_1(ColumnFixture):

  _typeDict={
    "input0": "Int",
    "input1": "Int",
    "output": "Int",
  }

  input0 = 0
  input1 = 0
  result = 0

  def output(self):
    return ( self.input0 + self.input1 )

test_2.py

import shlex, subprocess
from fit.ColumnFixture import ColumnFixture

class test_2(ColumnFixture):

  _typeDict={
    "input0": "Int",
    "input1": "Int",
    "resultcode": "Int",
    "output": "Int",
  }

  input0 = 0
  input1 = 0
  resultcode = 0
  output = 0

  def execute(self):
    args = ['/opt/SUT/a.out', str(self.input0), str(self.input1)]
    p = subprocess.Popen(args, stdout=subprocess.PIPE)
    ret = p.wait()
    self.resultcode = ret
    out = p.stdout.read()
    self.output = int(out)

if __name__ == '__main__':
  ins = test_2()
  ins.input0 = 5
  ins.input1 = 10
  print '---------- input0'
  print ins.input0
  print '---------- input1'
  print ins.input1
  ins.execute()
  print '---------- ins.resultcode'
  print ins.resultcode
  print '---------- ins.output'
  print ins.output

左上の Test をクリック。
Test が見当たらない場合は、Properties をクリックして、Page Type: の Test を選ぶ。

緑になればOK
テスト結果画面


その他
・WikiPageの!pathにも、環境変数を使えた。
・WikiWordにしたくないものは、CamelCaseではなく、under_scoreにすれば、とりあえずは解決。
・Output Captured の ! が出る。stdoutに出しているから?。テスト対象の問題ではなさそうなので、見栄えは悪いが放置。

・a.outの引数の過不足をテストする方法が不明。入力値に null 指定しても、引数に 'None'が渡されているようだ。こういうのは単体テストでやると思うので気にしない。

・大小比較や!=のやり方が不明(Slimならできる?)。どうしても必要なら、Fixtureでどうにか出来るのかも。
http://fitnesse.org/FitNesse.UserGuide.ComparisonExpressionsInFixtures
http://fitnesse.org/FitNesse.UserGuide.SliM.ValueComparisons

・これはSlimではなく、Fitを使ったやり方。!define TEST_SYSTEM (fit) してる。
http://fitnesse.org/FitNesse.UserGuide.OneMinuteDescription の図の上側のルート


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*