简体   繁体   English

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

[英]CANoe: How to select and start test cases from XML Test Module from Python using CANoe COM interface?


currently I am able to:目前我能够:

  • start CANoe application启动 CANoe 应用程序
  • load a CANoe configuration file加载 CANoe 配置文件
  • load a test setup file加载测试设置文件

    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}>.')


How can I access the XML Test Module loaded with the test setup (tse) file and select tests to be executed?如何访问加载了测试设置 (tse) 文件的 XML 测试模块并选择要执行的测试?

The last before line in your snippet is most probably causing the issue.代码段中的最后一行很可能是导致问题的原因。 I have been trying to fix this issue for quite some time now and finally found the solution.我已经尝试解决这个问题一段时间了,终于找到了解决方案。

Somehow when you execute the line self.test_setup.TestEnvironments.Item(1)不知何故,当您执行self.test_setup.TestEnvironments.Item(1)

win32com creates an object of type TestSetupItem which doesn't have the necessary properties or methods to access the test cases. win32com创建类型的对象TestSetupItem不具有必要的属性或方法来访问测试用例。 Instead we want to access objects of collection types TestSetupFolders or TestModules .相反,我们想要访问集合类型TestSetupFoldersTestModules对象。 win32com creates object of TestSetupItem type even though I have a single XML Test Module (called AutomationTestSeq) in the Test Environment as you can see here .即使我在测试环境中有一个 XML 测试模块(称为 AutomationTestSeq),win32com 也会创建TestSetupItem类型的对象,如您所见

There are three possible solutions that I found.我发现了三种可能的解决方案。


  1. Manually clearing the generated cache before each run.每次运行前手动清除生成的缓存。

Using win32com.client.DispatchWithEvents or win32com.client.gencache.EnsureDispatch generates a bunch of python files that describe CANoe's object model.使用win32com.client.DispatchWithEventswin32com.client.gencache.EnsureDispatch生成一堆描述 CANoe 对象模型的 python 文件。

If you had used either of those before, TestEnvironments.Item(1) will always return TestSetupItem instead of the more appropriate type objects.如果您之前使用过其中任何一个, TestEnvironments.Item(1)将始终返回TestSetupItem而不是更合适的类型对象。

To remove the cache you need to delete the C:\\Users\\{username}\\AppData\\Local\\Temp\\gen_py\\{python version} folder.要删除缓存,您需要删除C:\\Users\\{username}\\AppData\\Local\\Temp\\gen_py\\{python version}文件夹。

Doing this every time is of course not very practical.每次都这样做当然不是很实用。


  1. Force win32com to always use dynamic dispatch.强制 win32com 始终使用动态调度。 You can do this by using:您可以使用以下方法执行此操作:

canoe = win32com.client.dynamic.Dispatch("CANoe.Application") Any objects you create using canoe from now on, will be dynamically dispatched. canoe = win32com.client.dynamic.Dispatch("CANoe.Application")从现在开始,您使用canoe创建的任何对象都将被动态调度。

Forcing dynamic dispatch is easier than manually clearing the cache folder every time.强制动态调度比每次手动清除缓存文件夹更容易。 This gave me good results always.这总是给我很好的结果。 But doing this will not let you have any insight into the objects.但是这样做不会让您对对象有任何了解。 You won't be able to see the acceptable properties and methods for the objects.您将无法看到对象可接受的属性和方法。


  1. Typecast TestSetupItem to TestSetupFolders or TestModules .将 TestSetupItem 类型TestSetupItemTestSetupFoldersTestModules

This has the risk that if you typecast incorrectly, you will get unexpected results.这有一个风险,如果你的类型转换不正确,你会得到意想不到的结果。 But has worked well for me so far.但到目前为止对我来说效果很好。 In short: win32.CastTo(test_env, "ITestEnvironment2") .简而言之: win32.CastTo(test_env, "ITestEnvironment2") This will ensure that you are using the recommended object hierarchy as per CANoe technical reference.这将确保您按照 CANoe 技术参考使用推荐的对象层次结构。

Note that you will also have to typecast TestSequenceItem to TestCase to be able to access test case verdict and enable/disable test cases.请注意,您还必须将TestSequenceItem类型转换为TestCase才能访问测试用例判决并启用/禁用测试用例。

Below is a decent example script.下面是一个体面的示例脚本。

"""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)

Just continue what you have done.继续你所做的。

The TestEnvironment contains the TestModules. TestEnvironment 包含 TestModules。 Each TestModule contains a TestSequence which in turn contains the TestCases.每个TestModule 包含一个TestSequence,而TestSequence 又包含TestCase。

Keep in mind that you cannot individual TestCases but only the TestModule.请记住,您不能单独使用 TestCase,而只能使用 TestModule。 But you can enable and disable individual TestCases before execution by using the COM-API.但是您可以使用 COM-API 在执行之前启用和禁用单个测试用例。

( typing this from the top of my head, might not work 100% ) 从我的头顶输入这个,可能无法 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()

You have to keep in mind that a TestSequence can also contain other TestSequences (ie a TestGroup).您必须记住,测试序列还可以包含其他测试序列(即测试组)。 This depends on how your TestModule is setup.这取决于您的 TestModule 是如何设置的。 If so, you have to take care of that in your loop and descend into these TestGroups while searching for your TestCase of interest.如果是这样,您必须在循环中处理它并在搜索您感兴趣的测试用例时下降到这些测试组中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM