I was trying to run the example from “TapApiFromPython/Misc Examples/DynamicallyGenerateTestPlan.py”, which I reworked to support python3.
It works fine with built-in BasicSteps but I can’t add my steps, generated by Python Plugin.
(I can use my steps in TUI)
I always get “System.NullReferenceException: Object reference not set to an instance of an object.”.
example of code:
import sys
import clr
import os
from pathlib import Path
tapPath = Path(os.environ["TAP_PATH"])
basic_steps_tapPath = tapPath / "Packages" / "OpenTAP"
my_steps_tapPath = tapPath / "Packages" / "Python" / "my_tap"
sys.path.append(str(tapPath))
sys.path.append(str(basic_steps_tapPath))
sys.path.append(str(my_steps_tapPath))
clr.AddReference("OpenTap")
clr.AddReference('OpenTap.Plugins.BasicSteps')
clr.AddReference('Keysight.OpenTap.Plugins.Python')
clr.AddReference('Python.my_tap')
import OpenTap
import OpenTap.Plugins.BasicSteps as BasicSteps
import Keysight.OpenTap.Plugins.Python as PythonPlugin
import Python.my_tap as MySteps
# Required to find plugins
print("Test Plan Started.")
OpenTap.PluginManager.Search()
OpenTap.SessionLogs.Initialize("generatedPlan_log.txt")
myTestPlan = OpenTap.TestPlan()
mySequenceStep = BasicSteps.SequenceStep()
# myTestPlan.Name = "MyTestplan"
# TestPlan.Name doesn't have a setter anymore
myDelayStep1 = BasicSteps.DelayStep()
myDelayStep1.DelaySecs = 2.5
myDelayStep1.Name = "Delay1"
myDelayStep2 = BasicSteps.DelayStep()
myDelayStep2.DelaySecs = 1.1
myDelayStep2.Name = "Delay2"
myStep = MySteps.RegularStep() # OUTPUT: System.NullReferenceException: Object reference not set to an instance of an object.
myStep.Name = "Regular Step 1"
mySequenceStep.ChildTestSteps.Add(myDelayStep1)
mySequenceStep.ChildTestSteps.Add(myDelayStep2)
mySequenceStep.ChildTestSteps.Add(myStep)
myTestPlan.ChildTestSteps.Add(mySequenceStep)
myTestPlan.Save("MyTestPlan.TapPlan")
myTestPlan.Execute()
print(f"Test Plan Ended.")
1 Like
@geomags123 Welcome to the community!
Which version of the Python Plugin are you using?
I think it is easiest if you have this script in the same directory as your custom steps, but @rolf_madsen, @ivan.diep , or @arvind.sundararajan may have a better idea.
@brennen_direnzo I have Python Plugin version 2.2.0.
But the issue is not that I can’t open Python.my_tap.dll
. I can import it and even print the type of steps I created.
print(MySteps.MyStep)
# OUTPUT: <class 'Python.my_tap.MyStep'>
print(type(MySteps.MyStep))
# OUTPUT: <class 'CLR.CLR Metatype'>
but when I try to create an object of this step I get the error:
my_step = MySteps.MyStep()
# System.NullReferenceException: Object reference not set to an instance of an object.
# at Keysight.OpenTap.Plugins.Python.PythonStepWrapper.load(String name, String moduleName)
Are you trying to create a TestPlan in code? Just wondering why you’re trying to instantiate a TestStep, I don’t think it’s the usual use model. Usually you’d create your TestStep classes in code, and then use those to create a TestPlan in the Editor. My point is - you may be trying something in Python that no one has tried before, not sure. Perhaps there’s some functionality missing.
Also, why try to use the compiled version? I think also the intention with Python is to use the Python classes and then “transpile” them. So your Python would reference your Python code as opposed to your compiled dll. I don’t disagree that you should be able to do it the way you’re trying to do it, I just think you’re running up against the use model here and may be why you’re having trouble. But like I said, that may also explain why there’s functionality missing or a bug, if that’s the case.
@john.berlien thank you for the response
Basically, the idea is to generate OpenTap Test Plan automatically using Python and Tap API.
I think I’m not the first one who’s trying to achieve it because I use just a slightly reworked example from the OpenTap Python Plugin repo (link) which was created by @rolf_madsen for Python 2.
Okay I see. Have you tried building a plugin in Visual Studio and then used in Python this way?
@john.berlien no, usually I build plugins using tap python build <plugin_name>
. Is there any difference?
Sorry I mean building a C# plugin in Visual Studio.
Hi @geomags123 ,
We don’t support inserting python-defined test steps directly in a test plan, they need to be wrapped first, that is why we have the build step. If you can get a reference to the C# wrapper type it should work.
You probably need to import a module called Python.[ModuleName] and then find your types in there.
@rolf_madsen not sure I understood everything properly but I inserted python steps exactly after wrapping them with tap python build <ModuleName>
as you said.
And also I imported the module you said:
sys.path.append(str(my_steps_tapPath))
clr.AddReference('Python.my_tap')
import Python.my_tap as MySteps
myStep = MySteps.RegularStep()
Is this what you were talking about? Or did you mean another wrapper?
Ah sorry, I though I understood what the problem was. Seems not so.
Can you provide the stacktrace from that exception? It seems like something may have to be initialized before you can do that.
@rolf_madsen
Traceback (most recent call last):
File "c:/Program Files/OpenTAP/Packages/Python/test_GenerateTestPlan.py", line 33, in <module>
myStep = MySteps.myRegularStep()
System.NullReferenceException: Object reference not set to an instance of an object.
at Keysight.OpenTap.Plugins.Python.PythonStepWrapper.load(String name, String moduleName)
at Python.tap.myRegularStep.load_instance()
at Keysight.OpenTap.Plugins.Python.PythonStepWrapper..ctor()
at Python.tap.BaseTestStep..ctor()
Fatal Python error: auto-releasing thread-state, but no thread-state for this thread
OK, thanks, so I guess the exception comes from this code: Keysight.OpenTap.Plugins.Python/SDK/PythonStepWrapper.cs · master · OpenTAP / Plugins / python · GitLab
I have no idea why it occurs though - I cannot immediately see any problem here.
Can you open an issue at Issues · OpenTAP / Plugins / python · GitLab with this information?
1 Like