简体   繁体   中英

Robot Framework keywords and Inheritance

I have a library of keywords. I have a few classes and subclasses, but I'm having an issue with inheritance and keywords being double-defined. For example:

MyLib.py

class Class1:
  def __init__(self):
    pass

  def do_something_generic(self):
    #do stuff that is generic to all subclasses
    pass

class Subclass1(Class1):
  def __init__(self):
    pass

  def do_something_specific_to_subclass1(self):
    #something specific
    pass

class Subclass2(Class1):
  def __init__(self):
    pass

  def do_something_specific_to_subclass2(self):
    #something specific
    pass

The specific keywords work fine, but when I try to call Do Something Generic I get Multiple keywords with name 'Do Something Generic' found . I can fully qualify the library name with MyLib.Class1.Do Something Generic , but is there any way to define Do Something Generic to always refer to the superclass, since the method is only defined there and is simply inherited by the subclasses?

From Robot Framework User Guide

When the static library API is used, Robot Framework uses reflection to find out what public methods the library class or module implements.
It will exclude all methods starting with an underscore,
and with Java libraries also methods that are implemented only in java.lang.Object are ignored.
All the methods that are not ignored are considered keywords.

Have you considered adding helper base class with a _do_something_generic function? You can exclude it from __all__ list. Then use the inheritance to expose keywords from the base class in Class1 .

MyLibrary.py:
__all__ = ['Class1', 'Subclass1', 'Subclass2']

class BaseClass:
  def _do_something_generic(self):
    pass

class Class1(BaseClass):
  def __init__(self):
    pass

  def do_something_generic(self):
    return self._do_something_generic()

class Subclass1(BaseClass):
  def __init__(self):
    pass

  def do_something_specific_to_subclass1(self):
    a = self._do_something_generic()
    return (a, 3)

class Subclass2(BaseClass):
  def __init__(self):
    pass

  def do_something_specific_to_subclass2(self):
    #something specific
    pass

I think the best solution is to simply move do_something_generic to a separate class, so that your base class only has helper functions and no public keywords:

class Class1:
  def __init__(self):
    pass

class Subclass0(Class1):
  def do_something_generic(self):
    #do stuff that is generic to all subclasses
    pass

While it might be possible to solve this with something exotic like using __slots__ or __getattr__ , or modifying self.__dict__ , it's probably not worth the trouble.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM