非常教程

Erlang 20参考手册

common_test

3. Getting Started

3.1新手介绍

本节的目的是让新手开始快速编写和执行一些第一个简单的测试,并以“通过示例学习”的方式进行。大多数解释都留给后面的部分。如果你没有太多的“通过实例学习”并喜欢更多的技术细节,请继续并跳到下一节。

本节展示了编写基本测试套件并执行其测试用例是多么简单的事情(但对于许多模块测试而言,通常是非常复杂的)。阅读本用户指南中的其余部分时,这不一定很明显。

注意

为了理解这里讨论和示例的内容,我们建议您首先阅读部分Common Test Basics

3.2测试用例执行

测试用例的执行如下:

图3.1:成功和不成功的测试用例执行

对于每个Common Test被命令执行的测试用例,它会产生一个专用的进程,测试用例函数开始运行。(与测试用例进程并行,启动一个空闲等待定时器进程,该进程与测试用例进程相关联,如果定时器进程超出等待时间,则发送退出信号来终止测试用例进程。称为时间陷阱)。

在场景1中,测试用例进程在case A完成执行其测试代码而没有检测到任何错误之后正常终止。测试用例函数返回一个值并将Common Test测试用例记录为成功。

在场景2中,测试case B执行期间检测到错误。这导致测试case B函数产生一个异常,结果,测试用例进程以非正常的原因退出。Common Test将其记录为不成功(失败)测试用例。

正如你从插图中可以理解的那样,Common Test需要一个测试用例来生成运行时错误以指示失败(例如,通过导致错误的匹配错误或通过调用exit/1,最好通过帮助函数ct:fail/1,2)。测试用例函数的正常返回表示成功执行。

3.3简易测试套件

如部分所示Common Test Basics,测试套件模块实现callback functions(强制或可选)用于各种目的,例如:

  • 测试套件的init/end配置函数
  • 测试用例的init/end配置函数
  • 测试用例组的init/end配置函数
  • 测试用例

配置功能是可选的。以下示例是一个没有配置函数的测试套件,包括一个简单的测试用例,用于检查模块是否mymod存在(即可以由代码服务器成功加载):

-module(my1st_SUITE).
-compile(export_all).

all() ->
    [mod_exists].

mod_exists(_) ->
    {module,mymod} = code:load_file(mymod).

如果操作失败,则会发生错误的匹配错误,从而终止测试用例。

3.4具有配置功能的测试套件

如果您需要执行配置操作来运行测试,则可以在套件中实施配置功能。配置功能的结果是配置数据,或者Config。这是从配置函数传递给测试用例的键值元组的列表(可能通过“较低级别”的配置函数)。数据流如下所示:

图3.2:套件中的配置数据流

以下示例显示了一个测试套件,该套件使用配置函数打开和关闭测试用例的日志文件(这是一种不必要的操作,与每个测试用例无关):

 -module(check_log_SUITE).
 -export([all/0, init_per_suite/1, end_per_suite/1]).
 -export([check_restart_result/1, check_no_errors/1]).

 -define(value(Key,Config), proplists:get_value(Key,Config)).

 all() -> [check_restart_result, check_no_errors].

 init_per_suite(InitConfigData) ->
     [{logref,open_log()} | InitConfigData].

 end_per_suite(ConfigData) ->
     close_log(?value(logref, ConfigData)).

 check_restart_result(ConfigData) ->
     TestData = read_log(restart, ?value(logref, ConfigData)),
     {match,_Line} = search_for("restart successful", TestData).

 check_no_errors(ConfigData) ->
     TestData = read_log(all, ?value(logref, ConfigData)),
     case search_for("error", TestData) of
{match,Line} -> ct:fail({error_found_in_log,Line});
nomatch -> ok
     end.

通过解析日志文件,测试用例验证我们的SUT已成功地重新启动,并且没有打印意外错误。

要在最近的测试套件中执行测试用例,请在UNIX / Linux命令行中输入以下内容(假定套件模块位于当前工作目录中):

$ ct_run -dir .

或:

$ ct_run -suite check_log_SUITE

要使用Erlang shell来运行我们的测试,您可以评估以下调用:

1> ct:run_test([{dir, "."}]).

或:

1> ct:run_test([{suite, "check_log_SUITE"}]).

运行测试的结果以HTML格式(存储在不同级别的独特日志目录中)的日志文件中打印。下图显示了日志文件结构:

图3.3:HTMLLogFile结构

3.5个问题和答案

在阅读本节以及相应的提示和答案链接后,您可能会遇到一些问题:

  • 问题: “我如何以及在哪里可以为我的测试指定变量数据,这些变量数据不得在测试套件中进行硬编码(例如主机名,地址和用户登录数据)?” 答:请参见章节External Configuration Data
  • 问题: “是否有办法在一个会话中声明不同的测试并运行它们,而无需编写自己的脚本?此外,这些声明是否可用于回归测试?”

答:见部分Test Specifications在部分运行测试和分析结果。

  • 问题: “可以自动重复测试案例和/或测试运行吗?” 答案:Test Case Groups在章节Running Tests和参考手册中详细了解并阅读有关开始标记/选项的内容。
  • 问题:Common Test按顺序或并行地执行我的测试用例?“

答:Test Case Groups在部分写作测试套件。

  • 问题: “timetraps的语法(前面提到过)是什么,以及如何设置它们?” 答:这在Timetrap Time-OutsWrite Test Suites一节的部分中有解释。
  • 问题:“有哪些功能可用于日志记录和打印?”

答:Logging在部分写作测试套件。

  • 问题: “我的测试需要数据文件,我最好在哪里存储它们?” 答:参见Data and Private Directories
  • 问题:“我可以先举一个测试套件的例子吗?”

答:Welcome!

您可能希望现在开始您自己的第一个测试套件,同时深入了解Common Test用户%27S指南和参考手册。关于本节中介绍的内容,还有很多需要学习的地方。还有许多其他有用的特性需要学习,所以请继续到其他部分,并有乐趣。

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1