【问题标题】:Call googletest test cases from Robot Framework从 Robot Framework 调用 googletest 测试用例
【发布时间】:2020-07-12 20:11:19
【问题描述】:

在我当前的项目中,我必须使用漂亮的 Robot Framework 运行测试用例。现在,已经有一些非常详细的测试用例,已经在 Google-Test 中实现,无法重写为 Robot Framework。

现在,在我们的持续集成设置 (Jenkins) 中,有必要使用 Robot Framework 启动所有测试用例,并且 Google-Test 测试需要由 Robot Framework 触发。

有没有一种简单的方法可以使用 Robot Framework 扩展库调用 google test 中的所有测试,或者是否有必要编写一个?

如果没有这样的扩展,什么是开始写一些的好方法。

【问题讨论】:

    标签: jenkins robotframework googletest


    【解决方案1】:

    基于 gtest 的测试只是可执行的二进制文件。 Robot Framework 具有内置库Process,可用于运行外部进程。文档here

    所以,基本上你可以使用 Run Process 关键字来触发 gtest 二进制文件的执行。

    【讨论】:

      【解决方案2】:

      如果您想查看 Robot Framework 中的各个测试,您应该处理 Google 测试的标准输出,该标准在 Run Process 关键字的返回对象中可用。

      在 Robot Framework 中,有一些方法可以在 runtime 中动态生成测试用例。下面的想法受到启发,它基于这篇博文:Dynamically create test cases with Robot Framework

      免责声明,它不是一个完整的解决方案,因为它不能处理在构建或运行 gtest 二进制文件期间可能发生的所有问题。例如构建错误、分段错误等。 此外,所需的努力可能不值得最终结果。它还需要持续的维护和开发,以跟随谷歌测试框架的变化。所以这只是一个具有示范和启发目的的小例子。

      gtest.py 是一个library that also acts as a listener。通过这种方式,它可以有一个start_suite 方法被调用,并将套件作为 Python 对象,robot.running.model.TestSuite。然后您可以将此对象与Robot Framework's API 一起使用来创建新的测试用例(或删除现有的测试用例)。 (对于多个 gtest 类,也可以为每个 gtest 类创建新的子套件,因此 Robot Framework 测试结构可以遵循原始 gtest 结构。)

      from robot.running.model import TestSuite
      from robot.libraries.BuiltIn import BuiltIn
      import re
      
      
      class TestCase():
      
          TESTNAME_PATTERN = re.compile(r"\[ RUN      \]\s(.*)\.(.*)")
      
          def __init__(self):
              self.name = None
              self.log = ''
              self.status = False
      
          def set_name(self, line):
              match = TestCase.TESTNAME_PATTERN.search(line)
              if match:
                  self.name = f'{match.group(1)}.{match.group(2)}'
                  self.log = line
              else:
                  raise RuntimeError("Error parsing unit test name")
      
      
          def set_status(self, lastline):
              if 'OK' in lastline:
                  self.status = True
      
      
      class gtest(object):
          ROBOT_LISTENER_API_VERSION = 3
          ROBOT_LIBRARY_SCOPE = 'GLOBAL'
          ROBOT_LIBRARY_VERSION = 0.1
      
          def __init__(self):
              self.ROBOT_LIBRARY_LISTENER = self
              self.top_suite = None
              self.cases = []
      
          def _start_suite(self, suite, result):
              self.top_suite = suite
      
          def add_test_cases(self, gtest_output):
              self.top_suite.tests.clear() # remove placeholder test
              case = TestCase()
              case_started = False
      
              for line in gtest_output.splitlines():
      
                  if line.startswith('[ RUN'):
                      case.set_name(line)
                      case_started = True
                  elif case_started and (line.startswith('[       OK ]') or line.startswith('[  FAILED  ]')):
                      case.log += f'\n{line}'
                      case.set_status(line)
                      self.cases.append(case)
                      case = TestCase()
                      case_started = False
                  elif case_started:
                      case.log += f'\n{line}'
      
              for case in self.cases:
                  self._add_test_case(case)
      
          def _add_test_case(self, case):
              tc = self.top_suite.tests.create(name=case.name)
              tc.keywords.create(name="Test", args=[case])
      
          def test(self, case):
              if case.status is False:
                  BuiltIn().fail(case.log)
              else:
                  BuiltIn().log(case.log)
      
      
      globals()[__name__] = gtest
      

      该库的使用方式如下,(所有与gtest相关的任务都应该在套件设置阶段实现),

      *** Settings ***
      Library         gtest
      Variables       gtest_output.py                # should come from Run Process keyword's output
      Suite Setup     Add Test Cases    ${stdout}    # build and run gtest binaries here
      
      *** Test Cases ***
      Placeholder
          [Documentation]    This is needed to avoid empty suite error.
          ...    It will be removed during the run.
          No Operation
      

      并提供以下输出。

      输入是一个字符串文字,因为重点是解析和动态测试用例的创建,而不是构建/运行 gtests 本身。

      gtest_output.py:

      stdout= \
      """
      Running main() from user_main.cpp
      [==========] Running 2 tests from 1 test case.
      [          ] Global test environment setup.
      [          ] 2 tests from SquareRootTest
      [ RUN      ] SquareRootTest.PositiveNos
      ../user_sqrt.cpp(6862): error: Value of: sqrt (2533.310224)
      Actual: 50.332
      Expected: 50.3321
      [  FAILED  ] SquareRootTest.PositiveNos (9 ms)
      [ RUN      ] SquareRootTest.ZeroAndNegativeNos
      [       OK ] SquareRootTest.ZeroAndNegativeNos (0 ms)
      [          ] 2 tests from SquareRootTest (0 ms total)
      
      [          ] Global test environment teardown
      [==========] 2 tests from 1 test case ran. (10 ms total)
      [  PASSED  ] 1 test.
      [  FAILED  ] 1 test, listed below:
      [  FAILED  ] SquareRootTest.PositiveNos
      
      1 FAILED TEST
      """
      

      【讨论】:

        猜你喜欢
        • 2016-05-05
        • 2022-08-20
        • 2014-02-27
        • 2018-12-14
        • 1970-01-01
        • 2016-01-13
        • 2017-08-08
        • 2018-02-09
        • 2014-09-20
        相关资源
        最近更新 更多