`
mryufeng
  • 浏览: 982388 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Unit Testing with Erlang’s Common Test Framework

阅读更多
原文地址: http://streamhacker.wordpress.com/2008/11/26/unit-testing-with-erlangs-common-test-framework/

Unit Testing with Erlang’s Common Test Framework

November 26, 2008 at 10:57 am (erlang) (common_test, eunit, make, otp, testing)

One of the first things people look for when getting started with Erlang is a unit testing framework, and EUnit tends to be the framework of choice. But I always had trouble getting EUnit to play nice with my code since it does parse transforms, which screws up the handling of include files and record definitions. And because Erlang has pattern matching, there’s really no reason for assert macros. So I looked around for alternatives and found that a testing framework called common_test has been included since Erlang/OTP-R12B. common_test (and test_server), are much more heavy duty than EUnit, but don’t let that scare you away. Once you’ve set everything up, writing and running unit tests is quite painless.
Directory Setup

I’m going to assume an OTP compliant directory setup, specifically:

   1. a top level directory we’ll call project/
   2. a lib/ directory containing your applications at project/lib/
   3. application directories inside lib/, such as project/lib/app1/
   4. code files are in app1/src/ and beam files are in app1/ebin/

So we end up with a directory structure like this:

project/
    lib/
        app1/
            src/
            ebin/

Test Suites

Inside the app1/ directory, create a directory called test/. This is where your test suites will go. Generally, you’ll have 1 test suite per code module, so if you have app1/src/module1.erl, then you’ll create app1/test/module1_SUITE.erl for all your module1 unit tests. Each test suite should look something like this: (unfortunately, wordpress doesn’t do syntax highlighting for erlang, so it looks kinda crappy)

-module(module1_SUITE).

% easier than exporting by name
-compile(export_all).

% required for common_test to work
-include("ct.hrl").

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% common test callbacks %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Specify a list of all unit test functions
all() -> [test1, test2].

% required, but can just return Config. this is a suite level setup function.
init_per_suite(Config) ->
    % do custom per suite setup here
    Config.

% required, but can just return Config. this is a suite level tear down function.
end_per_suite(Config) ->
    % do custom per suite cleanup here
    Config.

% optional, can do function level setup for all functions,
% or for individual functions by matching on TestCase.
init_per_testcase(TestCase, Config) ->
    % do custom test case setup here
    Config.

% optional, can do function level tear down for all functions,
% or for individual functions by matching on TestCase.
end_per_testcase(TestCase, Config) ->
    % do custom test case cleanup here
    Config.

%%%%%%%%%%%%%%%%
%% test cases %%
%%%%%%%%%%%%%%%%

test1(Config) ->
    % write standard erlang code to test whatever you want
    % use pattern matching to specify expected return values
    ok.

test2(Config) -> ok.

Test Specification

Now the we have a test suite at project/app1/test/module1_SUITE.erl, we can make a test specification so common_test knows where to find the test suites, and which suites to run. Something I found out that hard way is that common_test requires absolute paths in its test specifications. So instead of creating a file called test.spec, we’ll create a file called test.spec.in, and use make to generate the test.spec file with absolute paths.
test.spec.in

{logdir, "@PATH@/log"}.
{alias, app1, "@PATH@/lib/app1"}.
{suites, app1, [module1_SUITE]}.

Makefile

src:
    erl -pa lib/*/ebin -make

test.spec: test.spec.in
    cat test.spec.in | sed -e "s,@PATH@,$(PWD)," > $(PWD)/test.spec

test: test.spec src
    run_test -pa $(PWD)/lib/*/ebin -spec test.spec

Running the Tests

As you can see above, I also use the Makefile for running the tests with the command make test. For this command to work, run_test must be installed in your PATH. To do so, you need to run /usr/lib/erlang/lib/common_test-VERSION/install.sh (where VERSION is whatever version number you currently have). See the common_test installation instructions for more information. I’m also assuming you have an Emakefile for compiling the code in lib/app1/src/ with the make src command.
Final Thoughts

So there you have it, an example test suite, a test specification, and a Makefile for running the tests. The final file and directory structure should look something like this:

project/
    Emakefile
    Makefile
    test.spec.in
    lib/
        app1/
            src/
                module1.erl
            ebin/
            test/
                module1_SUITE.erl

Now all you need to do is write your unit tests in the form of test suites and add those suites to test.spec.in. There’s a lot more you can get out of common_test, such as code coverage analysis, HTML logging, and large scale testing. I’ll be covering some of those topics in the future, but for now I’ll end with some parting thoughts from the Common Test User’s Guide:

    It’s not possible to prove that a program is correct by testing. On the contrary, it has been formally proven that it is impossible to prove programs in general by testing.

    There are many kinds of test suites. Some concentrate on calling every function or command… Some other do the same, but uses all kinds of illegal parameters.

    Aim for finding bugs. Write whatever test that has the highest probability of finding a bug, now or in the future. Concentrate more on the critical parts. Bugs in critical subsystems are a lot more expensive than others.

    Aim for functionality testing rather than implementation details. Implementation details change quite often, and the test suites should be long lived.

    Aim for testing everything once, no less, no more

分享到:
评论
6 楼 GodwitNow 2009-08-03  
mryufeng 写道
啊 中毒太深! 模块的加载运行都是靠code:path()来定位的 include是给编译器看的呀。。。


嘿嘿,谢谢老大!
还没试,等有结果了再来汇报!~;)
5 楼 mryufeng 2009-07-28  
啊 中毒太深! 模块的加载运行都是靠code:path()来定位的 include是给编译器看的呀。。。
4 楼 GodwitNow 2009-07-28  
老大,请教个问题:
如果在module1_SUITE.erl 里面用到了module1.erl里面的函数,那么在执行run_test的时候,
-include参数,是要包含 lib/app1/src 么?

为虾米我在自己的机器上运行的时候,老是提示函数找不到呢?
3 楼 litaocheng 2009-04-11  
恩,eunit,很多时候,我是想用可是用不上.呵呵
很多module都依赖其它(可能这是一种不好的程序设计), 结果想unit test,要写出很多的数据.
还是common test这种更方便一些.
2 楼 mryufeng 2009-04-11  
比eunit的优势是有基础设施 方便你做复杂的测试!
1 楼 litaocheng 2009-04-11  
这个make用的很恰当,呵呵。common test,必须的

相关推荐

    erlang port driver test

    标题 "erlang port driver test" 指的是一个测试项目,这个项目专注于验证和测试 Erlang 的 Port Driver 功能。测试的目标可能是确保 Port Driver 能够正确地在 Linux 操作系统上运行,因为描述中提到 "can run on ...

    Designing for Scalability with Erlang-OTP.pdf

    Designing for Scalability with Erlang-OTP.pdf Designing for Scalability with Erlang-OTP.pdf Designing for Scalability with Erlang-OTP.pdf

    erlang mochiweb-test demo

    这个 "erlang mochiweb-test demo" 压缩包很可能是为了展示如何使用 Mochiweb 在 Erlang 中构建一个简单的 Web 应用程序或测试环境。 Mochiweb 的核心组件包括以下几个部分: 1. **HTTP 服务器**:Mochiweb 提供了...

    testing-erlang-book, 在测试Erlang时,public 书.zip

    testing-erlang-book, 在测试Erlang时,public 书 测试 Erlang我已经创建了一本关于使用QuickCheck和Erlang的新书,你可以在这里找到 http://www.erlang-quickcheck-book.com/。关于本书Erlang已经经存在很长一段...

    Designing for Scalability with Erlang/OTP

    This book is what you get if you put together an Erlang enthusiast who worked on the R1 release of OTP in 1996 and a Distributed Systems specialist who discovered Erlang/OTP

    erlang nif test

    在"erlang nif test"这个项目中,我们很显然看到这是一个关于测试Erlang NIF功能的演示。 Erlang是一种面向并发、分布式计算的函数式编程语言,它的设计目标是构建高可用、容错性强的系统。NIFs是Erlang与C交互的...

    erlang test 生成 dets

    标题中的“erlang test 生成 dets”表明我们要讨论的是使用Erlang编程语言进行测试,并生成DETS(Disk-based Erlang Terms Storage)文件的过程。DETS是Erlang提供的一种持久化数据存储机制,类似于关系数据库的表,...

    Erlang中文手册

    Erlang 中文手册 译者 注...........................................................I 其它译者..........................................................II 第 1 部分 入门....................................

    Building Web Applications with Erlang

    在本段内容中,我们将会详细解析Erlang语言在构建Web应用程序方面的知识点。首先,我们需要了解Erlang语言的特性和优势,然后逐步探索如何使用Erlang构建可扩展的系统,并通过RESTful架构提供Web服务。在此基础上,...

    [Erlang] 网络应用开发 (Erlang 实现) (英文版)

    [奥莱理] Building Web Applications with Erlang Working with REST and Web Sockets on Yaws (E-Book) ☆ 出版信息:☆ [作者信息] Zachary Kessin [出版机构] 奥莱理 [出版日期] 2012年06月14日 [图书页数] ...

    Building Web Applications with Erlang.2012.英文

    1. Erlang是一种用于构建可伸缩系统的编程语言,特别适合于开发需要持续运行的应用程序。它广泛应用于电信行业,但其用途远远不限于此。Erlang语言的无类型特性(Lack of Types)和开放电信平台(OTP—For More Than...

    erlang编程 Introducing Erlang

    **Erlang编程:Introducing Erlang** Erlang是一种函数式编程语言,由爱立信在1986年开发,主要用于构建高可用性、容错性和并发性的分布式系统。"Introducing Erlang"是Simon St. Laurent撰写的一本入门级教程,...

    ErlangB和ErlangC计算工具(exe可执行文件+excel两个)

    Erlang B和Erlang C是电信领域中两种重要的流量模型,用于预测和分析通信系统中的呼叫处理能力和拥塞情况。这两个模型由丹麦工程师Agner Krarup Erlang在20世纪初提出,至今仍广泛应用于现代通信网络的设计与优化。 ...

    erlang25.0 windows版本

    Erlang是一种高级编程语言,特别适用于并发、分布式和实时系统。它由Ericsson公司开发,主要用于构建高可用性、容错性和可扩展性的软实时系统。Erlang的25.0版本是该语言的一个更新,针对Windows操作系统进行了优化...

    erlang_版本24.3.4.4

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson开发,主要用于构建高可用性、分布式和实时系统。版本24.3.4.4是Erlang的一个更新版本,包含了对先前版本的改进和修复。Erlang以其强大的错误...

Global site tag (gtag.js) - Google Analytics