I am using an acceptance testing framework (robot framework) and it has an API which allows you to 'visit' suites and tests before execution.
The framework does not save the original suites name (a.k.a. tests.my_test). If you wanted to run that test twice with different names it will throw out the tests component and become new_name.my_test. I wanted to be able to preserve that information so that while viewing it can have descriptive names, but while searching the suite trees I could still find the original test names and rerun.
Questions to people unfamiliar with the framework
I wanted to piggyback off of their work to stay as compatible with the framework as possible. The selection of rerunned tests is here. It includes a function
gather_failed_tests which uses class GatherFailedTests. Since, that native feature of rerunfailed and my feature of rerunrenamedtests can't coexist I chose to simply monkeypatch the GatherFailedTests class to inherit from my class, which fixes the names before it would gather the tests.
Is that a dangerous idea anyway? Should I copy all the source for the function
gather_failed_tests and rename them in their entirety? It's a maintainability vs stability problem. I either can monkey patch a minimal component and hope I get any fixes added to the function or surrounding framework or I can have to manually update the whole chain.
I feel like there is a more efficient way to go through the iterable suites. suite_obj.suites returns an iterable of suites. However the initial top level suite itself also needs to be searched. Is there a way to collapse
It is ultimately a tree of suites and I need to handle the first element in each branch that has the
originallongname in metadata.
Questions for anyone who knows robot
I'm unhappy with wiping out the parent when I am configuring a non-root suite
test.parent.parent = None. I'm uncertain if why that method doesn't just configure the parent's criticality instead of failing, but regardless of how it functions is there a better way to alter the longname property without destroying info?
from robot.api import SuiteVisitor from robot.conf import gatherfailed class rename(SuiteVisitor): """Store the original longname so that rerunning can happen even with virtually reorganized tests.""" def __init__(self, new_name): self.new_name = new_name def start_suite(self, suite): originallongname = suite.longname suite.metadata.setdefault('originallongname', originallongname) suite.configure(name=self.new_name) class resetname(SuiteVisitor): def config_test(self, suite): originallongname = suite.metadata['originallongname'] try: suite.configure(name=originallongname) # Critically setting from non-root error except TypeError: for test in suite.tests: test.parent.name = originallongname test.parent.parent = None def config_all_suites(self, suite): for suite in suite.suites: try: self.config_test(suite) except KeyError: self.config_suites(suite) def config_suites(self, suite): try: self.config_test(suite) except KeyError: self.config_all_suites(suite) def start_suite(self, suite): self.config_suites(suite) class RenameThenGatherFailedTests(resetname): def __init__(self): self.tests =  def visit_test(self, test): if not test.passed: self.tests.append(test.longname) def visit_keyword(self, kw): pass gatherfailed.GatherFailedTests = RenameThenGatherFailedTests class rerunrenamedtests(SuiteVisitor): def __init__(self, output): self.output = output def start_suite(self, suite): tests = gatherfailed.gather_failed_tests(self.output) suite.filter(included_tests=tests)
If it would help to see how this would be used you could see here.