CANoe:如何使用CANoe COM接口从Python的XML测试模块中选择和启动测试用例?

2024-06-26 11:18:18 发布

您现在位置:Python中文网/ 问答频道 /正文


目前我可以:

  • 开始使用独木舟
  • 加载独木舟配置文件
  • 加载测试设置文件

    def load_test_setup(self, canoe_test_setup_file: str = None) -> None:
        logger.info(
            f'Loading CANoe test setup file <{canoe_test_setup_file}>.')
    
        if self.measurement.Running:
            logger.info(
                f'Simulation is currently running, so new test setup could \
                not be loaded!')
            return
    
        self.test_setup.TestEnvironments.Add(canoe_test_setup_file)
    
        test_environment = self.test_setup.TestEnvironments.Item(1)
        logger.info(f'Loaded test environment is <{test_environment.Name}>.')
    


如何访问加载了测试设置(tse)文件的XML测试模块并选择要执行的测试?


Tags: 文件testselfinfononeenvironmentisdef
2条回答

代码段中的最后一行before很可能是导致问题的原因。 我已经尝试解决这个问题很长一段时间了,终于找到了解决方案

当您执行self.test_setup.TestEnvironments.Item(1)行时

win32com创建了一个类型为TestSetupItem的对象,该对象没有访问测试用例所需的属性或方法。相反,我们希望访问集合类型为TestSetupFoldersTestModules的对象。win32com创建了TestSetupItem类型的对象,尽管我在测试环境中有一个单独的XML测试模块(称为AutomationTestSeq),您可以see here

我发现了三种可能的解决方案


  1. 在每次运行之前手动清除生成的缓存

使用win32com.client.DispatchWithEventswin32com.client.gencache.EnsureDispatch生成一组描述CANoe对象模型的python文件

如果您以前使用过这两个对象中的任何一个,TestEnvironments.Item(1)将始终返回TestSetupItem,而不是更合适的类型对象

要删除缓存,需要删除C:\Users\{username}\AppData\Local\Temp\gen_py\{python version}文件夹

当然,每次这样做都不太实际


  1. 强制win32com始终使用动态分派。 您可以使用以下方法进行此操作:

canoe = win32com.client.dynamic.Dispatch("CANoe.Application") 从现在起,您使用canoe创建的任何对象都将被动态调度

强制动态分派比每次手动清除缓存文件夹更容易。这总是给我带来好的结果。但这样做不会让您对对象有任何洞察。您将无法看到对象的可接受属性和方法


  1. 类型转换TestSetupItemTestSetupFoldersTestModules

这样做的风险是,如果键入错误,您将得到意外的结果。但到目前为止对我来说效果很好。 简而言之:win32.CastTo(test_env, "ITestEnvironment2")。这将确保您按照CANoe技术参考使用推荐的对象层次结构

请注意,您还必须将TestSequenceItem类型转换为TestCase才能访问测试用例裁决并启用/禁用测试用例

下面是一个不错的示例脚本

"""Execute XML Test Cases without a pass verdict"""
import sys
from time import sleep
import win32com.client as win32

CANoe = win32.DispatchWithEvents("CANoe.Application")
CANoe.Open("canoe.cfg")

test_env = CANoe.Configuration.TestSetup.TestEnvironments.Item('Test Environment')

# Cast required since test_env is originally of type <ITestEnvironment>
test_env = win32.CastTo(test_env, "ITestEnvironment2")
# Get the XML TestModule (type <TSTestModule>) in the test setup
test_module = test_env.TestModules.Item('AutomationTestSeq')

# {.Sequence} property returns a collection of <TestCases> or <TestGroup>
# or <TestSequenceItem> which is more generic
seq = test_module.Sequence
for i in range(1, seq.Count+1):
    # Cast from <ITestSequenceItem> to <ITestCase> to access {.Verdict}
    # and the {.Enabled} property
    tc = win32.CastTo(seq.Item(i), "ITestCase")
    if tc.Verdict != 1: # Verdict 1 is pass
        tc.Enabled = True
        print(f"Enabling Test Case {tc.Ident} with verdict {tc.Verdict}")
    else:
        tc.Enabled = False
        print(f"Disabling Test Case {tc.Ident} since it has already passed")


CANoe.Measurement.Start()
sleep(5)   # Sleep because measurement start is not instantaneous
test_module.Start()
sleep(1)

继续你所做的

TestEnvironment包含TestModules。每个TestModule都包含一个TestSequence,该序列依次包含测试用例

请记住,您不能单独测试用例,而只能测试模块。但是您可以在执行之前使用COM-API启用和禁用单个测试用例

在我的头顶上输入这个,可能无法100%工作

test_module = test_environment.TestModules.Item(1) # of 2 or whatever
test_sequence = test_module.Sequence
for i in range(1, test_sequence.Count + 1):
    test_case = test_sequence.Item(i)
    if ...:
        test_case.Enabled = False # or True

test_module.Start()

您必须记住,TestSequence还可以包含其他TestSequence(即TestGroup)。这取决于TestModule的设置方式。如果是这样,您必须在循环中处理这些问题,并在搜索感兴趣的测试用例时进入这些测试组

相关问题 更多 >