如何在使用单个测试项目时将所有QtTestLib单元测试结果组合在一个文件中?

Rom*_*lov 6 c++ qt qttest qtestlib

在我们的项目中,我们使用QtTestLib进行单元测试.原因是整个项目在可能的情况下已经使用Qt并且它是一个GUI应用程序,因此我们希望能够测试GUI界面.

我们的项目是由MSVC编译的,所以我们不希望每个测试都有一个单独的项目文件,因为它会使解决方案变得混乱.因此,我们为所有测试创建了一个项目.所有测试都应该在CIS上自动进行(持续集成),因此我们尝试使用一些XSLT转换通过XML格式的输出文件将测试插入Hudson.

但似乎测试输出存在问题.如果对所有测试使用单个main(),并且仅向每个测试传输cmd行参数:

#include "MyFirstTest.h"
#include "MySecondTest.h"

int main(int argc, char **argv)
{
  int result = 0;
  MyFirstTest test1;
  result |= QTest::qExec(&test1, argc, argv);
  MySecondTest test2;
  result |= QTest::qExec(&test2, argc, argv);
  return result;
}
Run Code Online (Sandbox Code Playgroud)

然后你会得到一个多次重写的结果文件.因此,如果您想使用输出文件(例如xml)稍微自动化它,您将只获得其中的最后结果.所有其他都将被覆盖.

我们已经尝试过这种方法,它不能让你使用像Hudson这样的连续集成系统.所以我的问题是:有没有机会在一个输出文件中附加结果?当然,我们可以使用一些解决方法,例如通过QTest :: qExec()运行每个测试,并使用修改后的参数将结果写入单独的文件,但这似乎不是最好的方法.理想情况下,我希望有一个结果文件与CIS一起使用.

mue*_*lan 3

通过这个技巧,您可以将各个测试 xml 报告收集到临时缓冲区/文件中;全部来自单个测试二进制文件。让我们使用 QProcess 从一个二进制文件中收集单独的测试输出;测试使用修改后的参数调用自身。首先,我们引入一个特殊的命令行参数,它可以正确利用子测试 - 所有这些都仍然在您的测试可执行文件中。为了方便起见,我们使用接受 QStringList 的重载 qExec 函数。然后我们可以更轻松地插入/删除“-subtest”参数。

// Source code of "Test"

int
main( int argc, char** argv )
{
  int result = 0;

  // The trick is to remove that argument before qExec can see it; As qExec could be
  // picky about an unknown argument, we have to filter the helper 
  // argument (below called -subtest) from argc/argc; 

  QStringList args;

  for( int i=0; i < argc; i++ )
  {
     args << argv[i];
  }

  // Only call tests when -subtest argument is given; that will usually
  // only happen through callSubtestAndStoreStdout

  // find and filter our -subtest argument

  size_t pos = args.indexOf( "-subtest" );

  QString subtestName;

  if( (-1 != pos) && (pos + 1 < args.length()) )
  {
    subtestName = args.at( pos+1 );

    // remove our special arg, as qExec likely confuses them with test methods

    args.removeAt( pos );
    args.removeAt( pos );

    if( subtestName == "test1" )
    {
      MyFirstTest test1;
      result |= QTest::qExec(&test1, args);
    }

    if( subtestName == "test2" )
    {
      MySecondTest test2;
      result |= QTest::qExec(&test2, args);
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的脚本/命令行调用中:

./Test -subtest test1 -xml ... >test1.xml
./Test -subtest test2 -xml ... >test2.xml
Run Code Online (Sandbox Code Playgroud)

在这里 - 我们有办法分离测试输出。现在我们可以继续使用 QProcess 的功能来为您收集标准输出。只需将这些行附加到您的 main. 这个想法是,如果没有请求显式测试,但使用我们的特殊参数,再次调用我们的可执行文件:

bool
callSubtestAndStoreStdout(const String& subtestId, const String& fileNameTestXml, QStringList args)
{
   QProcess proc;

   args.pop_front();

   args.push_front( subtestId );
   args.push_front( "-subtest" );

   proc.setStandardOutputFile( fileNameTestXml );

   proc.start( "./Test", args );

   return proc.waitForFinished( 30000 ); // int msecs
}

int 
main( int argc, char** argv )
{
   .. copy code from main in box above..

   callSubtestAndStoreStdout("test1", "test1.xml", args);
   callSubtestAndStoreStdout("test2", "test2.xml", args);

   // ie. insert your code here to join the xml files to a single report

   return result;
}
Run Code Online (Sandbox Code Playgroud)

然后在您的脚本/命令行调用中:

./Test -xml           # will generate test1.xml, test2.xml
Run Code Online (Sandbox Code Playgroud)

事实上,希望未来的 QTestLib 版本能让这变得更容易。