运行报告生成控制
默认情况下,CoverageScanner 库在 instrumented 应用程序退出时生成执行报告。这可能对于单元测试套件(在其中,在每次单个测试后生成报告更为可取)或对于像守护进程一样永远不会终止的应用程序来说还不够。
为此,CoverageScanner 库也允许您:
- 将 C 代码嵌入到 instrumented 应用程序中以控制报告生成(请参阅单元测试)。
- 在收到 Microsoft® Windows 事件或 UNIX® 信号时生成覆盖率报告。
- 在任意函数返回后自动保存覆盖率数据(请参阅–cs-trigger-function)
以下章节描述第二种方法。
使用 UNIX 信号生成执行报告
要启用使用 UNIX 信号的执行报告生成,请使用 --cs-dump-on-signal=<sig> instrumentation 选项,其中 <sig> 是信号号或其常见名称,例如 SIGUSR1。
可以使用 UNIX kill 命令引发报告生成。(例如:kill -SIGUSR1 <pid>)
使用 Microsoft Windows 事件生成执行报告
要启用使用 Microsoft Windows 事件的执行报告生成,请使用 --cs-dump-on-event=<event> instrumentation 选项,其中 <event> 是标识事件的字符串。
由于没有标准的 Windows 命令与 UNIX kill 命令等效,Coco 提供了一种在以下章节中描述的替代方案。
发送事件到应用程序的程序
Coco 包含一个用于将事件发送到 Windows 应用程序的工具,用于与 --cs-dump-on-event 一起使用。这并不经常需要,因此您需要自己编译它。
该程序位于目录 <Windows Coco>\dump_on_event 中。它存在两种版本,一个用 C++ 编写,另一个用 C# 编写。它们分别称为 dump_on_event 和 dump_on_event_cs。
要编译程序并查看其工作原理,请按照以下说明操作。以下说明针对的是 C++ 的情况。C# 版本非常相似,具体差异请看最后。
- 将 <Windows Coco>
\dump_on_event文件夹复制到其他位置,例如C:\dump_on_event,因为原始版本是写保护的。 - 双击文件
build_cpp以启动对dump_on_event.cpp和示例应用程序event_sample_cpp.cpp的编译。当编译event_sample_cpp.cpp时,会使用选项--cs-dump-on-event=COVERAGE进行配置。 - 程序编译后,会出现三个窗口。
- 是 CoverageBrowser 窗口,其中已加载文件
event_sample_cpp.exe.csmes的内容。它包含程序event_sample_cpp的源代码,但还没有汇总数据。 - 一个命令提示符窗口,可用于稍后运行程序
dump_on_event。 - 一个命令窗口,在其中运行
event_sample_cpp。每秒打印一个点,并将持续五分钟。
- 是 CoverageBrowser 窗口,其中已加载文件
- 现在可以向
event_sample_cpp发送事件COVERAGE。在命令提示符窗口中输入C:\dump_on_event>dump_on_event COVERAGE
当程序
event_sample_cpp收到事件时,它将创建一个文件event_sample_cpp.exe.csexe,其中包含迄今为止生成的汇总数据。再次发送该命令。文件
event_sample_cpp.exe.csexe因此增长,因为新的汇总数据会被追加到它上面。不会将相同的数据写入两次。 - 您可以使用 文件 > 加载执行报告 从 CoverageBrowser 导入执行报告。每次数据转储都作为单独的执行出现,因此如果您发送了两次事件,您将在 执行 窗口中看到两次执行。
相同的步骤也适用于程序的 C# 版本。您只需要将 build_cpp 替换为 build_cs,将 dump_on_event 替换为 dump_on_event_cs,将 event_sample_cpp 替换为 event_sample_cs。
全局事件
一般来说,Windows 事件是为了特定账户而创建的,因此无法从同一台机器上的其他账户访问。但 Windows 还支持系统级事件。它们的名称以 Global\ 开头。
因此,要从不同账户的应用程序中生成 Windows 事件的代码覆盖率报告,需要系统级事件。
在以下示例中,我们使用程序 dump_on_event 生成事件
- 使用参数
--cs-dump-on-event=Global\COVERAGE编译您的应用程序。 - 启动您的应用程序。
- 在另一个账户中,执行以下命令
C:\dump_on_event>dump_on_event Global\COVERAGE
该应用程序随后将覆盖率报告写入磁盘。
编写自己的程序
您还可以使用 dump_on_event 作为从测试环境发送事件的示例。实际上,它只是 Microsoft Windows 函数 SetEvent() 的包装器
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <iostream>
void DisplayError( LPTSTR lpszMessage )
{
// Retrieve the system error message for the last-error code
LPSTR lpMsgBuf;
DWORD dw = GetLastError();
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
( LPSTR ) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
std::cerr << lpszMessage << " (error " << dw << "): " << lpMsgBuf << '\n';
LocalFree( lpMsgBuf );
}
int main( int argc, char *argv[] )
{
if ( argc != 2 )
{
std::cerr << "Usage: " << argv[0] << " <event_name>" << '\n';
return 1;
}
const char * eventName = argv[1] ;
HANDLE ghEvent = OpenEventA(
EVENT_MODIFY_STATE,
FALSE,
eventName
);
if ( ghEvent == NULL )
{
DisplayError( "Opening event failed" );
return 1;
}
if ( ! SetEvent( ghEvent ) )
{
DisplayError( "Raising event failed" );
CloseHandle( ghEvent );
return 1;
}
CloseHandle( ghEvent );
return 0;
}Coco v7.2.0©2024 Qt公司有限公司。
Qt及其相关标志是Qt公司在芬兰以及/或其他国家/地区的商标。所有其他商标均为各自所有者的财产。