本主题说明了如何定义用于跨平台测试的自定义测试执行流(例如,用于使用交叉编译器构建测试,然后执行特定于平台的操作以进行部署、测试执行和结果收集)。

本节包括:

了解测试执行流

当您运行测试配置集以执行测试时,C/C++test 会执行一系列操作,这些操作通常会导致将单元测试结果加载到 C/C++test 用户界面中。这些操作在测试流定义中指定,该定义以 XML 格式存储并保存为测试配置的一部分。所有执行测试执行的内置测试配置都具有相应的预配置测试流定义。 

除了提供专为基于主机的测试而设计的预配置执行流之外,C/C++test 还允许您自定义测试流,以提供一种使用非标准环境的简便方法。 

自定义测试执行流

您可以使用【测试配置】管理器部分中的 执行> 常规> 执行详细信息 提供的编辑器来配置测试执行流参数以满足您的特定需求。

在大多数情况下,无需创建执行流的自定义版本,因为内置的【测试配置】可以轻松编辑最关键且经常修改的流属性。 

为用户定义的测试配置定义自定义执行流:

  1. 选择 Parasoft> 测试配置 以打开【测试配置】面板。
  2. 打开 执行> 常规 选项卡。
  3. 要修改现有属性,请直接在属性表中编辑参数。



    如果在表中单击鼠标右键,则可以使用以下命令: 
    • 恢复默认值
    • 插入文件位置
    • 插入目录位置
  4. 要调整表格中当前未显示的测试流属性(例如,您希望经常修改的属性):
    1. 选择适当的流程,然后单击 编辑
    2. 在测试流中找到该属性定义。它应该如这样:

      <SetProperty key="property_key"
      value="property_default_value"
    3. 添加两个附加属性 — uiEditable="true"displayName="user_friendly_name" — 这样属性定义如下所示

      <SetProperty key="property_key"
      value="property_default_value"
      uiEditable="true"
      displayName="This is a customizable property" />

      由于 uiEditable="true" 属性已添加到SetProperty 流步骤, 因此该属性将在属性表中可自定义。将使用displayName属性的值在此处列出。Value 属性将用作默认值。

    4. 单击 确定 以保存修改的文件。XML 文档将被验证。如果在验证过程中发现任何问题,将予以报告。
  5. 点击 应用,然后 确定 保存修改后的测试配置。

然后,自定义项将与测试配置一起保存。

定义自定义测试执行流:高级

我们建议您首先尝试修改属性列表(如上所述),然后(如果需要其他流自定义)定义自定义测试流程。

自定义测试执行流定义以 XML 格式存储,并保存为【测试配置】的一部分(这便可以在整个团队之间共享它)。通常,此类定义描述了在非标准环境中执行单元测试所需的步骤顺序。它们也可以用于启动任何命令行实用程序。实际上,自定义测试流定义可以包括 C/C++test 内部操作或作为操作系统中的进程启动的外部实用程序。可以通过以下方式修改默认测试流程:

  • 删除现有步骤
  • 添加新步骤
  • 自定义现有步骤的参数

为用户定义的测试配置定义自定义执行流:

  1. 选择 Parasoft> 测试配置 以打开【测试配置】面板。
  2. 展开 内建> Unit Testing  文件夹。
  3. 右键单击 Build Test Executable ,然后从快捷菜单中选择 复制 。




  4. 确保已选择 用户自定义> Build Test Executable 。
  5. 输入此测试配置的新名称(例如,诸如构建<target> 可执行文件之类的名称)。
  6. 打开 执行> 符号 选项卡,然后清除复选框找到的 使用桩函数

    注释

    如果在不禁用使用桩函数 选项的情况下构建测试可执行文件,则在构建测试可执行文件时会出现以下错误:

    错误预处理文件 "C:\Program 
    Files\ParaSoft\C++test9.0\plugins\com.parasoft.xtest.libs.cpp.win32.x86_9.0.4.43\ os\win32\x86\etc\safestubs\safe_stubs_Win32.c":  
    
    程序以代码退出:1
  7. 编辑测试流程:
    1. 打开 执行> 常规 选项卡。
    2. 测试执行流 组合框中选择自定义流 (需要许可证) 然后单击 编辑 按钮。
    3. 通过从 可用的内置测试执行流 框中选择一个现有的测试流, 单击 恢复, 然后编辑该测试流的 XML,输入修改后的测试流。请参阅Customizing the Test Execution Flow Definition - Example以获取有关如何修改流定义的详细信息。
  8. 单击 确定 以保存修改的文件。XML 文档将被验证。如果在验证过程中发现任何问题,将予以报告。
  9. 点击 应用,然后 确定 保存修改后的测试配置。

使用套接字通信通道定义测试流

在有 TCP/IP 套接字可用的嵌入式环境中,通常使用它们来自动化测试流程。使用套接字通信通道执行测试通常涉及:

  1. 通过运行适当的测试配置来构建可执行测试。
    • 如有必要,修改此测试配置的测试流以适合您的特定需求。在大多数情况下,唯一的区别是生成的可执行文件的扩展名和与网络相关的特定值(端口、IP 号等)的设置。

      示例测试流修改

      <SetProperty key="results_port" value="2567" />
      <SetProperty key="coverage_port" value="2568" />
      <TestRunnerWithSocketsGenerationStep
      testSuiteConfigFile="${cpptest:testware_loc}/testsuites.xml" 
      testrunnerCFile="${cpptest:testware_loc}/cpptest_testrunner.c" 
      testrunnerCppFile="${cpptest:testware_loc}/cpptest_testrunner.cpp" 
      resultsHost="10.9.1.30"
      testLogPort=${cpptestproperty:results_port}
      covLogPort=${cpptestproperty:coverage_port}
      />
      <CompileStep />
      <LinkStep result="${cpptest:testware_loc}/${project_name}Test.foo"/>

      第一部分 (TestRunnerWithSocketsGenerationStep) 准备测试框架以使用特定的网络值(IP、端口–从属性文件获取)运行。 

      第二部分编译可执行测试。

      最后一部分(LinkStep)负责调用链接器,以获取最终的测试执行程序(此处已调用 $ {project_name}Test.foo;您将需要更改扩展名以匹配系统的详细信息)。

      请注意应该使用 TestRunnerWithSocketsGenerationStep 代替默认的 TestRunnerGenerationStep。

  2. 将可执行测试部署到目标设备。
    • 此步骤不能总是自动化的。如果您的系统不支持自动部署,则可能需要将可执行测试手动部署到目标设备。否则,您可以使用 FTP 协议,同步工具或系统提供的任何其他方式。
  3. 运行 C/C++test SocketListener 工具,该工具配置为通过 socket 通信通道收集结果。
    • 有关如何执行此步骤(和步骤 4)的详细信息,请参阅以下提示框。
    • 运行该程序后,它将开始等待结果到达指定端口。
  4. 启动测试可执行文件。初始化后,它将打开两个端口并尝试将数据发送到 C/C++test。该数据将由监听代理收集,并加载到 C++test 中以进行进一步分析。
    • 有关如何执行此步骤(和步骤 3)的详细信息,请参阅以下提示框。
示例测试流步骤包括了步骤 3 和 4
<CustomStep
id="run_socket_listeners"
label="Running Socket Listeners..."
commandLine="&quot;java&quot; -cp &quot;${cpptest:cfg_dir}/../lib/source/socket_listener&quot;
SocketListener --channel &quot;${cpptestproperty:results_port}@$
{cpptest:testware_loc}/cpptest_results.tlog&quot; --channel 
&quot;${cpptestproperty:coverage_port}@$
{cpptest:testware_loc}/cpptest_results.clog&quot; -sf 
&quot;${cpptest:testware_loc}/sync_file&quot; -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="true"
/>
<CustomStep
id="run_synchronization"
label="Running Synchronization..."
commandLine="&quot;java&quot; -cp &quot;${cpptest:cfg_dir}/../lib/source/socket_listener&quot;
Synchronize -sf &quot;${cpptest:testware_loc}/sync_file.init&quot; -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="false"
/>
<CustomStep
id="run_test_exec"
label="Running Tests..."
commandLine="${cpptest:testware_loc}/${project_name}Test.foo" workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="false"
/>
<CustomStep
id="run_synchronization"
label="Running Synchronization..."
commandLine="&quot;java&quot; -cp &quot;${cpptest:cfg_dir}/../lib/source/socket_listener&quot;
Synchronize -sf &quot;${cpptest:testware_loc}/sync_file.final&quot; -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="false"
/>

上面的步骤执行以下操作(以列出的顺序):

  • 运行 SocketListener Java 类,该类配置为监听预定义的端口。它还使用 -sf 开关创建同步文件(在本例中为 sync_file)。
  • 运行 Synchronize Java 类。请注意,第一步具有 runInBackground="true" 属性;这意味着下一步无需等待则可以运行至该步骤完成。这是必需的,因为 SocketListener 直到监听停止才完成。当 SocketListener 初始化并准备好接收结果时,它将创建同步文件(在本例中为 sync_file.init),以便 run_synchronization 步骤可以完成并且可以运行 test_exec。这样可以防止因没有正确初始化监听代理的情况下开始执行测试导致的测试结果丢失。

  • 然后启动 run_test_exec 步骤,并运行可执行测试。它连接到 SocketListener 并通过 TCP/IP 协议传输结果。
  • 传输结束后,SocketListener 将创建 .tlog 和 .clog 文件(测试和覆盖率信息文件)。另一个同步文件(sync_file.final)反馈给同步步骤,所有步骤均已完成,并且可以读取结果。

选择外部嵌入式调试模式

选择外部嵌入式调试模式只能通过直接修改 Test Flow 配方来完成。在第一个 <RunnableExecution> 部分的开头附近的某处,将以下行插入到 Test Flow 方法中;其他未发布的属性:

<SetProperty key="emb_dbg" value="true" />

有关示例,请查看支持外部嵌入式模式的环境的内置测试配置(请参阅相应章节)。

有关外部嵌入式调试模式的信息,请参见 调试测试用例

更改测试入口点函数

入口点宏控制测试入口点。默认情况下调用 main()。但是,有时只能从正在测试的程序的不同位置调用测试,或者需要以特殊方式调用。您可以使用以下宏对此进行控制:

名称说明
CPPTEST_EPT_main如果定义,则将 'int main(int, char*[])’用作入口点。
CPPTEST_EPT_wmain如果定义,则将 'int wmain(int, wchar_t*[])’ 用作入口点。
CPPTEST_EPT_WinMain如果定义,则将 'int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPSTR, int)’ 用作入口点。
CPPTEST_EPT_WinMain如果定义,则将 'int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)’ 用作入口点。
CPPTEST_EPT_void_main如果定义,则将 'void main(int, char*[])’用作入口点。
CPPTEST_EPT_main_no_args如果定义,则将 'int main(void)’用作入口点。
CPPTEST_EPT_void_main_no_args如果定义,则将 'void main(void)’用作入口点。
CPPTEST_ENTRY_POINT_C_LINKAGE如果定义,则主函数声明如果用 c++ 代码编译,则以 'extern "C"’ 开头。

您还可以定义 CPPTEST_ENTRY_POINT 宏。如果将定义此宏,则生成的主函数将如下所示:

    CPPTEST_ENTRY_POINT_RETURN_TYPE 
CPPTEST_ENTRY_POINT(CPPTEST_ENTRY_POINT_ARGS)
{
	CppTest_Main(CPPTEST_ENTRY_POINT_ARGC, CPPTEST_ENTRY_POINT_ARGV); 
	CPPTEST_ENTRY_POINT_RETURN_STATEMENT
}

CPPTEST_ENTRY_POINT_RETURN_TYPE, CPPTEST_ENTRY_POINT_ARGS, CPPTEST_ENTRY_POINT_ARGC, CPPTEST_ENTRY_POINT_ARGV and CPPTEST_ENTRY_POINT_RETURN_STATEMENT 具有以下可以重新定义的默认值:

名称
CPPTEST_ENTRY_POINT_RETURN_TYPEint
CPPTEST_ENTRY_POINT_ARGSvoid
CPPTEST_ENTRY_POINT_ARGC0
CPPTEST_ENTRY_POINT_ARGV0
CPPTEST_ENTRY_POINT_RETURN_STATEMENTreturn 0;

您还可以定义 CPPTEST_ENTRY_POINT 宏。定义此宏可防止生成主例程。在这些情况下,您需要调用 CppTest_Main(0, 0) 函数来执行测试用例。 

您必须在包含CppTest_Main(0, 0)调用的源文件中包括 cpptest.h 头文件。不要从单元测试期间调用的函数中调用CppTest_Main(0, 0) 。这样做会导致循环,CppTest_Main(0, 0) 被无限调用。 

确保使用 PARASOFT_CPPTEST 宏控制对源文件的更改。示例:

#ifdef PARASOFT_CPPTEST 
#include "cpptest.h"
#endif
...
#ifdef PARASOFT_CPPTEST
    CppTest_Main(0, 0); 
#endif

可以在【项目选项】的【构建设置】的【编译器选项】区域中设置这些宏。


有关项目选项的详细信息,请参见设置项目和文件选项

自定义测试执行流定义-示例

这是基于 Windows 主机的单元测试的示例测试流程:

<?xml version="1.0" encoding="UTF-8"?>
<FlowRecipeTemplate toolName="C++test" formatVersion="1.0">
	<Name>Default host-based unit testing</Name>
 
	<RunnableExecution>
 
	<SetProperty key="stub_config_file" value="${cpptest:testware_loc}/stubconfig.xml" />
	<SetProperty key="stub_config_header_file" value="${cpptest:testware_loc}/cpptest_stubconfig.h" />
 
	<TestCaseFindingStep
		testSuiteConfigFile="${cpptest:testware_loc}/testsuites.xml" allowNoTestCasesRun="false"
	/>
 
	<PrecompileStep />
		<AppendIncludedTestCases />
		<HarnessInstrumentationStep /> 
		<ReadStaticCoverageStep />
		<SendStaticCoverageStep />
		<UserStubsInstrumentationStep />
		<ReadSymbolsDataStep /> 
		<LsiStep />
		<ReadLsiConfigStep />
 
	<AnalyzeMissingDefinitions stopOnUndefined="true" generateS-tubs="false" />
	
	<ConfigureStubs />
 
	<CreateStubConfigHeader />
 
	<TestRunnerGenerationStep
		testSuiteConfigFile="${cpptest:testware_loc}/testsuites.xml"
		testrunnerCFile="${cpptest:testware_loc}/cpptest_testrunner.c"
		testrunnerCppFile="${cpptest:testware_loc}/cpptest_testrunner.cpp"
		testLogFile="${cpptest:testware_loc}/cpptest_results.tlog" 
		covLogFile="${cpptest:testware_loc}/cpptest_results.clog"
	/>
 
	<CompileStep />
 
	<LinkStep result="${cpptest:testware_loc}/${project_name}Test.exe"/>
 
	</RunnableExecution>
	     <ExecuteTestsExecution>
			<RemoveFileStep
				file="${cpptest:testware_loc}/cpptest_results.tlog"
			/>
 
	<CustomStep
		id="run_tests"
		label="Running tests..."
		commandLine="&quot;${cpptest:testware_loc}/${project_name}Test.exe&quot; --start-after=${cpptestprop-erty:test_case_start_number}"
		workingDir="${cpptest:test_exec_work_dir}"
		result="${cpptest:testware_loc}/cpptest_results.tlog" 
		timeoutTrackFile="${cpptest:testware_loc}/cpptest_results.tlog" 
		timeoutInfoProperty="test_exec_timeouted"
		runInDebugger="${cpptest:run_in_debugger}"
	/>
 
	<ReadTestLogStep
		testLogFile="${cpptest:testware_loc}/cpptest_results.tlog" timeoutInfoProperty="test_exec_timeouted"
	/>

	<ReadDynamicCoverageStep
		covLogFile="${cpptest:testware_loc}/cpptest_results.clog"
	/>
 
	   </ExecuteTestsExecution>
		
		   <RunnableExecution>
				     <ClearTempCoverageData />
							</RunnableExecution>
</FlowRecipeTemplate>

注释

  • runInBackground 指定该步骤应在后台还是在前台运行。设置为 true 时,它允许立即执行以下操作,而无需等待上一个操作完成。设置为 false 时,正在运行的进程必须先完成,然后才能开始下一个顺序。默认值是 false

如果正确添加了自定义(交叉)编译器定义,并且将预构建的主机 C/C++test 运行时库替换为指定目标的交叉编译库(请参阅 使用交叉编译器配置测试),那么 C/C++test 应该能够成功执行几乎所有操作-除了用于启动可执行测试和加载测试日志文件的步骤。步骤如下所述。

<CustomStep
id="run_tests"
label="Running tests..."
commandLine="&quot;${cpptest:testware_loc}/${project_name}Test.exe&quot;" workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.tlog"
runInBackground="false"
timeoutTrackFile="${cpptest:testware_loc}/cpptest_results.tlog"
/>
<ReadTestLogStep
testLogFile="${cpptest:testware_loc}/cpptest_results.tlog"
/>
<ReadDynamicCoverageStep
covLogFile="${cpptest:testware_loc}/cpptest_results.clog"
contextID=""
/>

您可能需要用适合您正在使用的嵌入式环境的步骤替换这些步骤。例如,假设您的目标是支持 FTP 但不支持远程执行(不提供 rsh 或任何类似实用程序)的基于嵌入式 Linux 的 Power PC 板。在这种情况下,测试的一般模式可以是:

  1. 准备可执行测试并执行交叉构建(这应该由默认的一组操作来处理,但是要使用交叉编译器)。
  2. 使用 FTP 将可执行测试部署到目标板上。
  3. 等待测试执行完成(可执行测试将由位于目标上的代理启动)。
  4. 使用 FTP 下载测试结果。

例如,让我们考虑一下此 schema 的简单实现。

如果这是已有步骤:

<CustomStep
id="run_tests"
label="Running tests..."
commandLine="&quot;${cpptest:testware_loc}/${project_name}Test&quot;" workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.tlog" runInBackground="false"
timeoutTrackFile="${cpptest:testware_loc}/cpptest_results.tlog"
/>

您可以这样:

<CustomStep
id="deploy_test"
label="Deploying tests..."
commandLine="&quot;/home/machine/user/cptests/helper/Store.py${project_name}Test&quot;"
workingDir="${cpptest:testware_loc}"
/>
<CustomStep
Customizing the Test Flow 341
id="sleep"
label="Waiting for test execution..." 
commandLine="sleep 30" 
workingDir="${cpptest:testware_loc}" 
result="cpptest_results.tlog" 
runInBackground="false"
/>
  • FTP 传输是使用帮助 python 脚本自动完成的,该脚本在本主题的末尾提供。

当测试执行流到达“sleep”步骤时,可执行测试应该已经部署到目标板上。Sleep 命令是提供微细微的同步所必需的,这样下一步(下载测试结果)就不会在测试执行完成之前开始。 

在生产环境中,您通常希望实现更准确的同步(例如,在测试执行完成后借助文件标记创建)。在此示例中,我们将简单地使用 sleep,它会在尝试访问目标平台上的结果文件之前停止流执行。它在目标平台上需要一个简单的代理,即一个等待上传的可执行文件测试并启动它的代理。下面是这种脚本的简单示例:

#!/bin/bash
while [ 1 ]
do
if [ -e *Test ]; then
# Give it some time to finish upload...
# test executable transfer may be in progress
echo "Found test executable, waiting for upload to be finished..." sleep 10
echo "Cleaning up before tests..."
rm results.*log
echo "Adding exe perm .... to *Test"
chmod +x *Test
# execute
echo "Executing *Test"
./*Test
# Remove test executable
echo "Removing *Test"
rm -f ./*Test
else
echo "Test executable not detected ..." fi
echo "Sleeping..."
sleep 3
done

同样它不执行任何同步; 它只是寻找文件系统中出现的指定文件名模式。出现后,它会等待一些额外的时间来完成上传(可以通过在上传完成后在主机端创建文件标记来代替它),然后启动测试可执行文件,并创建结果文件(带有测试结果和包含覆盖率结果的 results.clog)。这些文件需要下载回主机并加载到 C++test 中。为此,您需要修改另一部分测试流定义。在执行这些“读取日志”步骤之前...

<ReadTestLogStep
testLogFile="${cpptest:testware_loc}/cpptest_results.tlog" />
<ReadDynamicCoverageStep
covLogFile="${cpptest:testware_loc}/cpptest_results.clog" contextID=""
/>

您将添加自定义步骤,以从目标平台下载结果文件;例如:

<CustomStep
id="results_dwl"
label="downloading tests results..."
commandLine="&quot;/home/machine/user/cptests/helper/Get.py cpptest_results.tlog&quot;"
workingDir="${cpptest:testware_loc}"
result="cpptest_results.tlog"
runInBackground="false"
/>
<CustomStep
id="coverage_dwl"
label="downloading coverage results..."
commandLine="&quot;/home/machine/user/cptests/helper/Get.py cpptest_results.clog&quot;"
workingDir="${cpptest:testware_loc}"
result="cpptest_results.clog"
runInBackground="false"
/>

进行此设置后,您应该能够在目标设备上执行单元测试并自动执行完整的测试循环。根据开发环境的不同,可以应用此示例的多种变形。 

示例 FTP 自动化脚本

本节提供了用于自动执行 FTP 操作的示例 Python 脚本。

Store.py

#!/usr/bin/python
 
import sys
print "Argv = ", sys.argv
from ftplib import FTP
ftp = FTP('10.9.1.36', 'user', 'pass') ftp.set_debuglevel(1)
print ftp.getwelcome()
file = open(sys.argv[1], "rb")
try:
	     ftp.storbinary("STOR %s" % sys.argv[1], file)
finally:
	     file.close()      
		ftp.quit()

Get.py

#!/usr/bin/python
 
import sys
print "Argv = ", sys.argv 
if len(sys.argv) < 2:
     print "Too few arguments"
from ftplib import FTP
ftp = FTP('10.9.1.36', 'user', 'pass') ftp.set_debuglevel(1)
print ftp.getwelcome()
file = open(sys.argv[1], "wb")
try:
     ftp.retrbinary("RETR %s" % sys.argv[1], file.write)
finally:
     file.close() 
ftp.quit()

测试流说明和示例

执行控制元素

这些是每个配方的最高级别的元素('FlowRecipeTemplate' 文档根目录除外)。它们是执行流步骤(命令)的容器:步骤必须放置在其上下文中并在其中按顺序执行。然而,它们不能被嵌套。引入一个新的需要关闭其之前一个。

RunnableExecution

无条件执行包含的命令。

示例:

<RunnableExecution>
    <Echo msg="Hello world!" /> 
</RunnableExecution>"

ConditionalExecution

有条件地执行包含的命令。当测试值包含稍后描述的 C/C++test 执行流变量之一时,此命令很有用。

属性: 

  • value - 测试值(要测试的值)。
  • equals - 测试值必须匹配的比较值。无法与 'notEquals’共存。
  • notEquals - 测试值不匹配的比较值。无法与 'equals’共存。

示例:

 <ConditionalExecution value="${cpptest:os}" equals="unix">
     <Echo msg="This is UNIX-like OS." /> 
</ConditionalExecution>"

ExecuteTestsExecution

循环执行包含的命令,直到执行完所有测试用例。仅当包含测试执行步骤(启动可执行测试 'CustomStep' ) 后跟 'ReadTestLogStep'时,此元素才有用/有效。{cpptestproperty:test_case_start_number} 变量内部会自动更新,并将其传递到可执行测试的'--start-after=' 参数。

示例:

示例
<ExecuteTestsExecution>
    <CustomStep commandLine="&quot;${cpptest:testware_loc}/
	${project_name}Test.exe&quot; --start-after=${cpptestprop-erty:test_case_start_number}"
...other attributes... /> 
    <ReadTestLogStep testLogFile="${cpptest:testware_loc}/cpptest_results.tlog" />
</ExecuteTestsExecution>"

命令

AnalyzeMissingDefinitions

内部步骤,用于分析有关缺失符号的信息。如果设置了适当的属性,它也可以用于为丢失的符号自动生成桩函数。如果(在生成可选桩函数之后)仍然缺少一些符号,如果在【测试配置】中选中了【执行->符号->执行早期检查潜在的链接器问题】选项,将停止执行流程。

属性:

  • generateStubs -- 如果定义为 "true",将为缺少的符号生成自动桩函数。默认情况下,它设置为 "true”。
  • generateUserStubs -- 如果定义为 "true",则将打开桩函数向导以启用缺少符号的用户桩函数的定义。默认情况下,它设置为 "true”。

示例:

     <AnalyzeMissingDefinitions generateStubs="true" />

AppendIncludedTestCases

将包含的测试套件文件与适当的项目源文件捆绑在一起的内部步骤。

示例:

      <AppendIncludedTestCases />

ClearTempCoverageData

内部步骤用于清除临时的静态和动态覆盖率数据。如果不需要存储静态覆盖率数据以备将来使用,则应将其包括在执行流的末尾。如果您有两个要按顺序运行的执行流程配方(例如,“构建可执行测试”和“读取测试结果”),则仅第二个应在最后包含 ClearTempCoverageData 步骤。

示例:

     <ClearTempCoverageData />

CompileStep

内部步骤用于编译要链接到可执行测试中的检测源文件。

示例:

     <CompileStep />

ConditionalStop

如果给定条件满足或不满足(取决于属性),则停止测试执行流

弃止的 - 在后续版本的 C++test 中将删除此命令。请改用 'ConditionalExecution’控制元素和无条件 'Stop’ 的组合。

属性:

  • property -- 要检查的执行流属性的名称。
  • Equals -- 当属性具有指定的值时,执行停止。此属性是可选的。
  • notEquals -- 当 property 的值不是指定的值时,执行将停止。此属性是可选的。

示例:

     <ConditionalStop property="test_exec_timeouted" equals="true" />

ConfigureStubs

用于创建桩函数配置 xml 文件的内部步骤。结果文件的位置由"stub_config_file"执行流属性控制。

示例:

     <ConfigureStubs />

CustomStep

运行外部可执行文件。

属性:

  • commandLine -- 定义要执行的命令行。
  • workingDir -- 为创建的进程定义工作目录。
  • runInBackground -- 如果设置为 "true",则进程将异步运行。此属性是可选的。默认情况下,它设置为 "false"。
  • runInDebugger -- 如果设置为 "true”,则按【测试配置】中的配置运行调试器。此属性是可选的。默认情况下,它设置为 "false"。
  • okExitCode -- 如果指定,将检查进程的退出代码,并在失败的情况下停止测试执行流。此属性是可选的。
  • stdIn -- 如果指定,提供的文件的内容将用作该进程的标准输入。此属性是可选的。
  • stdOut -- 如果指定,将进程中的 stdout 写入提供的文件中。此属性是可选的。
  • stdErr -- 如果指定,将进程中的 stdout 写入提供的文件中。此属性是可选的。此属性是可选的。
  • responseFileSupported -- 告诉进程是否支持从 @file 指定的响应文件中读取命令行参数。在这种情况下,当进程命令行超过最大长度(由 com.parasoft.xtest.common.process.maxcmdlength Java 参数指定;默认值为 32000)时,命令行参数将通过响应文件传递给进程。此属性是可选的。默认情况下,它设置为 "false"。
  • dependencyFiles -- 定义进程依赖文件。它与 "result” 属性一起使用,以确定在命令行未更改时是否可以将步骤跳过为 "up-to-date”,因为之前的运行和结果文件比所有依赖文件都新。此属性是可选的。
  • result --定义进程结果文件。它与 "dependencyFiles” 属性一起使用,以确定在命令行未更改时是否可以将步骤跳过为 "up-to-date”,因为之前的运行和结果文件比所有依赖文件都新。此属性是可选的。
  • id -- 指定步骤的标识符。
  • label -- 指定步骤的标签(将在 C/C++test 控制台中打印)。
  • bypassConsole -- 如果设置为 "true",该过程的输出不会打印在 C/C++test 控制台上。此属性是可选的。默认情况下,它设置为 "false"。
  • timeoutTrackFile -- 如果指定,C/C++test 将使用在测试配置中为运行可执行文件指定的超时。将定期检查指定的文件,如果在超过指定的超时时间内未对其进行修改,则该进程将停止。此属性是可选的。
  • timeoutInfoProperty -- 指定发生超时时要设置为 "true”的测试单元属性的名称。此属性是可选的。

示例:

<CustomStep
	id="ctdt_nm"
	label="CTDT Generation - extracting symbols..."
	commandLine="&quot;${cpptestproperty:nm}&quot; -g ${cpptest:test_objects_quoted}"
	workingDir="${cpptest:testware_loc}"
	stdOut="${cpptest:testware_loc}/ctdt_nm.out" 
	result="${cpptest:testware_loc}/ctdt_nm.out" 
	bypassConsole="true"
	dependencyFiles="${cpptest:test_objects_quoted}"
/>

CreateStubConfigHeader

用于生成桩函数配置头文件的内部步骤,该文件将由已检测源包括在内。结果标头的位置由 "stub_config_header_file”执行流属性控制。 

示例:

     <CreateStubConfigHeader />

Echo

在 C++test 控制台或文件上打印给定的消息。

 属性:

  • msg -- 定义要打印的消息。
  • label -- 定义此流步骤的标签,以在 C++test 控制台上打印。
  • file -- 如果指定,C/C++test 会将给定的消息打印到指定的文件(而不是在控制台上)。此属性是可选的。

示例:

     <Echo msg="Hello world!"/>

HarnessInstrumentationStep

内部步骤会检测项目源文件。

示例:

     <HarnessInstrumentationStep />

LinkStep

使用先前准备的目标文件可执行测试链接。

属性:

  • result -- 指定输出可执行测试文件的位置。
  • linker -- 如果指定,则定义要使用可执行文件的链接器,而不是在项目属性中定义可执行文件。  此属性是可选的。
  • linkerCmdLine -- 如果指定,则定义要使用的链接器命令行模式,而不是在编译器定义文件中定义的链接器命令行模式。此属性是可选的。

示例:

      <LinkStep result="${cpptest:testware_loc}/${project_name}Test.exe" />

LsiStep

内部步骤用于分析有关已使用符号和可用符号的信息。

属性:

示例:

     <LsiStep />

PrecompileStep

内部步骤可为 LSI 分析预编译项目源文件。

示例:

      <PrecompileStep />

PrepareDataSources

将托管数据源转换为 C++test 测试执行运行时库支持的格式 -- CSV 文件或包含要编译为可执行测试的源代码数组的源文件。

属性:

  • generationDir -- 生成的 CSV 或数组源文件的输出目录。此属性是可选的。默认情况下,它设置为当前测试单元的 C++test 测试件目录。
  • inputDir -- 在实际测试用例执行期间读取数据源时要使用的生成 CSV 文件的位置。如果实际的测试执行是在目标设备上进行的,并且生成的 CSV 文件需要移动到该位置,则它可能与 "generationDir”不同。此属性是可选的。默认情况下它设置为 "generationDir”属性的值。
  • limit -- 指定要转换的最大数据源行数。  小于零的值表示应转换所有数据源行。此属性是可选的。默认情况下它设置为 -1。
  • type -- 定义是将数据转换为 CSV 文件还是源代码数组。  应该定义为 "csv”或 "array"。此属性是可选的。  默认情况下它设置为 "csv"。

示例:

     <PrepareDataSources limit="100" type="csv" />

ReadDynamicCoverageStep

读取包含测试执行覆盖结果的日志文件。

属性:

  • covLogFile -- 要读取的文件。可以包含 '*’和 '?' 通配符一次读取多个文件。要读取通过使用拆分文件通信通道获得的一系列文件 (请参见 文件通信通道实现),请指定第一个文件的路径(例如, 'cpptest_results.clog'),并确保所有文件都位于同一目录中 并且其名称遵循原始命名方案('cpptest_results.clog', 'cpptest_results.clog.0001','cpptest_results.clog.0002', 等)。该系列中的其余文件将自动与第一个合并,然后删除。

ReadLsiConfigStep

内部步骤用于从 LSI 模块读取数据。

示例:

     <ReadLsiConfigStep />

ReadNativeCoverage

从 C++test 2.3/6.x 导入的本机测试用例中读取测试覆盖率信息(如果当前测试单元中有)。

示例:

      <ReadNativeCoverage />

ReadNativeTestsLog

从 C++test 2.3/6.x 导入的本机测试用例中读取测试执行日志(如果当前测试单元中有)。

示例:

      <ReadNativeTestsLog />

ReadStaticCoverageStep

内部步骤读取在检测项目源文件时准备的静态覆盖率信息文件。

示例:

     <ReadStaticCoverageStep />

ReadSymbolsDataStep

内部步骤用于读取有关在已处理源文件中使用/定义的符号的信息。

属性:

  • readStubsSymbols --定义是否应读取已处理的桩函数文件中的信息。默认情况下它设置为 "true"。

示例:

    <ReadSymbolsDataStep />

ReadTestLogStep

从测试日志中读取测试执行结果。

属性:

  • testLogFile -- 指定要读取的测试日志文件。要读取通过使用拆分文件通信通道获得的一系列文件 (请参见 文件通信通道实现),请指定第一个文件的路径(例如, 'cpptest_results.tlog'),并确保所有文件都位于同一目录中 并且其名称遵循原始命名方案('cpptest_results.tlog', 'cpptest_results.tlog.0001','cpptest_results.tlog.0002', 等)。该系列中的其余文件将自动与第一个合并,然后删除。

  • timeoutInfoProperty -- 内部属性定义了要检查的测试流属性,以发现驱动程序是否由于超时而停止了测试执行。应该设置为 "test_exec_timeouted"。
  • logTime -- 定义用于在控制台上显示每个测试日志消息的时间的格式模式。在格式字符串中,所有字母(a-z 和 A-Z)均被视为模式。文本必须用单引号("'")引起来。两个单引号("''")用于打印一个单引号。可以使用以下模式:

    Y    年
    M  月
    d   天
    a   Am/pm 标记
    H  小时 (0-23)
    h   小时 (1-12)
    m  分钟
    s   秒
    S   毫秒
    Z   RFC 822 时区

    可以通过重复图案字母来设置最小位数。较短的数字为零填充。如果年份模式有两个字母(yy),则使用两位数的年份。如果月份模式具有三个或更多字母 (MMM),则将使用文本;否则,将使用数字。此属性是可选的。

示例:    

<ReadTestLogStep
	testLogFile="${cpptest:testware_loc}/cpptest_results.tlog" 
	timeoutInfoProperty="test_exec_timeouted"
	logTime="'Date': yy/MM/dd, 'Time': HH:mm:ss.SSS"
/>

RemoveFileStep

从文件系统中删除给定的文件。

属性:

  • file -- 定义要删除的文件。可以包含 '*’和 '?' 通配符一次删除多个文件。

示例:

     <RemoveFileStep file="${cpptest:testware_loc}/*.clog" />

RunNativeTests

执行从 C++test 2.3/6.x 导入的本机测试用例(如果当前测试单元中有)。

示例:

     <RunNativeTests />

SendStaticCoverageStep

内部步骤用于将所有读取的静态覆盖率信息传递到覆盖率结果系统。

示例:

     <SendStaticCoverageStep/>

SetProperty

设置执行流属性。您可以使用带有 'search’和 'replace' 属性的正则表达式来搜索和替换值。当测试值包含本节稍后介绍的 C++test 执行流变量之一时,此功能特别有用。

属性:

  • key -- 要设置的属性的名称。
  • value -- 要设置的属性的值。
  • search -- 用于搜索值的正则表达式。可选的。
  • replace -- 用来替代表达式的文本。如果存在 'search’属性,则为必需。

示例 1:

<SetProperty key="stub_config_file" value="${cpptest:testware_loc}/stubconfig.xml" />

将 plain 值存储到 "${cpptestproperty:stub_config_file}"

示例 2:

<SetProperty key="twl_mixed_path" value="${cpptest:testware_loc}" search="\\" replace="/" />

将所有反斜杠替换为正斜杠以获得所提供的值,并将结果存储到"${cpptestproperty:twl_mixed_path}":

停止

无条件停止执行流。

TestCaseFindingStep

内部步骤用于准备具有要执行的测试用例列表的 xml 文件。随后 TestRunnerGenerationStep 使用 xml 文件。

属性:

  • testSuiteConfigFile -- 定义输出 xml 文件。
  • allowNoTestCasesRun -- 指定在没有要执行的测试用例时是否应停止执行流程。

示例:

<TestCaseFindingStep

       testSuiteConfigFile="${cpptest:testware_loc}/testsuites.xml" allowNoTestCasesRun="false"

/>

TestRunnerGenerationStep

TestRunnerWithSocketsGenerationStep

准备测试运行程序源代码,将其作为测试用例执行的驱动程序。根据指定的属性,可执行测试将生成日志文件或通过套接字连接发送结果。

属性:

  • testrunnerCFile -- 测试运行程序文件的位置(如果项目仅包含 C 代码)。
  • testrunnerCppFile -- 测试运行程序文件的位置(如果项目仅包含 C++ 代码)。
  • testSuiteConfigFile -- 具有要执行的测试用例列表的 xml 文件。该文件应由 TestCaseFindingStep 准备。
  • testLogFile -- 定义可执行测试应在何处生成测试执行日志文件。如果使用套接字通信,则可以跳过。
  • covLogFile -- 定义可执行测试应在何处生成测试覆盖率日志文件。如果使用套接字通信,则可以跳过。
  • resultsHost -- 定义套接字监听器等待测试结果的主机。
  • testLogPort -- 定义套接字监听器将在其上等待测试执行结果的端口。如果使用文件通讯,则可以跳过。
  • covLogPort -- 定义套接字监听器将在其上等待测试覆盖率结果的端口。如果使用文件通讯,则可以跳过。
  • appendLogs -- 定义套接字监听器将在其上等待测试覆盖率结果的端口。默认情况下它设置为 "true"。

UserStubsInstrumentationStep

检测桩函数文件的内部步骤。

示例:

     <UserStubsInstrumentationStep />

变量

由于执行流配方是一个 xml 文档,因此用作流步骤属性的所有值都必须是有效的 xml 字符串。这意味着所有出现的特殊字符(例如 " 或 <)都需要用适当的转义序列(例如分别为 &quot; 或 &lt;)代替。

可以在流步骤属性中使用的变量是:

  • ${workspace_loc} -- 工作空间位置。
  • ${project_name} -- 测试项目的名称。
  • ${project_loc} -- 测试项目的位置。
  • ${project_loc:PROJECT_NAME} -- PROJECT_NAME 项目的位置。
  • ${resource_loc:RESOURCE_PATH} -- RESOURCE_PATH 表示的资源的位置。
  • ${cpptest:testware_loc} -- 当前测试单元的 C++test 测试软件的位置。
  • ${cpptest:cfg_dir} -- C++test 配置文件在 C++test 安装目录中的位置。
  • ${cpptest:utils_dir} -- C++test 工具在 C++test 安装目录中的位置。
  • ${cpptest:uid} -- 唯一标识符。
  • ${cpptest:add_file_ext} -- 根据项目源文件的扩展名计算的附加创建的源文件的扩展名。
  • ${cpptest:os} -- 操作系统类型: "windows" 或 "unix" (linux)。
  • ${cpptest:run_in_debugger} -- 根据【测试配置】中【在调试器中运行测试】选项的值决定是 "true” 还是 "false”。
  • ${cpptest:test_exec_work_dir} -- 按照【测试配置】中的指定可执行测试的工作目录。
  • ${cpptest:test_object_files} -- 将成为可执行测试中的一部分的目标文件的逗号分隔符列表。
  • ${cpptest:test_objects_quoted} -- 将作为可执行测试一部分的目标文件的空格分隔列表;每个文件将被引号(")包围。
  • ${cpptest:test_objects_esc_quoted} -- 将作为可执行测试一部分的目标文件的空格分隔列表;每个文件将被引号(\")包围。

FileSynchronizeStep

此步骤暂停执行流,同时等待一个指定的文件被创建,或等待该文件在指定的时间内处于非活动状态。行为取决于下面描述的使用的属性。

属性:

  • fileSync - 此步骤将尝试与之同步的文件的完整路径。
  • timeout - 等待文件(由 fileSync 属性指定)创建的时间长度(以毫秒为单位)。如果在超时前未创建文件,则执行流将照常恢复。此属性优先于下面描述的 fileInactiveTimeout 属性,因此不能与其结合使用。
  • fileInactiveTimeout -在通过 fileSync 属性指定的文件上超时之前,等待文件不活动的时间(以毫秒为单位)。这可以通过连续检查文件的上次修改时间来完成。当 C++test 检测到文件在指定的时间段内处于非活动状态时,执行流将恢复。

示例:

以下设置将使执行流程暂停 10 秒钟,或者直到 sync_file.txt 文件出现在指定位置为止:

<FileSynchronizeStep
	fileSync="${cpptest:testware_loc}/sync_file.txt" 
	timeout="10000"
/>

以下设置将跟踪 cpptest_results.tlog 文件的时间戳。当 C++test 检测到该文件在10秒钟内处于非活动状态时,执行流程将恢复:

<FileSynchronizeStep
	fileSync="${cpptest:testware_loc}/cpptest_results.tlog" 
	fileInactiveTimeout="10000"
/>
  • No labels