<p>代码段中的最后一行before很可能是导致问题的原因。
我已经尝试解决这个问题很长一段时间了,终于找到了解决方案</p>
<p>当您执行<code>self.test_setup.TestEnvironments.Item(1)</code>行时</p>
<p>win32com创建了一个类型为<code>TestSetupItem</code>的对象,该对象没有访问测试用例所需的属性或方法。相反,我们希望访问集合类型为<code>TestSetupFolders</code>或<code>TestModules</code>的对象。win32com创建了<code>TestSetupItem</code>类型的对象,尽管我在测试环境中有一个单独的XML测试模块(称为AutomationTestSeq),您可以<a href="https://i.stack.imgur.com/zTeHd.png" rel="nofollow noreferrer">see here</a></p>
<p>我发现了三种可能的解决方案</p>
<hr/>
<ol>
<li>在每次运行之前手动清除生成的缓存</李>
</ol>
<p>使用<code>win32com.client.DispatchWithEvents</code>或<code>win32com.client.gencache.EnsureDispatch</code>生成一组描述CANoe对象模型的python文件</p>
<p>如果您以前使用过这两个对象中的任何一个,<code>TestEnvironments.Item(1)</code>将始终返回<code>TestSetupItem</code>,而不是更合适的类型对象</p>
<p>要删除缓存,需要删除<code>C:\Users\{username}\AppData\Local\Temp\gen_py\{python version}</code>文件夹</p>
<p>当然,每次这样做都不太实际</p>
<hr/>
<ol start=“2”>
<li>强制win32com始终使用动态分派。
您可以使用以下方法进行此操作:</li>
</ol>
<p><code>canoe = win32com.client.dynamic.Dispatch("CANoe.Application")</code>
从现在起,您使用<code>canoe</code>创建的任何对象都将被动态调度</p>
<p>强制动态分派比每次手动清除缓存文件夹更容易。这总是给我带来好的结果。但这样做不会让您对对象有任何洞察。您将无法看到对象的可接受属性和方法</p>
<hr/>
<ol start=“3”>
<li>类型转换<code>TestSetupItem</code>到<code>TestSetupFolders</code>或<code>TestModules</code></李>
</ol>
<p>这样做的风险是,如果键入错误,您将得到意外的结果。但到目前为止对我来说效果很好。
简而言之:<code>win32.CastTo(test_env, "ITestEnvironment2")</code>。这将确保您按照CANoe技术参考使用推荐的对象层次结构</p>
<p>请注意,您还必须将<code>TestSequenceItem</code>类型转换为<code>TestCase</code>才能访问测试用例裁决并启用/禁用测试用例</p>
<p>下面是一个不错的示例脚本</p>
<pre><code>"""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)
</code></pre>