[TechCorner Challenge #7] Change an XPath Match assertion to a JSONPath Match assertion
- 5 years ago
Task: Create a script to convert XPath Match assertion to JSONPath Match assertion for the REST test steps where the request URL is the following: https://example.com/test.
This is a solution created for [TechCorner Challenge #7]
Thanks, sonya_m! When I started as a tester, I realized the power groovy gave for automating even a lot of the manual processes of building tests within ReadyAPI. Having a degree on software engineering, I leaned hard on that and groovy and the api's of ReadyAPI itself to try to remove a lot of the menial parts of building a suite of tests. I love groovy and how much it helps!
That being said, I may have went down the more complicated path of looking at the xpath statement and I may have tried to solve a problem that wasn't there. The issue I ran into was the <e> element under tags, as that made me think that may be a listable element. While the example provided only one <e>, I went down the path of how I would write this if there were MORE than that. That's when things (to me) got really complex and hard to follow. I did come up with something, but I am not 100% comfortable with it. I either made it way too complex or made too many (potentially bad) assumptions.
Here's what I came up with:
def project = context.testCase.testSuite.project; def URL = "https://example.com/test"; for (ts in project.getTestSuiteList()) { for (tc in ts.getTestCaseList()) { for (step in tc.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep)) { // Was also stuck here. Is there an easier way to get the rest URL/URI of a REST test step? This method requires the REST step has been ran. // Seems like room for improvement. if (step.getHttpRequest().getResponse().getURL().toString().equals(URL)) { for (assertion in step.getAssertionList()) { if (assertion.getName().equals("XPath Match")) { def xpaths = assertion.getPath().toString().tokenize("\n"); def json = xpaths[1] // Strip the xpath response statement down to the necessary parts. This makes assumptions on the xpath string always matching the example other than indexed location of E. json = json.replace("//ns1:Response[1]/", "").replaceAll("ns1:", "").replace("tags[1]", "tags").replace("id[1]", "id"); // Split the xpath statement into an array for ease of modifying, using the / character as a delimiter json = json.tokenize("/"); // Assuming the xpath statement is always tags/e/id, the second spot in the array is the position of the <e> element we're concerned with. json[1] = (json[1].replaceAll("[A-z\\[\\]]","").toInteger() - 1).toString() // Rebuild the json path. json = json[0] + "[" + json[1] + "]." + json[2]; log.info(json); // def json = "tags[0].id"; // Get the expected content as a string def result = assertion.getExpectedContent().toString(); // Remove the offending assertion // step.removeAssertion(assertion); // Add new JSONPath assertion step.addAssertion("JsonPath Match"); def jsonAssertion = step.getAssertionByName("JsonPath Match"); // Set the path and the expected content jsonAssertion.setPath(json); jsonAssertion.setExpectedContent(result); } } } } } }