Let's talk Meta Programming to automatically refactor test cases in SOAPUI
One of SOAPUI's most powerful features and certainly my favourite is using Groovy forMeta-Programmingto factor and enhace my tests. I thought I would share the latest meta-coding script I've added to myReusable Script library. This script can be used to enhance and cleanup a TestSuite that is created automatically using the built in feature Interface -> Generate TestSuite. I import quite a lot of my REST API and this approach saves me a lot of grunt work. Script Features: Renames each RestReqest from "Request N" to something more appropiate following a basic BDD syntaxusing the HTTP Method and the resource description to provide appropriate description. e.g. "Request N" using a "HTTP GET /account" becomes "When /account is Retrieved" If the TestCase contains multiple requests these are split into new approriately named TestCases using the above convention to comply with the automated testing best practice of testing one thing at a time. Adds an Groovy script forGiven and Thenaround each Request step in each TestCase. To use this script. Define a Library TestSuite in the root of the project you want to refactor. Disable theLibraryTestSuite so that it doesn't get run in an uncontrolled manner. Define Meta-Programming Testcase to get this: Create a Groovy script in Meta-Programming and add the following code: Then simply run the Refactor Generate Tests. refactorGeneratedTests(testRunner.testCase.testSuite.project) cleanUp(testRunner.testCase.testSuite.project) def refactorGeneratedTests(def thisProject) { assert thisProject log.info "Processing ${thisProject.name}" for (testSuite in thisProject.testSuiteList) { if (!testSuite.isDisabled()) { log.info "- ${testSuite.name}" for (testCase in testSuite.testCaseList) { if (!testCase.isDisabled()) { log.info "-- ${testCase.name}" renameRequestSteps(testCase) forEachRequestMake(testCase) ensureBdd(testCase) } } } } } def renameRequestSteps(testCase) { assert testCase assert testCase instanceof WsdlTestCase def languageMap = [ "GET": 'Retrieved', "POST": 'Created', "PUT": "Updated", 'DELETE': 'Deleted'] log.info "languageMap : ${languageMap}" boolean isFirst = true for (testStep in testCase.testStepList) { log.info "--- ${testStep.name} ${testStep.getClass().getSimpleName()}" if (isREST(testStep)) { if (testStep.label.startsWith("Request")) { String restOperation = testStep.getOperation().getName() log.info "restOperation : " + restOperation String methodType = testStep.getRestMethod().getMethod() log.info "methodType : ${methodType}" actionName = languageMap.get(methodType) log.info "actionName : ${actionName}" String newStepName = "When ${restOperation} is ${actionName}" log.info "${newStepName}" testStep.setName(newStepName) } } } } def forEachRequestMake(testCase) { assert testCase assert testCase instanceof WsdlTestCase def languageMap = [ "GET": 'Retrieve', "POST": 'Create', "PUT": "Update", 'DELETE': 'Delete'] log.info "languageMap : ${languageMap}" boolean isFirst = true for (testStep in testCase.testStepList) { log.info "--- ${testStep.name} (${testStep.getClass().getSimpleName()})" if (isREST(testStep)) { String restOperation = testStep.getOperation().getName() log.info "restOperation : " + restOperation String methodType = testStep.getRestMethod().getMethod() log.info "methodType : ${methodType}" actionName = languageMap.get(methodType) log.info "actionName : ${actionName}" String newTestCaseName = "${actionName} ${restOperation} " log.info "${newTestCaseName}" if (isFirst) { testCase.setName(newTestCaseName) isFirst = false } else { // clone the test for each REST request testCase.testSuite.cloneTestCase(testCase, newTestCaseName); } } } } def ensureBdd(testCase) { assert testCase assert testCase instanceof WsdlTestCase givenStep = "Given content for the request" if (testCase.getTestStepByName(givenStep) == null) { testCase.insertTestStep("groovy", givenStep, 0) } thenStep = "Then the response is as expected" if (testCase.getTestStepByName(thenStep) == null) { testCase.addTestStep("groovy", thenStep) } } def isREST(def testStep) { assert testStep return testStep instanceof RestTestRequestStep; } def addHttpStatusAssertions(testStep) { assert testStep return testStep instanceof RestTestRequestStep; if (testStep.getAssertionCount() == 0) { testStep.addAssertion("Valid HTTP Status Codes").setCodes("200") testStep.addAssertion("Invalid HTTP Status Codes").setCodes("400, 500") } log.info testStep.getAssertionList() } def cleanUp(def thisProject) { assert thisProject log.info "${thisProject.name}" for (testSuite in thisProject.testSuiteList) { log.info "- ${testSuite.name}" for (testCase in testSuite.testCaseList) { log.info "-- ${testCase.name}" String actionName = testCase.name.split().head() log.info "-- ${actionName}" for (testStep in testCase.testStepList) { log.info "--- ${testStep.name} ${testStep.getClass().getSimpleName()}" if (isREST(testStep)) { if (testStep.name.contains(actionName)) { log.info("keep ${testStep.name} in ${testCase.name}") } else { log.info("remove ${testStep.name} from ${testCase.name}") testCase.removeTestStep(testStep) } } } } } } // https://www.soapui.org/apidocs/com/eviware/soapui/impl/wsdl/teststeps/RestTestRequestStep.html // class com.eviware.soapui.impl.wsdl.WsdlProject // class com.eviware.soapui.impl.wsdl.WsdlTestSuite // class com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase // class com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep log.info context.getClass() log.info testRunner.getClass() log.info testRunner.testCase.getClass() log.info testRunner.testCase.testSuite.getClass() log.info testRunner.testCase.testSuite.project.getClass() log.info testRunner.testCase.testSuite.project.workspace.getClass() import com.eviware.soapui.impl.wsdl.WsdlTestSuite import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep871Views0likes0Comments