Search code examples
pythonpytestcocotb

How to get the current test name in cocotb


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?

Solution

  • 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