rebar和common_test使用实践和疑惑澄清
rebar是个功能非常强大的Erlang项目管理工具,参看这里 https://github.com/basho/rebar,他的定位是:
rebar is an Erlang build tool that makes it easy to compile and
test Erlang applications, port drivers and releases.rebar is a self-contained Erlang script, so it’s easy to distribute or even
embed directly in a project. Where possible, rebar uses standard Erlang/OTP
conventions for project structures, thus minimizing the amount of build
configuration work. rebar also provides dependency management, enabling
application writers to easily re-use common libraries from a variety of
locations (git, hg, etc).
common_test是Erlang强大的黑盒测试框架 参见这里
Common Test is a portable application for automated testing. It is suitable for black-box testing of target systems of
any type (i.e. not necessarily implemented in Erlang), as well as for white-box testing of Erlang/OTP programs. Blackbox
testing is performed via standard O&M interfaces (such as SNMP, HTTP, Corba, Telnet, etc) and, if required, via
user specific interfaces (often called test ports). White-box testing of Erlang/OTP programs is easily accomplished by
calling the target API functions directly from the test case functions. Common Test also integrates usage of the OTP
cover tool for code coverage analysis of Erlang/OTP programs.
Common Test executes test suite programs automatically, without operator interaction. Test progress and results is
printed to logs on HTML format, easily browsed with a standard web browser. Common Test also sends notifications
about progress and results via an OTP event manager to event handlers plugged in to the system. This way users can
integrate their own programs for e.g. logging, database storing or supervision with Common Test.
Common Test provides libraries that contain useful support functions to fill various testing needs and requirements.
There is for example support for flexible test declarations by means of so called test specifications. There is also
support for central configuration and control of multiple independent test sessions (towards different target systems)
running in parallel.
Common Test is implemented as a framework based on the OTP Test Server application.
但是common_test由于太强大了,新手使用起来会比较麻烦,经常会碰到些问题,不好解决。
这时候rebar来救助了,它的ct功能把common_test使用的麻烦给解决掉了,让你轻松做测试。
我们先来体验下:
$ mkdir foo $ cd foo/ $ touch rebar.config $ rebar create-app appid=foo ==> foo (create-app) Writing src/foo.app.src Writing src/foo_app.erl Writing src/foo_sup.erl $ rebar create template=ctsuite ==> foo (create) Writing test/mymodule_SUITE.erl $ rebar ct suite=mymodule ==> foo (ct) DONE. Testing chuba.foo.mymodule_SUITE: TEST COMPLETE, 0 ok, 0 failed, 1 skipped of 1 test cases $ cd logs $ hostname -i 10.232.31.89 $ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...
打卡浏览器 http://10.232.31.89:8000我们可以看到:
上面我们演示了rebar的ct功能使用的基本步骤,底下是进阶信息:
我们从rebar_ct.erl中可以看到:
%% Global options: %% verbose=1 - show output from the common_test run as it goes %% suite=\"foo\"\" - runs <test>/foo_SUITE %% case=\"mycase\" - runs individual test case foo_SUITE:mycase ... get_ct_config_file(TestDir) -> Config = filename:join(TestDir, \"test.config\"), case filelib:is_regular(Config) of false -> \" \"; true -> \" -ct_config \" ++ Config end. ... get_config_file(TestDir) -> Config = filename:join(TestDir, \"app.config\"), case filelib:is_regular(Config) of false -> \" \"; true -> \" -config \" ++ Config end.
如果test目录下有app.config 那么会把它用-config app.config传给vm, 这个app.config主要用于设置application的环境变量。
如果有test.config, 那么会把它用 -ct_config test.config传给vm, 这个test.config主要用于配置测试案例的变量。
test.config规格是类似这样的,可以参见common_test userguide里面配置的章节:
{key, value}.
{catalog, [{k1,v1}, {k2, v2}]}.
程序里面要用方式获取:
ct:get_config(key).
ct:get_config({catalog,key}).
获取配置的方式有底下几种,是很容易混淆的地方,我来解释下:
test_mymodule(_Config) -> io:format(\"port ~p~n\", [ct:get_config({foo, port})]), io:format(\"priv_dir ~p~n\", [?config(priv_dir, _Config)]), io:format(\"priv_dir ~p~n\", [proplists:get_value(priv_dir, Config)]), ok.
?config(key, Config).只是用于读取config变量里面的值,和proplists:get_value(key, Config)是一样的。
看代码:
-define(config,test_server:lookup_config). lookup_config(Key,Config) -> case lists:keysearch(Key,1,Config) of {value,{Key,Val}} -> Val; _ -> io:format(\"Could not find element ~p in Config.~n\",[Key]), undefined end.
现在我们来演示下test.config的使用:
$ pwd /home/chuba/foo/test $ cat test.config {foo, [{hostname, \"127.0.0.1\"}, {port, 8000} ]}. $ diff mymodule_SUITE.erl mymodule_SUITE.erl.orig 164c164 < [{require, foo}, {userdata,[{doc,\"Testing the mymodule module\"}]}]. --- > [{userdata,[{doc,\"Testing the mymodule module\"}]}]. 167,168c167 < io:format(\"port ~p~n\", [ct:get_config({foo, port})]), < ok. --- > {skip,\"Not implemented.\"}. $ rebar ct suite=mymodule ==> foo (ct) DONE. Testing chuba.foo.mymodule_SUITE: TEST COMPLETE, 1 ok, 0 failed of 1 test cases
当然也可以用ct_run来运行:
$ct_run -suite $PWD/mymodule_SUITE -pa $PWD/ebin -logdir $PWD/logs -config test/test.config Erlang R14B04 (erts-5.8.5) 1 [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.5 (abort with ^G) Common Test v1.5.5 starting (cwd is /home/chuba/foo) (ct@my031089)1> Common Test: Running make in test directories... CWD set to: \"/home/chuba/foo/logs/ct_run.ct@my031089.2011-10-19_11.52.21\" TEST INFO: 1 test(s), 1 case(s) in 1 suite(s) Testing chuba.foo.mymodule_SUITE: Starting test, 1 test cases Testing chuba.foo.mymodule_SUITE: TEST COMPLETE, 1 ok, 0 failed of 1 test cases Updating /home/chuba/foo/logs/index.html... done Updating /home/chuba/foo/logs/all_runs.html... done
我们可以看到ct_run是通过-config foo.config 这样来传配置文件的,这个地方和容易和erl -config app.config混淆。
实际上ct_run是个程序,我们看下他的代码:
//ct_run.c ... else if (cnt < erl_args) { if (strcmp(argv[1], \"-config\") == 0) PUSH(\"-ct_config\"); else if (strcmp(argv[1], \"-decrypt_key\") == 0) PUSH(\"-ct_decrypt_key\"); else if (strcmp(argv[1], \"-decrypt_file\") == 0) PUSH(\"-ct_decrypt_file\"); else PUSH(argv[1]); } ...
-config选项会被转化成-ct_config来传递给vm,所以和-config app.config就能分开,但是理解起来确实很恼人。
小结: rebar和common_test配合起来用的很爽。
建议继续学习:
- Erlang match_spec引擎介绍和应用 (阅读:4530)
- whatsapp深度使用Erlang有感 (阅读:4572)
- php-erlang (阅读:4309)
- gen_tcp调用进程收到{empty_out_q, Port}消息奇怪行为分析 (阅读:3544)
- hibernate使用注意事项 (阅读:3219)
- Erlang linkin driver用port_control方式时的一些经验分享 (阅读:2968)
- Erlang如何限制节点对集群的访问之net_kernel:allow (阅读:2971)
- ERLANG OTP源码分析 – gen_server (阅读:2859)
- erlang学习手记 (阅读:2697)
- gen_tcp容易误用的一点解释 (阅读:2638)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Yu Feng 来源: Erlang非业余研究
- 标签: common_test ct Erlang rebar
- 发布时间:2011-10-25 13:46:30
- [54] android 开发入门
- [53] IOS安全–浅谈关于IOS加固的几种方法
- [51] Oracle MTS模式下 进程地址与会话信
- [51] 图书馆的世界纪录
- [50] 如何拿下简短的域名
- [50] Go Reflect 性能
- [48] 读书笔记-壹百度:百度十年千倍的29条法则
- [47] 【社会化设计】自我(self)部分――欢迎区
- [38] 程序员技术练级攻略
- [31] 视觉调整-设计师 vs. 逻辑