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

章节目录:

了解测试执行流程

当您运行一个测试配置集来执行测试时,C/C++test 会执行一系列操作,这些操作通常会使单元测试结果被加载到 C/C++test UI 中。这些操作在测试流程定义中指定,测试流程定义以 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 属性的值显示在表格中。该值属性将用作默认值。

    4. 点击确定,保存修改的文件。将会验证 XML 文档。验证过程中发现的任何问题会进行报告。
  5. 点击应用确定,保存修改的测试配置。

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

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

我们建议您先尝试修改属性列表(如上所述),然后——如果需要进行额外的流程自定义设置——再定义自定义测试流程。

自定义测试执行流程定义以 XML 格式存储,并作为测试配置的一部分保存(因此可以在团队中共享)。通常,此类定义描述了在非标准环境中执行单元测试所需的一系列步骤,也可以用来启动任何命令行工具。自定义测试流程定义可以包括 C/C++test 内部操作或作为操作系统中的进程启动的外部工具。可以通过以下方式修改默认测试流程:

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

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

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




  4. 选中用户自定义> Build Test Executable
  5. 为此测试配置输入一个新的名称(例如,Build <target> Executable)。
  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 来输入您修改的测试流程。有关如何修改流程定义的详细信息,请参阅自定义测试执行流程定义 - 示例
  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 工具,该工具用于通过套接字通信通道收集结果。
    • 有关如何执行这一步骤(和步骤 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)会告知同步步骤执行已完成,可以读取结果。

选择外部嵌入式调试模式

选择外部嵌入式调试模式只能通过直接修改测试流程方法来完成。将以下行插入测试流程方法中靠近第一个 <RunnableExecution> 部分开始的地方;与其他未发布的属性一起:

<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++ 代码时,main 函数声明以 'extern "C"' 开头。

您还可以定义 CPPTEST_ENTRY_POINT 宏。如果定义该宏,则生成的 main 函数类似于:

    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 和 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_DEFINED 宏。定义该宏可防止生成 main 例程。在这类情况下,您需要调用 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=""
/>

您可能需要将这些步骤替换为适用于您正在使用的嵌入式环境的步骤。例如,假设您的目标是一个基于嵌入式 Linux 的 Power PC 板,支持 FTP,但不支持远程执行(没有 rsh 或任何类似的工具)。在这种情况下,用于测试的常规方法可能是:

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

例如,让我们考虑这种方法的一个简单实现。

如果已有步骤为:

<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 传输是使用 helper 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.tlog 和包含覆盖率结果的 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

在循环中执行包含的命令,直到执行所有测试用例。此元素仅在包含后面紧接 'ReadTestLogStep' 的测试执行步骤(启动测试可执行文件的 'CustomStep')时才有效。在 {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”,将为丢失的符号自动生成桩函数。默认设置为“false”。
  • generateUserStubs - 如果定义为“true”,将打开桩函数向导,为丢失的符号定义用户桩函数。默认设置为“false”。

示例:

     <AnalyzeMissingDefinitions generateStubs="true" />

AppendIncludedTestCases

将包含的测试套件文件与相应项目源文件绑定在一起的内部步骤。

示例:

      <AppendIncludedTestCases />

ClearTempCoverageData

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

示例:

     <ClearTempCoverageData />

CompileStep

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

示例:

     <CompileStep />

ConditionalStop

如果满足或不满足给定条件(视属性而定),则停止测试执行流程。

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

属性:

  • property -- 要检查的执行流程属性的名称。
  • equals -- 当属性具有指定值时,执行停止。该属性为可选项。
  • notEquals -- 当属性的值不是指定的值时,执行停止。该属性为可选项。

示例:

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

ConfigureStubs

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

示例:

     <ConfigureStubs />

CustomStep

运行外部可执行文件。

属性:

  • commandLine -- 定义要执行的命令行。
  • workingDir -- 为创建的进程定义工作目录。
  • runInBackground -- 如果设置为“true”,则异步运行进程。该属性为可选项。默认设置为“false”。
  • runInDebugger -- 如果设置为“true”,则运行测试配置中配置的调试器。该属性为可选项。默认设置为“false”。
  • okExitCode -- 如果指定该属性,将检查流程的退出代码,并在失败时停止测试执行流程。该属性为可选项。
  • stdIn -- 如果指定该属性,所提供文件的内容将用作进程的 stdin。该属性为可选项。
  • stdOut --如果指定该属性,来自进程中的 stdout 将被写入提供的文件。此属性为可选项。
  • stdErr -- 如果指定该属性,来自进程中的 stdout 将被写入提供的文件。该属性为可选项。
  • responseFileSupported -- 告知进程是否支持从 @file 指定的响应文件中读取命令行参数。在该情况下,当进程命令行超过最大长度(使用com.parasoft.xtest.common.process.maxcmdlength Java 参数指定;默认为 32000)时,命令行参数将通过响应文件传递给进程。该属性为可选项。默认设置为“false”。
  • dependencyFiles -- 定义进程依赖文件。与“result”属性一起使用,以确定当命令行自上次运行以来没有发生变更且结果文件比所有依赖文件更新时,是否可以将步骤视作“最新”步骤跳过。该属性为可选项。
  • result -- 定义进程结果文件。与“dependencyFiles”属性一起使用,以确定当命令行自上次运行以来没有发生变更且结果文件比所有依赖文件更新时,是否可以将步骤视作“最新”步骤跳过。该属性为可选项。
  • 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" />

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

示例 2:

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

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

Stop

无条件停止执行流程。

TestCaseFindingStep

用于准备包含要执行的测试用例列表的 xml 文件的内部步骤。该 xml 文件之后由 TestRunnerGenerationStep 使用。

属性:

  • 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