Add Test case with robot.api

how to add a test to a robot file from the api ?

I tried this but it does not work…

Does anyone have an example of adding test cases on a robot test via the api ? I’m probably not using the api features correctly

from robot.api.parsing import *
from robot.api import TestSuite
from RobotFrameworkTests.Tests.CONSTANTS import *

class TestModifier(ModelTransformer):

    def visit_File(self, node):
        # print(node.sections)
        for test_case_sections in node.sections:
            if type(test_case_sections) == TestCaseSection:
                print("test_case_sections.body : " + str(test_case_sections.body))
                
                new_test = [KeywordCall([Token(Token.SEPARATOR, '    '), Token(Token.KEYWORD, 'Log'), Token(Token.SEPARATOR, '    '), Token(Token.ARGUMENT, 'Third Example'), Token(Token.EOL, '\n')])
                    ,KeywordCall([Token(Token.SEPARATOR, '    '), Token(Token.KEYWORD, 'Keyworddddd1'), Token(Token.SEPARATOR, '    '), Token(Token.ARGUMENT, 'Yooo'), Token(Token.EOL, '\n')]),
                    EmptyLine([Token(Token.EOL)])]

                test_case_sections.body.append(new_test)

                print("Test cases : ")
                for test_case in test_case_sections.body:
                    print("    " + str(type(test_case.body)) + str(test_case.body))


        # Call `generic_visit` to visit also child nodes.
        return self.generic_visit(node)


model = get_model(CURRENT_TEST_NAME, curdir=CURRENT_PATH)
TestModifier().visit(model)
model.save(CURRENT_PATH+'//modified.robot')

Commande prompt result :

test_case_sections.body : [<robot.parsing.model.blocks.TestCase object at 0x0000015D169596C8>, <robot.parsing.model.blocks.TestCase object at 0x0000015D169598C8>]
Test cases : 
    <class 'list'>[KeywordCall(tokens=[Token(SEPARATOR, '    ', 3, 0), Token(KEYWORD, 'Log', 3, 4), Token(SEPARATOR, '    ', 3, 7), Token(ARGUMENT, 'First Example', 3, 11), Token(EOL, '\n', 3, 24)]), KeywordCall(tokens=[Token(SEPARATOR, '    ', 4, 0), Token(KEYWORD, 'Keyword1', 4, 4), Token(SEPARATOR, '    ', 4, 12), Token(ARGUMENT, 'Regaeman', 4, 16), Token(EOL, '\n', 4, 24)]), EmptyLine(tokens=[Token(EOL, '\n', 5, 0)])]
    <class 'list'>[KeywordCall(tokens=[Token(SEPARATOR, '    ', 7, 0), Token(KEYWORD, 'Log', 7, 4), Token(SEPARATOR, '    ', 7, 7), Token(ARGUMENT, 'Second Example', 7, 11), Token(EOL, '\n', 7, 25)]), EmptyLine(tokens=[Token(EOL, '\n', 8, 0)])]
Traceback (most recent call last):
  File "C:/BureauLocal/ProvisionningRobotFrameworkGit/RobotFrameworkTests/Tests/visit_File.py", line 33, in <module>
    TestModifier().visit(model)
  File "C:\Users\a811585\AppData\Local\Programs\Python\Python37\lib\site-packages\robot\parsing\model\visitor.py", line 62, in visit
    return visitor(node)
  File "C:/BureauLocal/ProvisionningRobotFrameworkGit/RobotFrameworkTests/Tests/visit_File.py", line 25, in visit_File
    print("    " + str(type(test_case.body)) + str(test_case.body))
AttributeError: 'list' object has no attribute 'body'

Process finished with exit code 1

Robot Test :

*** Test Cases ***
First Example
    Log    First Example
    Keyword1    Regaeman

Second example
    Log    Second Example

*** Keywords ***
Keyword1
    [Arguments]    ${arg}
    Log    Keyword1 ${arg}

Keyword2
    [Arguments]    ${arg}
    Log    Keyword2 ${arg}

Solved


class TestModifier(ModelTransformer):

    def visit_File(self, node):
        # print(node.sections)
        for test_case_sections in node.sections:
            if type(test_case_sections) == TestCaseSection:
                print("test_case_sections.body : " + str(test_case_sections.body))
                print(test_case_sections.body[0].header)

                new_test = TestCase(
                    header=TestCaseName([Token(Token.TESTCASE_NAME, "test3"), Token(Token.EOL)]),
                    body=[KeywordCall([Token(Token.SEPARATOR, '    '), Token(Token.KEYWORD, 'Log'), Token(Token.SEPARATOR, '    '), Token(Token.ARGUMENT, 'Third Example'), Token(Token.EOL)])
                     ,KeywordCall([Token(Token.SEPARATOR, '    '), Token(Token.KEYWORD, 'Keyworddddd1'), Token(Token.SEPARATOR, '    '), Token(Token.ARGUMENT, 'Yooo'), Token(Token.EOL)]),
                     EmptyLine([Token(Token.EOL)])]
                )

                test_case_sections.body.append(new_test)

                print("Test cases : ")
                for test_case in test_case_sections.body:
                     print("    " + str(type(test_case.body)) + str(test_case.body))


        # Call `generic_visit` to visit also child nodes.
        return self.generic_visit(node)

Do you want to add them dynamically for execution or save them to disk? Parsing API that you use is good for the latter but there are better options for the former.

When using the parsing API, you can visit exactly those nodes you need. In this particular case visit_TestCasesSection would be better than visit_File.

@lealexio Could you please explain this part, "from RobotFrameworkTests.Tests.CONSTANTS import * "? Is it used to connect the robot file with a python file?