如果您想查看 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
"""