Swift が opensource 化されてもう一月以上。みなさんテストはどうされてますか?
もちろんこの場合XCTestなんてチャラいものは使えません。Linux版にSwift自体はあってもXcodeなんてありませんから。
というわけで、私はずっとTest Anything Protocolを使ってきました。
発祥はPerl Communityですが、別にPerlでなくても使えます。例えばJSの世界ではよく使われているmochaも対応してますし、TAP適合の出力であれば、それをチェックするためのスクリプトprove
は、Perlが入っている環境であれば必ず入っているのでOS XとLinux Distroの過半では out-of-box で使えます。
見てのとおりシンプルなものなので、その場で都度実装してもいいですし実際そうしてきたのですが、ずいぶんとSwiftのプロジェクトも増えたので、今回その部分だけ独立させました。
実際のテストコードは、こんな。
let test = TAP(tests:7)
test.ok(42+0.195 == 42.195, "42 + 0.195 == 42.195")
test.eq(42+0.195, 42.195, "42 + 0.195 is 42.195")
test.eq([42,0.195],[42,0.195], "[42,0.195] is [42,0.195]")
test.eq([42:0.195],[42:0.195], "[42:0.195] is [42,0:195]")
test.ne(42+0.195, 42.0, "42 + 0.195 is not 42")
test.ne([42,0.195],[42,0.0], "[42,0.195] is not [42,0.0]")
test.ne([42:0.195],[42:0.0], "[42:0.195] is not [42:0.0]")
test.done()
出力は、こんな。
1..7
ok 1 - 42 + 0.195 == 42.195
ok 2 - 42 + 0.195 is 42.195
ok 3 - [42,0.195] is [42,0.195]
ok 4 - [42:0.195] is [42,0:195]
ok 5 - 42 + 0.195 is not 42
ok 6 - [42,0.195] is not [42,0.0]
ok 7 - [42:0.195] is not [42:0.0]
prove
に食わせると、こんな。
% prove ./main
./main .. ok
All tests successful.
Files=1, Tests=7, 0 wallclock secs ( 0.02 usr + 0.01 sys = 0.03 CPU)
Result: PASS
で、何がありがたいかっていうと、.travis.yml
もこれくらい簡単になること。
language: objective-c
osx_image: xcode7
script:
- make test
Makefile
はこんな感じ。
BIN=main
MOD=TAP
MODSRC=tap/tap.swift
BINSRC=$(MODSRC) tap/main.swift
MODULE=$(MOD).swiftmodule $(MOD).swiftdoc
SWIFTC=swiftc
SWIFT=swift
ifdef SWIFTPATH
SWIFTC=$(SWIFTPATH)/swiftc
SWIFT=$(SWIFTPATH)/swift
endif
OS := $(shell uname)
ifeq ($(OS),Darwin)
SWIFTC=xcrun -sdk macosx swiftc
endif
all: $(BIN)
module: $(MODULE)
clean:
-rm $(BIN) $(MODULE) lib$(MOD).*
$(BIN): $(BINSRC)
$(SWIFTC) $(BINSRC)
test: $(BIN)
prove ./$(BIN)
$(MODULE): $(MODSRC)
$(SWIFTC) -emit-library -emit-module $(MODSRC) -module-name $(MOD)
repl: $(MODULE)
$(SWIFT) -I. -L. -l$(MOD)
見てのとおり、make test
のみならず、モジュールも作れるのでmake repl
でREPLからも使えます。
% make repl
xcrun -sdk macosx swiftc -emit-library -emit-module tap/tap.swift -module-name TAP
swift -I. -L. -lTAP
Welcome to Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81). Type :help for assistance.
1> import TAP
2> let test=TAP()
test: TAP.TAP = {
tests = 0
runs = 0 values
}
3> test.eq(42,42,"Life, the Universe, and Everything")
ok 1 - Life, the Universe, and Everything
$R0: Bool = true
4> test.eq(42,41,"Life, the Universe, and Everything")
not ok 2 - Life, the Universe, and Everything
# got: 42
# expected: 41
$R1: Bool = false
5> test.done()
1..2
error: REPL process is no longer alive, exiting REPL
Swift REPL requires a running target process.
ENJOY!
Dan the Simple Tester