robotcode icon indicating copy to clipboard operation
robotcode copied to clipboard

[Enhancement] Redesign Set Global/Suite/Test Variable and VAR Statement handling

Open zastress opened this issue 2 years ago • 11 comments

Describe the bug Global Variables that are declared inside Test Setup or Suite Setup are not recognized inside a test case

If possible add some example source code like:

*** Settings ***
Test Setup    My Test Keyword

*** Keywords ***

My Test Keyword
    VAR    ${global}    scope=GLOBAL

*** Test Cases ***
Example Test Case
    Log    ${global}

Expected behavior Variable should not be marked inside test as non-existent

zastress avatar Feb 14 '24 10:02 zastress

Hi,

thanks for reporting this issue.

The scope of variables is determined by runtime. Although examples like these may seem simple, it's an endless pitfall to predict the existence of a variable statically like this. Imagine the variables is defined in a resource file that may or may not be imported.

Not only for language servers, but also for testers such variables quickly turn in to a nightmare, as they are unpredictable and magic.

Given the effort to maintain such feature and the effort to maintain magic randomly scoped variables, this feature is unlikely to be implemented in RobotCode.

If you want to make other testers aware of the use of global veriables, define a variable in *** Variables *** in order to indicate testers (and the plugin) the use of a non-local scoped variables:

*** Settings ***
Test Setup    My Test Keyword

*** Variables ***
${GLOBAL}

*** Keywords ***
My Test Keyword
    VAR    ${GLOBAL}    scope=GLOBAL

*** Test Cases ***
Example Test Case
    Log    ${GLOBAL}

This also helps as workaround for supporting autocompletion by RobotCode

Noordsestern avatar Feb 15 '24 18:02 Noordsestern

So, the reason I submitted this issue is I was using lsp before and these variables were resolved. I taught this was an easy fix 😃

zastress avatar Feb 15 '24 19:02 zastress

a comment from my side: What RFLS/LSP does is guessing, it might be that the variable is defined at some point, but you can't be sure. You could say that it is called in the test setup at the suite level, but you can also overwrite the test setup in a test, so that the above test setup is no longer called and then you wonder why it doesn't work.

d-biehl avatar Feb 15 '24 20:02 d-biehl

Just a comment to point out that the workaround is a bit odd for TEST scope variables: I have to define a SUITE variable in the *** Variables *** section, so that I don't get the "VariableNotFound" error or the "VariableNotUsed" warning, and get autocompletion.

But then at runtime I don't get the Variable '${XXX}' not found. error because the SUITE variable is found instead. I get an existing variable, with the default value defined at suite level.

image

Just saying, I understand it can be hard to fix.

BTW it is not possible to define variable scope in the *** Variables *** section, right?

gohierf avatar Feb 26 '24 15:02 gohierf

No, you have to think a little differently here. If the variable in the test has the default value of the suite, something has gone wrong and some prerequisites have not been met. You can check this in the test scope and react to it specifically.

IF  $MY_VAR=UNDEFINED  Fail  Oops some keywords were not executed before

However, you cannot easily find out whether a variable is defined, i.e. whether Set Test Variable has been called, unless you build an exception handler around it. But then you can only react to the error message, which in turn is also prone to errors.

In addition, you can find all references to this variable in the source code and you can also be sure that this variable is really meant.

d-biehl avatar Feb 26 '24 21:02 d-biehl

BTW it is not possible to define variable scope in the *** Variables *** section, right?

you're right

d-biehl avatar Feb 26 '24 21:02 d-biehl

a comment from my side: What RFLS/LSP does is guessing, it might be that the variable is defined at some point, but you can't be sure. You could say that it is called in the test setup at the suite level, but you can also overwrite the test setup in a test, so that the above test setup is no longer called and then you wonder why it doesn't work.

Hello, @d-biehl I agree you can't be sure whether it has been properly set or not, but checking that Set Test/Suite/Global Variable has been called within the given scope (or the new VAR in RF7) is enough for most people. If the Set Test Variable is not properly set then an error will be raised at runtime (or even during dryrun). I prefer that option that should be less happening rather than having lots of linter errors or the workaround you suggest of using the *** Variables *** to set empty values (besides with that solution if you set a Suite with children or global variable you will have to repeat that hack on every file where you are using that variable)

Leemur89 avatar Aug 12 '24 08:08 Leemur89

Hi there, @d-biehl I definitely agree w @Leemur89 and others. My team has also struggled with this behavior, and multiple testers have messaged me about how to deal with it properly. Coming from LSP and using Test Variables extensively, such behavior creates quite a large visual disruption in the code. Interestingly, this seems to be the biggest challenge we have encountered when transitioning from LSP to RobotCode.

Yes, you can bypass the error in multiple ways, but none of them are ideal (e.g., I use a diagnostic modifier in setting.json, but now the actually missing variables are ignored too).

Is there any way to consider implementing the same behavior as in LSP? 🙏

Thank you kindly, Tereza

tchudobova-cen69317 avatar Jan 14 '25 09:01 tchudobova-cen69317

"After migrating from the robot-server plugin to the robotcode plugin, our existing project has many variable not found errors. This kind of incompatible change should consider the experience of existing users - at least there should be a compatibility mode for transition. Alternatively, if you don't recommend using Set Test/Suite/Global Variable, you should mark these as deprecated rather than removing them completely. Such frequently used features should not be completely discontinued without careful consideration. Besides new projects, older projects still need to use the original plugin and version 6.1.1."

AsteriskZuo avatar Apr 28 '25 14:04 AsteriskZuo

Hi @AsteriskZuo, @tchudobova-cen69317 and all the others,

To clarify once again: RobotCode is not a fork or derivative of the Robot Framework Language Server. It is a completely standalone, purely hobby-driven open-source project. Therefore, no functionality has been removed, no functions need to be marked as “deprecated,” and a compatibility mode simply wouldn’t make sense here.

I’m not saying you shouldn’t use Set Test/Suite/Global Variable (or, in newer Robot Framework versions, the VAR statement)—but you should use it differently and correctly:

Instead of having RFLS dynamically infer Set Test/Suite/Global Variable, RobotCode relies from the start on explicit variable declarations in the *** Variables *** section to ensure clarity and maintainability.

This clear, static approach guarantees that your code remains traceable and maintainable at all times—across projects. This behavior is intentional, designed to eliminate errors caused by hidden, context-dependent variable assignments.

I’ve already done some preliminary work and sketched out concrete ideas (and code) to address this more gracefully. It will still surface as an error or warning—albeit with new wording—which you can reprioritize or disable via DiagnosticModifiers.

Since I develop the entire project in my spare time, it might take a little while to implement these changes, as other priorities come first.

I’m reopening this issue so we can better track progress here.

In the meantime:

  1. Navigate to the error at Set Global/Suite/Test Variable.
  2. Place the cursor on the problematic code.
  3. Open the quick-fix menu by clicking the yellow lamp icon or using the tooltip.
  4. Select Create Suite Variable ….

That will resolve the issue.

d-biehl avatar Apr 28 '25 22:04 d-biehl

I also run into this problem, and I can't see how *** Variables *** can solve this. What I want to achieve is to have a build directory for each test case based on the suite and test names (without spaces).

*** Variables ***
${OBJDIR}=    ${SUITE NAME}/${TEST NAME}

This is not possible due to the ${TEST NAME} is None in this scope. I'm then defining the variable in the Test Setup phase like this, and I run into the problem discussed in this issue.

Image

Is there a better solution to this problem?

RasmusGOlsen avatar Nov 27 '25 13:11 RasmusGOlsen