11. Using Common Test for Large-Scale Testing
11使用通用测试进行大规模测试
11.1总则
大规模的自动化测试需要并行运行多个独立的测试会话。这是通过Common Test
在一个或多个主机上运行一些节点,测试不同的目标系统来完成的。独立配置,启动和控制测试节点可能是一项繁琐的操作。为了帮助这种自动化的大规模测试,Common Test
提供了一个主测试节点组件Common Test
Master,它处理分布式Common Test
节点系统中的中央配置和控制。
在Common Test
主服务器一个专用的Erlang节点上运行,采用分布式二郎神与任意数量的通信Common Test
测试节点,每个节点托管一个普通Common Test
的服务器。测试规范被用作输入,以指定在哪些测试节点上测试什么,使用哪种配置。
Common Test
主服务器到HTML日志文件类似于定期写入进度信息Common Test
的服务器。日志包含测试统计信息以及由每个独立Common Test
服务器写入的日志文件的链接。
该Common Test
主API由模块输出ct_master
。
11.2使用
Common Test
Master需要所有测试节点位于同一网络上并共享一个通用文件系统。Common Test
Master无法自动启动测试节点。Common Test
Master 必须提前启动节点才能启动它们的测试会话。
通过调用ct_master:run(TestSpecs)
或启动测试ct_master:run(TestSpecs, InclNodes, ExclNodes)
TestSpecs
是测试规范文件(字符串)的名称或测试规范列表。如果是列表,则依次处理规格(以及相应的测试)。TestSpecs
列表中的元素也可以是测试规范的列表。在测试执行之前,这样的列表中的规范被合并为一个组合规范。
例子:
ct_master:run(["ts1","ts2",["ts3","ts4"]])
在这里,“ts1”指定的测试先运行,然后运行“ts2”指定的测试,最后运行“ts3”和“ts4”指定的测试。
该InclNodes
给的说法run/3
是节点的名称列表。函数就像run/3
运行测试TestSpecs
一样run/1
,但也会在TestSpecs
没有明确标记特定节点名称的情况下进行任何测试,并在其中列出的节点上执行测试InclNodes
。通过run/3
这种方式,可以在大规模测试环境中使用任何测试规范(带或不带节点信息)。
ExclNodes
是要从测试中排除的节点的列表。也就是说,如果该节点ExclNodes
在运行时列出,则测试规范中指定的在特定节点上运行的测试不会执行。
如果Common Test
主设备最初无法连接到测试规范或InclNodes
列表中指定的任何测试节点,则会提示操作员使用该选项重新开始(在手动检查有问题的节点的状态之后),无需运行缺少节点,或放弃操作。
当测试开始时,Common Test
Master显示信息以控制涉及的节点。Common Test
Master还报告测试完成时是成功还是失败。如果连接丢失到某个节点,则该节点上的测试将被视为完成。Common Test
主站不会尝试重新建立与故障节点的联系。
在任何时候,要获取测试节点的当前状态,请调用函数ct_master:progress()
。
要停止一个或多个测试,请使用功能ct_master:abort()
(停止全部)或ct_master:abort(Nodes)
。
有关Common Test
主API的详细信息,请参阅模块ct_master
。
11.3测试规范
用作主站输入的测试规范Common Test
与用作常规Common Test
服务器输入的规范完全兼容。该语法Test Specifications
在“运行测试和分析结果” 部分中进行了介绍。
所有测试规范术语都可以有一个NodeRefs
元素。该元素指定要在哪个或哪些节点上执行配置操作或测试。NodeRefs
定义如下:
NodeRefs = all_nodes | [NodeRef] | NodeRef
NodeRef = NodeAlias | node() | master
NodeAlias
(atom()
)在测试规范中用作对节点名称的引用(所以节点名称只需要声明一次,这也可以使用常量来实现)。该别名用以下node
术语声明:
{node, NodeAlias, NodeName}
如果NodeRefs
具有该值all_nodes
,则在所有指定的测试节点上执行操作或测试。(声明没有NodeRefs
元素的术语具有相同的效果)。如果NodeRefs
具有该值master
,则该操作仅在Common Test
主节点上执行(即设置日志目录或安装事件处理程序)。
考虑一下部分中的示例Test Specifications
在运行测试和分析结果一节中,现在扩展了节点信息,并打算由Common Test
Master:
{define, 'Top', "/home/test"}.
{define, 'T1', "'Top'/t1"}.
{define, 'T2', "'Top'/t2"}.
{define, 'T3', "'Top'/t3"}.
{define, 'CfgFile', "config.cfg"}.
{define, 'Node', ct_node}.
{node, node1, 'Node@host_x'}.
{node, node2, 'Node@host_y'}.
{logdir, master, "'Top'/master_logs"}.
{logdir, "'Top'/logs"}.
{config, node1, "'T1'/'CfgFile'"}.
{config, node2, "'T2'/'CfgFile'"}.
{config, "'T3'/'CfgFile'"}.
{suites, node1, 'T1', all}.
{skip_suites, node1, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
{skip_cases, node1, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
{skip_cases, node1, 'T1', t1C_SUITE, [test1], "Ignore"}.
{suites, node2, 'T2', [t2B_SUITE,t2C_SUITE]}.
{cases, node2, 'T2', t2A_SUITE, [test4,test1,test7]}.
{skip_suites, 'T3', all, "Not implemented"}.
本示例指定与原始示例相同的测试。但现在如果开始一个呼叫ct_master:run(TestSpecName)
,试验t1
是在节点执行ct_node@host_x
(node1
),测试t2
的ct_node@host_y
(node2
)和测试t3
上都node1
和node2
。配置文件t1
是只读的node1
并且配置文件t2
只node2
,而配置文件t3
读取两个node1
和node2
。两个测试节点都将日志文件写入同一个目录。(但是,Common Test
主节点使用与测试节点不同的日志目录。)
如果测试会话,而不是用一个电话开始ct_master:run(TestSpecName, [ct_node@host_z], [ct_node@host_x])
,结果是测试t1
不运行ct_node@host_x
(或任何其他节点),而测试t3
上都运行ct_node@host_y
和ct_node@host_z
。
一个很好的特性是包含节点信息的测试规范仍然可以用作常规Common Test
服务器的输入(如部分所述Test Specifications
)。其结果是执行了指定在节点上运行的任何测试,该节点的名称与所讨论Common Test
节点的名称相同(通常ct@somehost
在使用该ct_run
程序启动时)。当然,没有显式节点关联的测试也总是执行。
11.4测试目标节点的自动启动
可以使用测试规范术语在测试目标节点上自动启动和执行初始操作init
。
支持两个子项,node_start
并且eval
。
例子:
{node, node1, node1@host1}.
{node, node2, node1@host2}.
{node, node3, node2@host2}.
{node, node4, node1@host3}.
{init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}.
{init, [node2, node3], {node_start, [{username, "ct_user"}, {password, "ct_password"}]}}.
{init, node4, {eval, {module, function, []}}}.
该测试规范宣称node1@host1
是使用用户回调函数开始callback_module:my_slave_callback/0
,和节点node1@host2
,并node2@host2
都使用默认回调模块启动ct_slave
。指定的用户名和密码用于登录远程主机host2
。另外,函数module:function/0
被评估node1@host3
,并且这个调用的结果被打印到日志中。
默认回调模块ct_slave
,具有以下特性:
- 在本地或远程主机上启动Erlang目标节点(应用程序
SSH
用于通信)。
- 能够用更多标志启动Erlang模拟器(支持任何标志
erl
)。
- 使用内部回调函数监视正在启动的节点。用于防止悬挂节点。(可配置)。
- 由从站监控主节点。如果主节点终止,则可以停止从节点。(可配置)。
- 从节点启动后执行用户功能。函数可以指定为
{Module, Function, Arguments}
元组列表。
注
一个eval
为节点,期限startup_functions
在node_start
选项列表可以指定。在这种情况下,首先启动节点,然后startup_functions
执行,最后调用指定的函数eval
。