0

Robot - 3.1.1 Python - 3.7.3

I wanted to access method that are written in nested inner class from robot framework.

Robot:

*** Settings ***
Library             ../***/***/***/OrderList.py

    *** Keywords ***

    Click from order
        click_order

Python:

class OrderList():
           pass
class Ordertable(OrderList):
       def click_order(self):
            foo

I am getting below error while running the above robot suite.

No keyword with name 'click_order' found.

If I move the click_order method under parent class (OrderList) like below, then robot could recognize.

class OrderList():
    def click_order(self):
            foo
class Ordertable(OrderList):
       pass

Could someone help me as to what changes required at robot suite to make a call to nested inner class methods?

Learner
  • 481
  • 1
  • 15
  • 28
  • Launch your test with this option `--pythonpath ../***/***/***/OrderList.py` and import your library as `OrderList.Ordertable`. – Bence Kaulics Aug 27 '19 at 09:37
  • @BenceKaulics I have added the complete python pah including filename in pythonpath and had imported as per your suggestion but apparently issue still appears. Import error also appears 'failed: ModuleNotFoundError: No module named '.' ' – Learner Aug 27 '19 at 09:42

2 Answers2

2

When Robot Framework imports a library, it tries to import just the class named the same as the .py file - as in your case, the class OrderList in the OrderList.py file. And it doesn't import any other classes - check the documentation for more details.

The easiest option would be to have the class you are going to use renamed, to the same name as the file.

If that's not applicable - and looks like your intent is to use more than one class, you could have the file in your PYTHONPATH (like, physically moving the file to a dir in it, or extend it to include the module's one) and import the classes separately as OrderList.Ordertable.
Another would be to solve it on the python side - put each class in a module of their own, each importing the one with the base class.

The first is ops nightmare, the second - design & maintenance; your choice :).

Todor Minakov
  • 19,097
  • 3
  • 55
  • 60
  • I am still getting the same error. I tried with specifying nested class like 'Library ../***/***/***/OrderList.Ordertable' and OrderList.Ordertable.click_order (Keyword call) – Learner Aug 27 '19 at 08:54
  • You cannot import the library with `'Library ../***/***/***/OrderList.Ordertable` - it either has to end with `".py"`, when you are importing a python module somewhere in the file system. Or - the .py file itself must be in a directory that's in your PYTHONPATH - then this import will work (and with no "../../" relative paths). Look at the other answer, how to append a dir to the PYTHONPATH temporary - for the run - use the argument `--pythonpath` when you call the `robot` script. – Todor Minakov Aug 27 '19 at 10:44
1

Here is an example about how to import a class as a library and not the whole python file:

  1. In a folder named tests there is a test.robot and an OrderList.py file.
  2. OrderList.py:

    class OrderList():
               pass
    
    class Ordertable(OrderList):
           def click_order(self):
                print('foo')
    
  3. test.robot:

    *** Settings ***
    Library        OrderList.Ordertable
    
    *** Test Cases ***
    AA
        click order
    
  4. Launch it with the following command from the parent folder of the tests folder: robot --pythonpath .\tests\ --test AA .\tests\test.robot

  5. Result:

    PS prompt> robot --pythonpath .\tests\ --test AA .\tests\test.robot
    ==============================================================================
    Test
    ==============================================================================
    AA                                                                    | PASS |
    ------------------------------------------------------------------------------
    Test                                                                  | PASS |
    1 critical test, 1 passed, 0 failed
    1 test total, 1 passed, 0 failed
    ==============================================================================
    Output:  C:\Users\myuser\output.xml
    Log:     C:\Users\myuser\log.html
    Report:  C:\Users\myuser\report.html
    
Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
  • This works fine if python and robot comes under same directory but if python file comes from different directory then baseclass.childclass is not accepted. Example: Library ../Library/OrderList.Ordertable – Learner Sep 02 '19 at 14:49
  • If the path passed with `--pythonpath` is an absoluth path then it should work regardless of the working directories. – Bence Kaulics Sep 02 '19 at 16:48
  • Since I am running the robot suite directly from python the '--pythonpath' is not supported. My way of execution is import robot robot.run("C:\\foo\\test_sample.robot", log=log, report=report, output=output, loglevel="DEBUG", stdout=exec_report) – Learner Sep 03 '19 at 17:08
  • You can set pythonpath from python directly: https://stackoverflow.com/questions/3108285/in-python-script-how-do-i-set-pythonpath – Bence Kaulics Sep 03 '19 at 17:40