Forum Discussion

mjlamora's avatar
mjlamora
New Contributor
2 years ago

Refactoring an API wipes out my request parameters

I'm building tests for an API that is in the midst of iterative development. The "Refactor definition" functionality sounds like exactly what I need, but every time I use it, it wipes out the test parameters from all of my functional tests and creates a mountain of rework. Is there something that I'm missing?

3 Replies

  • JoostDG's avatar
    JoostDG
    Frequent Contributor

    Hi mjlamora ,

    Like richie  metions: This issue has been around quite some time. I mentioned it once in a feature request for "refactor the refactoring" here : https://community.smartbear.com/t5/Feature-Requests/Refactor-Refactoring/idi-p/141007

    I recently gave a customer-feedback demo to Smartbear where I showed them this issue as well. It's indeed blocking in using the refactor API-definitions properly, which is a big feature in API development/testing obviously.

     

    I wrote a scripted workaround for this, which can be used via the test case setup. It checks that if certain parameters are emptied, they get re-filled again EITHER dynamically based on the test step name (values between brackets "(" & ")" will be set as parameter value) or EITHER any hardcoded value specified in the setup script.

    It's obviously not a solution to the actual SmartBear bug, but it can help others to still keep on using the refactoring feature without too much frustrations.

    The script contains also some specifics on language. That might not apply to your requests, so just take that out if not needed. 

    Below is script in my script library with name "parameterRefactoringBackup.groovy". So it's maintainable in one place instead of in each and every test case setup script.

     

     

    /**
     * Author: Joost De Geyndt (GreenLightGo) 21/01/2019
     * What: Refactoring an API definition sometimes has an unwanted effect: Some query parameters for methods GET, PUT, DELETE get blanked out!
     * Why: Blanking out is probably a SmartBear bug (?)... We cannot NOT refactor, as then we get outdated API definitions.
     * How: call script in a test case setup script.
     * Consists of 2 parts that will be called IF THE PARAMETER IS EMPTY:
     * Part 1:Fill in dynamically.
     * Based upon the size of array for "dynamicParametersToCheck" it will match the values between brackets from the test step name to the given parameters.
     * Example: test step name = "GET requestXYZ (abc) (12345) fr"
     * In the setup script we define String[] dynamicParametersToCheck = ["name", "nisCode", "Accept-Language"]
     * RESULT: Parameter "name", if emptied, will get value "abc". Parameter "nisCode" will get value "123456".
     * If a dynamic parameter-to-check has a name with "language" in it, the script will look at the last 2 characters of the test step name to pass this on as that language parameter.
     * RESULT: Parameter "Accept-Language" will be filled with "fr". If not language can be derived from the last 2 characters it will default to "nl".
     * Part 2: Hardcoded parameter values.
     * Example:
     * In the setup script we define String[] hardCodedParametersToCheck = ["queryType", "maxResult", "address", "history"] and their corresponding values String[] hardcodedParameterValues = ["name", "100", "true", "false"]
     * RESULT: Parameter "queryType" will be filled in with "name". Parameter "maxResult" with "100" etc. 
     * Note: You can also specify any dynamic properties, like e.g. String[] hardcodedParameterValues = ["\${#TestSuite#dynamicPropertyFromTestSuiteLevel}"]
     *** EXAMPLE SETUP SCRIPT:
     *** String[] dynamicParametersToCheck = ["nrn", "nisCode", "Accept-Language"]
     *** String[] hardCodedParametersToCheck = ["queryType", "maxResult", "address", "history"]
     *** String[] hardcodedParameterValues = ["nrn", "100", "true", "false"]
     *** def parameterRefactoringBackup = new parameterRefactoringBackup(context, log, testCase)
     *** parameterRefactoringBackup.Execute(dynamicParametersToCheck, hardCodedParametersToCheck, hardcodedParameterValues)
     **/
    
    import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext
    import org.apache.logging.log4j.core.Logger
    import com.eviware.soapui.model.testsuite.TestCase
    import java.util.regex.*;
    
    
    public class parameterRefactoringBackup {
        // Properties
        def context;
        def log;
        def testCase;
    
        // Constructor
        parameterRefactoringBackup(PropertyExpansionContext context, Logger log, TestCase testCase) {
            this.context = context
            this.log = log
            this.testCase = testCase
        }
    
        // Methods
        void Execute(String[] dynamicParametersToCheck = [], String[] hardCodedParametersToCheck = [], String[] hardcodedParameterValues = []) {
            int numberOfDynamicParametersToCheck = dynamicParametersToCheck.length
            int numberOfHardCodedParametersToCheck = hardCodedParametersToCheck.length
            int numberOfHardCodedParameterValues = hardcodedParameterValues.length
            assert (numberOfHardCodedParametersToCheck == numberOfHardCodedParameterValues): " The number of numberOfHardCodedParametersToCheck items does not match the number of possible numberOfHardCodedParameterValues!! Please update and try again!"
    
            for (int i = 0; i < testCase.getTestStepCount(); i++) {
                for (int j = 0; j < numberOfDynamicParametersToCheck; j++) {
                    String dynamicParameterValue = testCase.getTestStepAt(i).getPropertyValue(dynamicParametersToCheck[j])
                    //log.info "step " + (i + 1) + " for dynamicParametersToCheck number " + (j + 1) + "/" + (numberOfDynamicParametersToCheck) + " : parameter " + dynamicParametersToCheck[j] + " with parameterValue $dynamicParameterValue"
                    if (dynamicParameterValue == "") {
                        String testStepName = testCase.getTestStepAt(i).getName()
                        if (dynamicParametersToCheck[j].toLowerCase().contains("language")) {
                            def languageFromTestStep = testStepName[-2..-1]
                            if (languageFromTestStep.toLowerCase() == "fr") {
                                testCase.getTestStepAt(i).setPropertyValue(dynamicParametersToCheck[j], "fr")
                            } else {
                                if (languageFromTestStep.toLowerCase() == "de") {
                                    testCase.getTestStepAt(i).setPropertyValue(dynamicParametersToCheck[j], "de")
                                } else {
                                    if (languageFromTestStep.toLowerCase() == "en") {
                                        testCase.getTestStepAt(i).setPropertyValue(dynamicParametersToCheck[j], "en")
                                    } else {
                                        testCase.getTestStepAt(i).setPropertyValue(dynamicParametersToCheck[j], "nl")
                                    }
                                }
                            }
                            log.warn("Damnit.... TestCase: " + testCase.getName() + " - Step: " + (i + 1) + " - " + dynamicParametersToCheck[j] + " query parameter blank again...Probably SmartBear refactoring cleared this. parameterRefactoringBackup.groovy to the rescue: We fill it based upon the last 2 charachters in the step (or default to nl).")
                        } else {
                            try {
                                Matcher testStepInputRegex = Pattern.compile("(?<=\\().+?(?=\\))").matcher(testStepName)
                                String parameterFromTestStepName = testStepInputRegex[j]
                                testCase.getTestStepAt(i).setPropertyValue(dynamicParametersToCheck[j], parameterFromTestStepName)
                                log.warn("Damnit.... TestCase: " + testCase.getName() + " Step: " + (i + 1) + " - " + dynamicParametersToCheck[j] + " query parameter blank again...Probably SmartBear refactoring cleared this. parameterRefactoringBackup.groovy to the rescue: Take the " + (j + 1) + "th value from between the brackets in the test step name  = \"$parameterFromTestStepName\"")
                            }
                            catch (Exception ex) {
                                log.error "ERROR: Verify the test step from test case " + testCase.getName() + " has proper number of (value(s) between) \"(\" and \")\" brackets that match the number of dynamic parameters to check (=$numberOfDynamicParametersToCheck) vs testStepName $testStepName!"
                            }
                        }
    
                    }
                }
    
                for (int j = 0; j < numberOfHardCodedParametersToCheck; j++) {
                    String hardcodedParameterValue = testCase.getTestStepAt(i).getPropertyValue(hardCodedParametersToCheck[j])
                    //log.info "step " + (i + 1) + " for hardCodedParametersToCheck number " + (j + 1) + "/" + (numberOfHardCodedParametersToCheck) + " : parameter " + hardCodedParametersToCheck[j] + " with  parameterValue $hardcodedParameterValue"
                    if (hardcodedParameterValue == "") {
                        String testStepName = testCase.getTestStepAt(i).getName()
                        testCase.getTestStepAt(i).setPropertyValue(hardCodedParametersToCheck[j], hardcodedParameterValues[j])
                        log.warn("Damnit.... TestCase: " + testCase.getName() + " - Step: " + (i + 1) + " - " + hardCodedParametersToCheck[j] + " query parameter blank again.... Probably SmartBear refactoring cleared this. parameterRefactoringBackup.groovy to the rescue: We fill it based upon the " + j + "th provided hardcoded parameterValues = \"" + hardcodedParameterValues[j] + "\"")
                    }
                }
            }
        }
    }

     

  • richie's avatar
    richie
    Community Hero

    Hey mjlamora

    I haven't tried using thr Refactor functionality for a couple of years, but when i tried before it, it wiped out all the parm values, but that was with an earlier version of the functionality and it's matured quite a bit by the looks od things since i last tried.

    i've been reading the REST Refactoring help page (https://support.smartbear.com/readyapi/docs/apis/update/refactor-rest.html ) and in the content it states this -->> "In order not to lose the current value of the parameter, make sure to select the Keep existing value option in the subsequent Parameters Refactoring dialog."

    So i'd suggest trying to watch out for the "keep existing value" checkbox when doing the refactor. According to the instructions, that should work.

    Cheers,

    Rich

    • mjlamora's avatar
      mjlamora
      New Contributor

      Rich,

      Thanks for all of the input above. I see the "keep existing value" feature in the documentation as you've referenced, but the option to choose it never actually shows up when I'm (slowly and carefully!) going through the refactor steps.

      Per input from JoostDG below, it looks like it might be a bug still. 😕

      Thanks,

      MJL