Erlang被称作是“工业级的语言”,在测试领域,理应是有相当成熟度的。而,Joe老先生本人,也是崇尚“拿测试结果说话”的人(在《Programming Erlang》书中,上来就搞测试,然后再开讲的例子比比皆是)。就连 Erlang/OTP 本身的代码质量也是有严密的测试作为保障的。所以,如果在Erlang领域,你见到远比其他语言为多的测试相关工具、框架、包,丝毫也不应该感到惊奇。下面,我们就来看看“Erlang的测试兵器谱”中,都有什么好家伙。
首先是大名鼎鼎的 Test_Server ,需要说明的是 Erlang/OTP 自身代码的几千个 Test Case 就是构建在它的基础之上。Test_Server 的功能可谓面面俱到,让人眼花缭乱,从简单的测试任务,到对多环境下的测试,乃至对嵌入式系统进行测试,没有它不在行的。但也正因为此,使用稍嫌复杂,比如必须从 Erlang/OTP 的源码来构建和编译 Test_Server ,又比如较为复杂的 case 定义。
然后是 Yet Another 系列,隆重推出:yatsy——Yet Another Test Server (咦?最后一个 y 是哪里来的呢?), yatsy 和 test_server 的语法完全一致,功能大致相当,所不同的是: yatsy 是 host 在 google 上的 opensource 的项目,而 test_server 是 ericsson 的产品(虽说也给了 sourcecode 但不是 public repository ,这算哪门子区别?),另一个区别是 yatsy 和 yaws 有很好的结合(都是 Yet Another 一家的嘛),主要用来生成 report 。
另外,还有 Erlang QuickCheck 是一个 commercial 的测试工具,咱们支持 opensource 这里就不表了。
我个人最喜欢的小巧工具是 EUnit ,简单,易用。对于“非火箭科技”的普通程序员来说,简简单单的就好。60秒入门如下:
- -module(fib).
- -export([fib/1]).
- %% 加了这句,会自动多出来一个 test() 方法,测试直接跑 fib:test() 就好了。
- -include_lib("eunit/include/eunit.hrl").
-
- fib(0) -> 1;
- fib(1) -> 1;
- fib(N) when N > 1 -> fib(N-1) + fib(N-2).
-
- %% xxx_test() 是测试 case ,test() 会调用每一个 case 就像 junit 一样
- fib_test() -> fib(0) == 1.
-
- %% xxxx_test_() case 生成器,每个 ?_assert(...) 都会生成一个 case 函数
- %% 一般用这个就可以了
- fib_test_() ->
- [?_assert(fib(0) == 1),
- ?_assert(fib(1) == 1),
- ?_assert(fib(2) == 2),
- ?_assert(fib(3) == 3),
- ?_assert(fib(4) == 5),
- ?_assert(fib(5) == 8),
- ?_assertException(error, function_clause, fib(-1)),
- ?_assert(fib(31) == 2178309)
- ].
-
- setup() ->
- io:format("Setup called", []).
-
- %% 如果需要 setup 就这么干
- do_test_() ->
- {setup, fun setup/0, [?_assert(1=:=0)]}.
就这么多了,简洁明快吧。
上面是功能测试或者说单元测试,那么,在性能测试上,我们有鼎鼎大名和鼎鼎大名的 Tsung (嗯,谁知道这个词的正确发音是怎样的?)。这个东西,留待日后俺学习到了再和大家分享。