How to import and use user defined enum classes in robot framework using python

Viewed 1738

I am currently implementing some test cases in robot framework. Assertion checks that the integer is working. I want to change that to enum values. This is my basic requirement.

This is the robot file that I am using (TestCase.robot)

*** Settings ***
Library           Wrapper.py

*** Test Cases ***
TC_01
    ${rv}    Set Variable    ${0}    #${}
    Should Be Equal As Integers    ${rv}    0

In the line Should Be Equal As Integers ${rv} 0, instead of this integer value 0 assertion , I want to convert that integer to some enum value.

something like this.

Should Be Equal As Integers    ${rv}    Status.OK

where Status is a enum class which is defined in the Wrapper.py. This Wrapper.py is included in the TestCase.robot as a Library in this robot file. I can paste the content of that enum here

class Status(Enum):
    OK = 0
    NOT_OK = 1

so that instead of integers we can make it more readable. When I give like this I am getting error as

'(Status.OK)' cannot be converted to an integer: ValueError: invalid literal for int() with base 10: '(status.ok)'

Can you guys help to sort out this issue ?

2 Answers

A couple of things - first and foremost, you want to compare the value, which is the Enum.member_name.value property, as already pointed out.
The other things - python Enum is a bit special, it's not instantiated - which would stop you from importing a module having it as class with the same name (to directly reference it) - Robot Framework makes an instance of the class in those imports. So direct access to the value is not possible.

There is a solution, though - make a wrapper (function, in my sample here, but can be a sibling class'es method) that will return you the target value. Sample python:

def return_enum_value(member):
    return Status[member].value


class Status(Enum):
    OK = 0
    NOT_OK = 1

And the RF usage:

${the value}=    Return Enum Value  OK
Should Be Equal As Integers         0    ${the value}

I don't think there's a solution exactly as you want - that is being able to write ${Status.OK}. At least I didn't make it work after some time spent messing around with it. If there's actually a solution, please let me know in the comment section.

Also, if I write just:

from enum import Enum


class StatusEnum(Enum):
    OK = 0
    NOT_OK = 1


print(StatusEnum.OK)

it will print out StatusEnum.OK, not 0 as you perhaps expect. You'd need to write Status.OK.value to get 0. More on that in the docs.

So, the closest I was able to do this is this:

Status.py

from enum import Enum
from robot.api.deco import library, keyword


class StatusEnum(Enum):
    OK = 0
    NOT_OK = 1


@library
class Status:

    @keyword
    def status_ok(self):
        return StatusEnum.OK.value

    @keyword
    def status_not_ok(self):
        return StatusEnum.NOT_OK.value

And in RF:

*** Settings *** 
Library    Status.py

*** Test Cases ***
Check OK And NOT OK
    ${OK}=    Status Ok
    ${NOT_OK}=    Status Not Ok
    Should Be Equal As Integers    ${OK}    0
    Should Be Equal As Integers    ${NOT_OK}    1

But that honestly feels like too much trouble when I can just do:

*** Variables ***
${OK}=    0
${NOT_OK}=    1

*** Test Cases ***
Check OK And NOT OK  
    Should Be Equal As Integers    ${OK}    0
    Should Be Equal As Integers    ${NOT_OK}    1
Related