robotframework / RIDE

Test data editor for Robot Framework
Apache License 2.0
958 stars 378 forks source link

Pythonpath is not applied when loading libraries #2654

Closed JFoederer closed 10 months ago

JFoederer commented 11 months ago

Consider attached small example of a test suite that references a Python Robot library, that in turn references a technical library. All in separate folders from a single root folder called Example.

When I open the _testsuite folder in RIDE and try to run it, it fails at first. This is expected, because both the Robot library and the technical library are imported using a path starting in the Example folder: domain_lib.MyRobotLib.py and tech_lib.myTechLib.

[ ERROR ] Error in file 'C:\Users\johan.foederer\sandbox\Example\test_suite\A.robot' on line 2: Library 'domain_lib\MyRobotLib.py' does not exist.

This can be fixed by setting the Pythonpath in RIDE's settings: image

Setting .. in the Pythonpath suffices to run the test suite successful. Using a relative path is useful because it always works, even when switching between multiple projects that use the same basic structure. Absolute paths also work, though.

The issue is that the Pythonpath is used only for running the test suite, not when loading libraries. This causes the libraries to turn up red and documentation and auto-completion to be unavailable. This is still the case after restarting RIDE. image

A work around is to open a command prompt, create the Pythonpath env variable and then start RIDE from the prompt. This is however not a suitable solution for people that are not accustomed to using command line and are expected to just open the project using the desktop short cut.

Download the example: Example.zip

JFoederer commented 11 months ago

RIDE log belonging to the example:

20231011 07:58:07.075 [INFO]: Found Robot Framework version 6.1rc1 from C:\Users\johan.foederer\AppData\Local\Programs\Python\Python310\lib\site-packages\robot.

20231011 07:58:07.075 [INFO]: Started RIDE v2.0.8dev17 using python version 3.10.6 with wx version 4.2.0 in win32.

20231011 07:59:08.279 [INFO]: Inserted '..' to sys.path.

20231011 08:11:17.255 [WARN]: Importing test library "domain_lib/MyRobotLib.py" failed

Traceback (most recent call last):

  File "C:\Users\johan.foederer\AppData\Local\Programs\Python\Python310\lib\site-packages\robotide\spec\librarymanager.py", line 80, in _fetch_keywords
    path = get_path(
  File "C:\Users\johan.foederer\AppData\Local\Programs\Python\Python310\lib\site-packages\robotide\spec\xmlreaders.py", line 103, in get_path
    return _resolve_path(name.replace('/', os.sep), basedir)
  File "C:\Users\johan.foederer\AppData\Local\Programs\Python\Python310\lib\site-packages\robotide\spec\xmlreaders.py", line 120, in _resolve_path
    raise robotapi.DataError
HelioGuilherme66 commented 11 months ago

I believe that this is a problem of the test case itself, because it should clearly indicate the Path to the Library/Resource.

image

The test author should have written ../domain_lib/MyRobotLib.py.

When you write .. in the PYTHONPATH of RIDE, where is it relative from? From the installation of RIDE? Looks like when running it is relative to ${CURDIR}.

Anyway, if we modify the code to include ${CURDIR} as a Path for documentation search, then your problem would be solved, but the tests would fail if the user runs them in the command line, like I did in the example screenshot.

JFoederer commented 11 months ago

What I am looking for here is symmetry between a headless Robot run (e.g. in a ci/cd pipeline) and running from RIDE as an IDE. In the headless run, which is typically scripted, the pythonpath is set either before the call to Robot or as a command line argument.

When running from RIDE, we try to stay away from the command line. Instead we have the preferences window. When entering an absolute path, I expect the behaviour to be identical compared to passing the pythonpath as command line argument to Robot. Currently this is the case when running the tests from RIDE, but not for editing. This could be the first thing to cover from this issue.

I understand your concern about the relative path. This is different compared to headless runs and therefore maybe less straight forward. Because RIDE is a single application intended for interactive use it is common to switch between projects. From a user perspective it is inconvenient to modify the import settings after each switch. Even more so, when people work on different branches of the same project, it often goes unnoticed that the path is still wrong and they are testing against wrong dependencies.

This is where the relative path becomes important and, if my memory doesn't fail me, this used to work in older versions of RIDE. When opening a project I typically select a folder, the test suite folder (test_suite in the example). To me it was always obvious that the selected folder, shown as the top-level folder in the Test suites tree view, is the root folder. I am not sure if that maps one-on-one to ${CURDIR}, but I don't expect it to. I also did not consider the other options like open test suite, but I suppose it could work in a similar fashion. i.e. the file's folder is considered the root folder.

JFoederer commented 11 months ago

Now a bit more consise in reply to your question: if we modify the code to include ${CURDIR} as a Path for documentation search, then your problem would be solved, but the tests would fail if the user runs them in the command line, like I did in the example screenshot.

1) If I cd into the Example folder and run robot test_suite I expect it to fail

2) If I cd into the Example folder and run robot --pythonpath . test_suite I expect it to pass

3) If I open RIDE from any location, load the test_suite folder and set .. as pythonpath in preferences, I expect the test run to pass and the libraries to be properly loaded.

Plus that we will need to check whether ${CURDIR} is the right choice. Compared to the opened folder's path.

HelioGuilherme66 commented 11 months ago

This is different compared to headless runs and therefore maybe less straight forward. Because RIDE is a single application intended for interactive use it is common to switch between projects. From a user perspective it is inconvenient to modify the import settings after each switch. Even more so, when people work on different branches of the same project, it often goes unnoticed that the path is still wrong and they are testing against wrong dependencies.

This will be solved by local project configuration in the .ride directory (new issue from task: https://github.com/robotframework/RIDE/issues/2655)

JFoederer commented 11 months ago

Maybe, but it will not solve all the relative vs absolute path issues. I would then commit the config file to source control, but I have no control over to which location people do the check out.

HelioGuilherme66 commented 11 months ago

I still think that the test should reference the library with relative .. in this case:

3 - If I open RIDE from any location, load the test_suite folder and set .. as pythonpath in preferences, I expect the test run to pass and the libraries to be properly loaded.

JFoederer commented 11 months ago

To be honest, that is actually what I do, but the import then still fails with the indirection to the tech libraries.

HelioGuilherme66 commented 11 months ago

But, it is OK to find documentation, when the user explicitly declares it in PYTHONPATH, and we may document that .. is always relative to ${CURDIR} .

JFoederer commented 11 months ago

Regardless of personal preferences. I would expect that RIDE uses the exact same settings during editing and the test run. If the test run passes, all should be well and the libraries must be reachable during editing as well.

JFoederer commented 11 months ago

Is ${CURDIR} indeed the correct one? Does this always point to the folder opened by the user?

e.g. no runtime changes or dependencies on RIDE installation etc.?

HelioGuilherme66 commented 11 months ago

Is ${CURDIR} indeed the correct one? Does this always point to the folder opened by the user?

I need to confirm. There is some internal processing of the variable, it is re-written to the path of the current test suite directory. Not sure if this is done on RIDE code, or on lib/robot (modified from v3.1.2).

HelioGuilherme66 commented 10 months ago

@JFoederer Please try v2.0.8dev26.

Your example would not work fully, because the way tech_lib is referenced in domain_lib.

It actually worked fine, in Linux.

JFoederer commented 10 months ago

I tried on v2.0.8dev26 with the following results, results are identical on both Windows and Linux.

HelioGuilherme66 commented 10 months ago

That is the best I can do. Hope you find enough.

JFoederer commented 10 months ago

I appreciate the effort, so if this is the best, I'll happily take it.