Forum Discussion

rse's avatar
rse
New Contributor
2 years ago

Get test step name via property expansion in groovy step

Is it possible to get the test step name via a property expansion, or some other method that is automatically adjusted along with test step name changes?

 

When a property expansion is used in a groovy step, it is automatically updated when the test step name is changed.

 

For example, have the following property in a groovy step:

def id = context.expand( '${TestStep 1#id}' )

 

Change the name of the referred test step "TestStep 1" to "01 - test step" and this is automatically adjusted to:

def id = context.expand( '${01 - test step#id}' )

 

In our project we use some scripts to for example repeat a rest request step until the expected response is returned, or until a maximum number of attempts has been reached. In those scripts we refer to the test step to repeat by name:

def testStep = "TestStep 1"
Poll(testStep, responseProperty, expectedValue)

^ our "Poll"-method repeats "testStep" until the value of that test step's "responseProperty" is equal to the "expectedValue". Or a maximum number of 20 tries with a time out of 500 milliseconds between each attempt is reached.

 

But that "testStep"-variable is not automatically adjusted along with test step name changes.

 

We have some other methods that also rely on referring to a rest request test step by name from another groovy test step. As we use this a lot, changing test step names always comes with the risk of breaking tests.

  • JoostDG's avatar
    JoostDG
    Frequent Contributor

    Hi  rse ,

    Depending on where you are in your project, you can get the target test step name by an index(=number of the test step within a test case) via the "getTestTepAt()" method.

    Note that groovy/java is indexed with 0 as first value (so first step the parameter is "0", second step is "1" etc.)

    Example: I am in a groovy script test step and want to get the name from the first test step within this test case (e.g. your target rest test step):

    def targetTestStepName = testRunner.testCase.getTestStepAt(0).getName()

    This way, if you change the name it will always find it back. Same principle for a setup script or teardown script. 

     

    Within a script assertion you could do the same: 

    log.info messageExchange.modelItem.getParent().getName() // test step name
    log.info messageExchange.modelItem.getParent().getParent().getName() //test case name
    log.info messageExchange.modelItem.getParent().getParent().getParent().getName() //test suite name
    
    log.info messageExchange.modelItem.getParent().getParent().getParent().getTestCaseAt(1).getName() // second test case name in this test suite

    Of course, if you start changing the order of the target test steps this will no longer work neither. 

    You could get really groovy/robust by getting all test step names within a test case and then check if it CONTAINS a String value e.g. "step 1" so than if you change "step 1" to "teststep 1" it will still find it as well. 

    The getTestStepById() is ofcourse also robust, but a GUID is perhaps not that intuitive.

    • rse's avatar
      rse
      New Contributor

      JoostDGThanks for the reply. Sadly none of the suggestions are quite what I'm looking for.

       

      For the polling example we do use the following a lot, as it's mostly the preceding test step:

      testStep = context.testCase.getTestStepAt(context.getCurrentStepIndex()-1).getLabel()

       

      As you already said "Of course, if you start changing the order of the target test steps this will no longer work neither."

      Unfortunately for us, that is also something we do quite a lot, adding new test steps..

       

      CONTAINS.. might be more groovy, but robust? 😉

      I feel this would just add insult to injury: instead of at least knowing what's happening it'd become pretty much random if a test case ends up broken or not after a test step name change. If you managed to remember what you're allowed to change it would work of course. But that'd basically require a naming convention based around this.

      Could work in a new project, but we already have around 10k test steps in our project.

       

      getTestStepById() might be robust, but indeed nowhere near intuitive enough. When designing/maintaining it would be too much extra effort, as you can't easily see the GUIDs in the UI.

      And even if you could, as GUIDs are not easily compared at a glance, it would be hard to quickly see what test step it is actually referring to.

      • nmrao's avatar
        nmrao
        Champion Level 3

        rse 

        Understand the problem.

        Changing the step is common because of various reasons.

        Why not fix the test step name if at all possible? just to quote, "step 1" is not a good naming convention. Please give the meaningful name to the step so that you wouldn't have to rename so frequently.

         

        To your point, renaming step name is get replaced in all place of project including groovy script references (example you pointed context.expand), but not in other assignment, because of the fact that it is a string literal (no reference).

         

        Another chance is that if you know (i am sure you would) the method type, interface, name etc of a step, then it is possible to get the step dynamically. Of course, if the same type of request is used multiple times in same test case, will again have problem.

  • nmrao's avatar
    nmrao
    Champion Level 3

    Ok. If renaming is one time job then it is possible to search and replace from the text editor of your choice. Before that strongly suggest to close the project from ReadyAPI and have backup of the same.