Prework:

怎样写一个基本的Eunit? Doc.

1. 加入头文件:声明此模块以”_test”结尾的函数都是测试用,并在编译时自动在这个模块里加入test()函数(当然这个可以用宏来控制)

-include_lib("eunit/include/eunit.hrl").

2.编写测试用例:”*_test()”函数":

reverse_nil_test() -> [] = lists:reverse([]).
reverse_one_test() -> [1] = lists:reverse([1]).
reverse_two_test() -> [2,1] = lists:reverse([1,2]).
%%也可以用宏:这个有好几种,很方便,要用就看文档,比不用宏的优势在于出错信息详细
length_test() -> ?assert(length([1,2,3]) =:= 3).

3. 运行 Eunit

编译Module –> 然后:

Module:test().
%%或
eunit:test(Module).

以上是一个最简单的Eunit的例子,那么:

Question: 类似gen_server有启动进程类的Eunit怎么写?有并发的怎么写?

基本Code形式:

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-compile({no_auto_import, [get/1, put/2]}). basic_test_() ->
{setup,
fun() ->
?debugFmt("Starting ~p", [?MODULE]),
case start_link() of
{error, {already_started, _}} ->
ok;
{ok, _} ->
do_stop
end
end,
fun(Stop) ->
case Stop of
do_stop -> stop();
ok -> ok
end
end,
[
{timeout, 60, fun normal_insert/0},
{timeout, 60, fun ttl_insert/0}
]
}.
noraml_insert() ->
todo.
ttl_insert() ->
todo.
-endif.
Eunit提供以下格式:
%%To make the descriptions simpler, we first list some definitions:
Setup () -> (R::any())
SetupX (X::any()) -> (R::any())
Cleanup (R::any()) -> any()
CleanupX (X::any(), R::any()) -> any()
Instantiator ((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}
Where local | spawn | {spawn, Node::atom()}
Table .1: (these are explained in more detail further below.) %%The following representations specify fixture handling for test sets: {setup, Setup, Tests | Instantiator}
{setup, Setup, Cleanup, Tests | Instantiator}
{setup, Where, Setup, Tests | Instantiator}
{setup, Where, Setup, Cleanup, Tests | Instantiator}
Setup     () -> (R::any())
SetupX (X::any()) -> (R::any())
Cleanup (R::any()) -> any()
CleanupX (X::any(), R::any()) -> any()
Instantiator ((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}
Where local | spawn | {spawn, Node::atom()}

我们上面就是用的: {setup,Setup,Cleanup,TestList}这种,所以用Setup启动,运行TestList后用启动Setup的返回值传入Cleanup(Val)结束!注意这个test一定是xxx_test_()的形式,注意最后的_ 

可以看出_test_()的范围比_test()的大,但是限定为fun() –> end.

Tip: 如果你想用新起进程来测试一个模块【gen_server是不需要这样子的,本来就是新起了个进程】可以参照Where参数。

通过以上,我们就可以写出很漂亮的gen_server的enuit函数啦!!

那么如何让多个enuit并行跑呢?比如不相关的几个gen_server并行跑起来!

用参数:inparallel

base_test_() ->
{setup, spawn,
fun() -> start() end,
fun(_) -> stop() end,
{inparallel, 3,[
{timeout, 60, funnormal_insert/0},
{timeout, 60, ttl_insert/0}
]}
}.

惊喜:可以指定同时跑几个哦,上面指定了3个,不指定也可以的.

========================================================

一个好的application一定要有可靠的测试用例!,但是如果你在程序里面大量用有副作用的进程字典,还是很难写enuit的…

最新文章

  1. 第三方网站不能调用微信公众平台里的图片了 显示"此图片来自微信公众号平台未经允许不可引用"
  2. SVN小贴士
  3. 虚拟化之vmware DirectPath I/O
  4. OAF_架构MVC系列2 - Model的概述(概念)
  5. ASP.NET MVC5 第4章
  6. 书签(Bookmarks)
  7. BZOJ 1237 配对
  8. vim编辑器中撤销和恢复操作
  9. 工厂方法配置jdbc连接
  10. 前端css要加的一些
  11. Ready!Api创建使用DataSource和DataSourceLoop的循环测试用例
  12. Shell脚本编程入门(一)
  13. Python爬虫与一汽项目【一】爬取中海油,邮政,国家电网问题总结
  14. ES6模板字符串【${}配合反单引号一起用】
  15. select实现高并发服务器
  16. 用python表白了!!!
  17. python练习册0005
  18. java 线程状态相关测试
  19. IntelliJ IDEA设置代码括号对齐方式
  20. CSS-布局样式之筛选条件右边线的处理方法(no CSS3)

热门文章

  1. Tomcat官方文档关于数据源配置的内容
  2. 爬虫——回顾HTTP 协议
  3. TCP超时与重传机制
  4. NetworkStream.write只能使用一次,后面再使用无效
  5. [转]DWZ表单验证规则一览表(留着自己用)
  6. MyBatis 学习记录1 一个简单的demo
  7. 在MyEclipse中用debug调试应用程序
  8. My97DatePicker日期控件的使用
  9. 认识Echarts(网址:http://echarts.baidu.com/tutorial.html#ECharts%20%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D)
  10. java创建TXT文件并进行读、写、修改操作