0

I am using cocotb version 1.5.2, and I would like to write an utility function to create reports/plots per test.

MWE: Implementing the get_test_name function so that the following test will print my_wonderful_test.

import cocotb
@cocotb.test()
async def my_wonderful_test(dut):
  print(get_test_name(dut));

def get_test_name(dut):
  pass # how do I get the current test from here?
Bob
  • 13,867
  • 1
  • 5
  • 27
  • Does this answer your question? [Getting the caller function name inside another function in Python?](https://stackoverflow.com/questions/900392/getting-the-caller-function-name-inside-another-function-in-python) – Tzane Jun 14 '22 at 10:25
  • It could be used to build a solution once one find a way to identify which function in the stack is the test. Maybe the decorator will give some clue. – Bob Jun 14 '22 at 18:14
  • 1
    If you are calling it the same way as in the example isn't it just 1 level up? – Tzane Jun 15 '22 at 05:27
  • Yes @Tzane, the example was only to illustrate. – Bob Jun 15 '22 at 06:51
  • Check out the solution I was looking for @Tzane – Bob Jun 17 '22 at 07:05

2 Answers2

1

You can use "name" attribute :

import cocotb
@cocotb.test()
async def my_wonderful_test(dut):
  print(my_wonderful_test.name);

But not sure that exactly you want.

FabienM
  • 3,421
  • 23
  • 45
  • I want to determine the test name without passing a reference from the test itself. In order, I was expecting to have some method to get the current test, in the scope `get_test_name`. – Bob Jun 14 '22 at 08:14
  • I have found the solution I wanted, thank you for your attempt :) – Bob Jun 17 '22 at 07:04
1

Thank you for the commenters, and thank you @FabienM for trying to give an answer. Thank you for @Tzane for trying to find an answer. You were close.

If you want to know a one liner answer

import cocotb;
def get_test_name():
  return cocotb.regression_manager._test.name

but the underline prefix in _test maybe it will break in the future, but for since I was only concerned about version 1.5.2 this is OK for me.

Any way I implemented another method that scans the stack one level at a time and check if the frame is in a cocotb.test decorated function. This is also the method that cocotb uses to _discover_tests

It won't work if the test is in a closure, but I never use that, and I don't know if it is even supported.

import cocotb
import inspect;
import sys
@cocotb.test()
async def test_get_testname(dut):
  print('Runnign from test ', get_test_name())
def get_test_name():
  try:
    return cocotb.regression_manager._test.name
  except:
    pass
  cocotbdir = '/'.join(cocotb.__file__.split('/')[:-1])
  frame = sys._getframe();
  prev_frame = None
  while frame is not None:
    try:
      # the [documentation](https://docs.python.org/2/library/inspect.html#inspect.getmodule)
      # says
      #   Try to guess which module an object was defined in.
      # Implying it may fail, wrapp in a try block and everything is fine
      module = inspect.getmodule(frame.f_code)
      func_name = inspect.getframeinfo(frame).function
      if hasattr(module, func_name):
        ff = getattr(module, func_name)
        if isinstance(ff, cocotb.test):
          return func_name
    except:
      pass
    prev_frame = frame;
    frame = frame.f_back;
  # return None if fail to determine the test name

I don't know why my questions are so badly received

It was something simple that I preferred to engage more people

Bob
  • 13,867
  • 1
  • 5
  • 27