Handling Static and Dynamic Test Objects With Katalon Studio
Test objects are crucial for building a successful automation project. Check out this article to learn more about handling static and dynamic test objects with the Katalon Studio.
Join the DZone community and get the full member experience.
Join For FreeTest objects are one of the most crucial parts of building a successful automation project. Some of them are static, meaning that they do not change at all, and some of them are dynamic and are dependent on some dynamically changing parameters. This tutorial shows you the different approaches for handling different types of test objects.
Requirements
You should be able to write your tests in the Script view. You should also know the basics of Java/Groovy.
Static Objects
Static objects are very easy to handle. Just go to Object Repository, choose New Test Object, and use your favorite selector — I prefer XPath, so all my examples will be for XPaths, but the approach is the same for other selectors. Save your element and use the Katalon static built-in method tofindTestElement(String pathInRepository)
get your Test Object.
Dynamic Objects
Dynamic objects are a bit trickier to deal with than static objects, but it is not so difficult as it may look like. There is a Katalon way to handle parameterized objects, but I want to introduce other possible approaches.
Define Your Test Object Directly in a Test Case
The easiest way to define a test object is to look at the sample code below:
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
String dynamicId = 'Katalon123'
String xpath = '//div[@id="' + dynamicId + '"]'
TestObject to = new TestObject("objectName")
to.addProperty("xpath", ConditionType.EQUALS, xpath)
WebUI.click(to)
Without counting the import statements, the first two lines are simple: create a String
variable and put it into another String
. The magic is happening on the next two lines. You create a new instance of TestObject
(let's call it). Then, you assign your selector to this new test object using the method addProperty(String selectorType, ConditionType type, String selectorValue)
. Finally, you use the test object directly in the default Katalon keywords. For details on ConditionType
, please refer to the API documentation.
Easy, isn't it? Well, yes, but there are also cons of this solution. It is hardly maintainable, especially when your XPath changes often and when you create the same test object in multiple test cases.
Create a Separate Keyword for Dynamic Selectors
A better way to handle dynamic selectors is to extract them into separate keywords. You can have several keywords in your test project, one for a single page or so. It is up to you.
I will show a simple keyword holding dynamic selectors.
package mypackage
public class MySelectors {
public static final String dynamicIdPath = '//div[@id="%s"]'
}
As you can see, it is the same path as in the previous example, but there is a small difference. Instead of using a variable, I use %s wildcard for the String.format()
method. Let's update our original test case accordingly.
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import mypackage.MySelectors
String dynamicId = 'Katalon123'
String xpath = String.format(MySelectors.dynamicIdPath, dynamicId)
TestObject to = new TestObject("objectName")
to.addProperty("xpath", ConditionType.EQUALS, xpath)
WebUI.click(to)
As you can see, the only change is on the line defining. If you are not familiar with String.format()
, please refer to the Java documentation.
Alternatively, you can use your own wildcard in the selector value. Then, useString.replace()
rather than the String.format()
.
public static final String dynamicIdPath = '//div[@id="<<dynamicId>>"]'
// a line in test case:
String xpath = MySelectors.dynamicIdPath.replace("<<dynamicId>>", dynamicId)
The advantage of storing dynamic selectors in separate keywords is that you keep all selectors in one place. When a selector changes, you change only one place instead of all tests where you use it.
Create a Method That Returns a Dynamic Test Object
Now, we extend the MySelectors
keyword by adding a new method to return TestObject
. This will eliminate a few lines of code in your test case, making it more maintainable.
package mypackage
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
public class MySelectors {
public static final String dynamicIdPath = '//div[@id="%s"]'
public static TestObject getMyTestObject(String selectorType, String selectorValue) {
TestObject to = new TestObject()
to.addProperty(selectorType, ConditionType.EQUALS, selectorValue)
return to
}
}
And, our test case will look like this:
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import mypackage.MySelectors
String dynamicId = 'Katalon123'
String xpath = String.format(MySelectors.dynamicIdPath, dynamicId)
WebUI.click(MySelectors.getMyTestObject("xpath", xpath))
As our new method returns the TestObject
, we can call it directly using the default Katalon keywords. In the test case, you do not have to worry about creating a new instance of the TestObject
. You can customize it however you want, you can add more parameters into this method (i.e. ConditionType), or you can simplify pass it using the TestObjectProperty
instance.
Conclusion
The main point of this tutorial is that there are several different approaches to deal with dynamic selectors. This tutorial presents a few examples (more or less difficult) that can help you with this topic. I am 100 percent sure that there are even more effective ways how to do it, I will be glad if you share your own approach in the comments below.
Published at DZone with permission of Marek Melocik. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments