1

Robot Test

*** Settings ***
Variables   test_if_case_sensitive.py
Documentation    Suite description
Library     Process

*** Variables ***
${pw1}   "HeLLo1234"
${pw2}   "hello1234"
${test3}

*** Test Cases ***
Test1
    ${test1}=    set variable   ${passwordWithCaps}
    ${test2}=    set variable   ${passwordWithoutCaps}
    ${test1}=    set variable   ${pw1}
    ${test2}=    set variable   ${pw2}
    ${test3}=    set variable   ${message}
    Start Process   python3     test_if_case_sensitive.py
    Check If It Works
*** Keywords ***
Check If It Works
   PASS EXECUTION IF    ${test3} == "Passwords do not match"

Here is the python script

#test_if_case_sensitive.py
import socket
import string
import random

global passwordWithCaps
global passwordWithoutCaps
global message

def randomString(stringLength):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

def test_check_if_passwords_match_case_sensitive_when_creating_them(passwordWithCaps, passwordWithoutCaps):
    username = randomString(random.randint(10, 20))

    confirm_password = False
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    IP_address = "127.0.0.1"
    Port = 8081
    server.connect((IP_address, Port))

    while True:
        message = server.recv(2048).decode("utf-8")
        if message:
            print("Message 1" + message)
            if confirm_password:
                print("Message 2" + message)
                if message.__contains__("You have successfully registered"):
                    raise Exception("Passwords match when they shouldn't")
                break
            if message.__contains__("Please enter username"):
                server.send("--register".encode())
            if message.__contains__("Please enter a username to register"):
                server.send(username.encode())
            if message.__contains__("Please create a password"):
                server.send(passwordWithCaps.encode())
            if message.__contains__("Please confirm password"):
                confirm_password = True
                server.send(passwordWithoutCaps.encode())

            print(message)

test_check_if_passwords_match_case_sensitive_when_creating_them(passwordWithCaps, passwordWithoutCaps)

I am trying to assign global variables passwordWithCaps and passwordWithoutCaps from the Robot Test script using variables ${pw1} and ${pw2}. I instead get an error saying 'passwordWithCaps' is not defined which shows the issue stems from the python script. However, I also get this in the Robot Test -

Test1                                                                 | FAIL |
Variable '${passwordWithCaps}' not found.
1
  • Have you had a look at the Robot Framework User Guide section Creating Test Libraries which has practical Pyhton examples to create custom Python libraries? Commented Feb 21, 2020 at 18:26

1 Answer 1

3

Your design so far is not going to work; you are mixing the concepts of variables file with libraries. A few points where you approached it incorrectly:

  • variables files are evaluated at the beginning of the suite parsing; at that point the Variables section is still not evaluated. When RF/python gets to the method call & tries to execute it, it is getting passed 2 vars for which it knows nothing about - apart from the fact they are in the global scope. E.g. At this point nothing but the reservation of their names is a fact for these 2 variables, nor their datatypes (how to use them), nor their values (what are they).
  • the purpose of variables file is to insert in Robot Framework's scope new variable:value pairs; that happens with assignment operators (variable=value), or with the special function get_variables(), or with overriding the module attribute __all__, or with using a class (let's not get there). You have neither of those in the .py file. This might possibly be sidestepped with a global var scope (I haven't ever tried it) but it still needs it value set, somewhere. The reverse - inserting in the variables file scope sounds hard (if not impossible, I don't know; it might work with RF_var_the_name) - at the moment of the file evaluation there are not that many set variables, certainly no test ones.
  • the variables file are evaluated only once, during the import; even if that happened at a later stage - that test function would have been ran just once, so it can be used for only one case.
  • you are setting the variable ${test3} to be equal to the message, the one defined and used in the function. But the scope of that variable is strictly local, it is present only for the function and only through its execution; it will never leak out (that's a python fundamental point).
  • calling Start Process will create a new python process, totally isolated from the one running the case - and it would have no access to your variables - and passwordWithCaps & the other will be undefined (cause - if they were, that would have been in the case running one) & execution failing. Future tense, as we're not getting to this point at all, failing earlier.
  • (personal) global variables are frowned upon in python, that's a dangerous (& clumsy) mechanism for communication.

So what should you (IMHO) do? "Separation of concerns" - fancy way of saying "have a function that does the check on one place, and the test data stored in a different place" :) Drop the global variables declaration and the method call from the py file, and move it to a Library import. Now you will have access like a keyword called "test check if passwords match case sensitive when creating them", that you can feed with any data.
Change its last print() statement to return message - so it can communicate with the outside world by returning the message string.

And then, in your case(s) call the keyword, with different values :

${test3}=   test check if passwords match case sensitive when creating them    ${pw1}    ${pw2}
Should Be Equal    ${test3}    Passwords do not match

${test3}=   test check if passwords match case sensitive when creating them    samecase    samecase
Should Be Equal    ${test3}    Passwords do not match    # will supposedly fail

(By the way I don't see this message "Passwords do not match" ever getting out from the function, and the only thing breaking the loop is if the server has responded with success - you might want to check the flow logic there, for this negative test.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.