ContextTrace --- Test Case script can get its own "Test Case ID"

I have published a GitHub Repository:


I have developed a utility class com.kazurayam.ks.ContextTrace for Katalon Studio project, which enables a Test Case script to get its own “Test Case ID” and other useful identifications programatically at runtime.

Prerequisites

  • You need Katalon Studio of version 10.0.0 or newer as this library was developed on v10 which restored the “Custom Keyword” feature for the Free version.

  • No Katalon Enterprise license is required to use this library

Where to download the jar

You can download the ks-context-trace-*.jar file from the Releases page of the GitHub project at

You need to manually put the jar into the Drivers folder of your Katalon project and reopen your project. See the doc “Library management in Katalon Studio”

Usage

create a TestListener

You need to create a TestListener in your Katalon project. The file could be named any. E.g, Test Listeners/SetupContextTrace.groovy.

You can copy and paste the following code (no change will be required):

import com.kazurayam.ks.ContextTrace
import com.kms.katalon.core.annotation.BeforeTestCase
import com.kms.katalon.core.annotation.BeforeTestSuite
import com.kms.katalon.core.context.TestCaseContext
import com.kms.katalon.core.context.TestSuiteContext

class SetupContextTrace {

    @BeforeTestSuite
    def beforeTestSuite(TestSuiteContext context) {
        ContextTrace.setTestSuiteContext(context)
    }

    @BeforeTestCase
    def beforeTestCase(TestCaseContext context) {
        ContextTrace.setTestCaseContext(context)
    }
}

This TestListener is essential for the com.kazurayam.ks.ContextTrace class to work properly.

Katalon Studio fires the beforeTestCase(TestCaseContext) and beforeTestSuite(TestSuiteContext) methods in the TestListener, which pass the context objects to the ContextTrace object. The ContextTrace object will memorize the context objects so that user’s TestCase scripts can referer to later when necessary.

write a Test Case that uses ContextTrace

Now you can use the ContextTrace anywhere in your Test Case scripts. For example, see

Test Cases/main/demo in the app project:

import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import com.kazurayam.ks.ContextTrace
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

/**
 * main/demo
 */

println "ContextTrace.getTestSuiteId(): " + ContextTrace.getTestSuiteId()
println "ContextTrace.escapedTestSuiteId(): " + ContextTrace.escapedTestSuiteId()
println "ContextTrace.getCurrentTestCaseId(): " + ContextTrace.getCurrentTestCaseId()
println "ContextTrace.getEscapedCurrentTestCaseId(): " + ContextTrace.getEscapedCurrentTestCaseId()
println "ContextTrace.getTestCaseIdStack(): " + ContextTrace.getTestCaseIdStack()
println "ContextTrace.escapedTestCaseIdChain(): " + ContextTrace.escapedTestCaseIdChain()

WebUI.callTestCase(findTestCase("main/demo_sub"), [:])

The Test Cases/main/demo calls Test Cases/main/demo_sub, which looks like this:

import com.kazurayam.ks.ContextTrace

/**
 * main/demo_sub
 */

ContextTrace.status()

When you run the Test Cases/main/demo, you will see the following messages in the Console tab of Katalon Studio:

lib-demo

  1. The statement ContextTrace.getTestCaseIdStack() returned an instace of java.util.Stack, which was stringified into

[Test Cases/main/demo, Test Cases/main/demo_sub]

. This reveals that Katalon Studio launched Test Cases/main/demo, which then called the Test Cases/main/demo_sub via WebUI.callTestCase(...) keword.

  1. The statement ContextTrace.escapedTestCaseIdChain() returned a string

main-demo,main-demo_sub

. This string was derived from the Stack instance that is returned by ContextTrace.getTestCaseIdStack().

  1. Please note that the returned value main-demo,main-demo_sub was derived from the Test Case ID strings while slightly translated.
  • The leading prefix Test Cases/ was chomped off

  • Forward slash character / was translated into a hypen -

  • Whitespace character was translated into a under bar _

  • A series of Test Cases chained by the callTestCase() keyword is converted into a flat string delimited by comma ,

  1. The string returned by ContextTrace.escapedTestCaseIdChain() is shorter and more compact than the original TestCaseIds.

  2. The string returned by ContextTrace.escapedTestCaseIdChain() is suitable for a file name, as it contains no special characters (<>:"/\|?*) which are prohibited as a part of file name in Windows.

  3. ContextTrace.getTestSuiteId() returns the Test Suite ID in which the current testcase belongs if the testcase was invoked by a wrapper Test Suite. If the testcase was executed directly without wrapping Test Suite, then ContextTrace.getTestSuiteId() will return null, ContextTrace.escapedTestSuiteId() will return an empty string “”.

API documentation

The API document of com.kazurayam.ks.ContextTrace is found here

What is the ContextTrace class useful for?

For example, when a test case in Katalon Studio takes a screenshot of browser, it is a good practice to save the PNG into a file named with the string returned by ContextTrace.escapedTestCaseIdChain(). The following document describes this idea with sample code:

Many other usecases you would be able to find. You can insert a string of escapedTestCaseIdChain into your RDB tables or No-SQL databases to record the test’s activities, that would make the records self-describing well.

History

This project succeeds my old project TestCaseStack. I have encapsulated my hack into a jar and published it.

1 Like

Hi there, and thanks for posting in the Katalon community! :hugs:

To help you faster, please review our guide on Custom Keyword here: Introduction to custom keywords in Katalon Studio | Katalon Docs. Double-checking the steps and configurations might resolve the issue.

If the doc doesn’t help, feel free to provide more details, and a community member will assist you soon. Thanks for being a part of our community!

Best,
Elly Tran

It is a good practice to name screenshot files with the Test Case ID

Katalon Studio provides a built-in keyword WebUI.takeScreenshot. This feature brings an itchy problem to me. Let me describe the problem and what I have done.

I have developed a Katalon project https://github.com/kazurayam/ContextTrace/tree/master/app. Let’s go through this sample project, which will proposes a untility class com.kazurayam.ks.ContextTrace.

Original sample code

As the document tells, the WebUI.takeScreenshot keyword takes an argument fileName, which is optional. What value will the fileName take as default? So let me check it hands-on. I created a testcase script

Also I made a test suite

The test suite calls the aforementioned testcase. When I ran the test suite, I got the result in the Reports folder.

$ tree Reports/20251004_204203
Reports/20251004_204203
└── TS
    └── 20251004_204203
        ├── 1759578150377.png
        ├── 1759578157116.png
        ├── 1759578166156.png
        ├── 1759578172001.png
        ├── 20251004_204203.csv
        ├── 20251004_204203.html
        ├── console0.log
        ├── execution.properties
        ├── execution.uuid
        ├── execution0.log
        ├── JUnit_Report.xml
        ├── testCaseBinding
        └── tsc_id.txt

3 directories, 13 files

As you see, the WebUI.takeScreenshot() generated a PNG file named with 13 digits appended with postfix .png, like 1759578150377.png.

What is 1759578150377? — It is the value of new java.util.Date().getTime(); the Current Epoch Unix Timestamp.

This file name tells me nothing what the PNG image presents. Therefore I can not re-use the PNG files named in this format. These PNG files are just useless for me.

Awkward solution

How can I give screenshot files better names? — It’s easy. As the doc WebUI.takeScreenshot tells, I can specify fileName as the 1st argument.

It is a good idea to name the screenshot files with the TestCaseId. I can do it easily. See the test cases source code:

...
WebUI.openBrowser(GlobalVariable.G_SiteURL)

WebUI.takeScreenshot('1-Main_Test_Cases-TC_Verify_Successful_Appointment_-_awkward.png')
...

When I ran the app/Test Suites/TS - awkward, I got the following output in the Console:

$ tree Reports/20251004_212933
Reports/20251004_212933
└── TS - awkward
    └── 20251004_212933
        ├── 1-Main_Test_Cases-TC_Verify_Successful_Appointment_-_awkward.png
        ├── 2-Main_Test_Cases-TC_Verify_Successful_Appointment_-_improved,Common_Test_Cases-Login_-_awkward.png
        ├── 20251004_212933.csv
        ├── 20251004_212933.html
        ├── 3-Main_Test_Cases-TC_Verify_Successful_Appointment_-_awkward.png
        ├── 4-Main_Test_Cases-TC_Verify_Successful_Appointment_-_awkward.png
        ├── console0.log
        ├── execution.properties
        ├── execution.uuid
        ├── execution0.log
        ├── JUnit_Report.xml
        ├── testCaseBinding
        └── tsc_id.txt

3 directories, 13 files

The PNG files are named better than the original code — the sequence number 1,2,3,4 followed by Test Case ID. Even in the case where 2 or more Test Cases are chained by WebUI.callTestCase() keyword, the file name contains the full information of the chained test cases.

But I hate the test case source code. It is a terrible idea to hard-code a string like "2-Main_Test_Cases-TC2_Verify_Successful_Appointment_-improved,Common_Test_Cases-Login-_awkward.png" in the script. Anyone can imagin, such string literals will make the maintenance job a nightmare.

Improved solution

The com.kazurayam.ks.ContextTrace class can improve my code. See the README how to introduce it. See the test cases source code:

....
WebUI.openBrowser(GlobalVariable.G_SiteURL)

WebUI.takeScreenshot('1-' + ContextTrace.escapedTestCaseIdChain() + '.png')
....

As you see, the test case source code now contains no lengthy string literal, which is replaced with a call to ContextTrace.escapedTestCaseIdChain(). This style makes the code much more maintainable.

When I ran the app/Test Suites/TS - improved, I got the following output in the Console:

$ tree Reports/20251004_213229
Reports/20251004_213229
└── TS - improved
    └── 20251004_213229
        ├── 1-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_improved.png
        ├── 2-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_improved,Common_Test_Cases-Login_-_improved.png
        ├── 20251004_213229.csv
        ├── 20251004_213229.html
        ├── 3-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_improved.png
        ├── 4-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_improved.png
        ├── console0.log
        ├── execution.properties
        ├── execution.uuid
        ├── execution0.log
        ├── JUnit_Report.xml
        ├── testCaseBinding
        └── tsc_id.txt

3 directories, 13 files

This output is just similar to the “awkward solution”.

Modularized solution

The “improved solution” generates 4 screenshot files. This means, the test case scripts repeats the following code 4 times:

WebUI.takeScreenshot('1-' + ContextTrace.escapedTestCaseIdChain() + '.png')

and

WebUI.takeScreenshot('2-' + ContextTrace.escapedTestCaseIdChain() + '.png')

and

WebUI.takeScreenshot('3-' + ContextTrace.escapedTestCaseIdChain() + '.png')

and

WebUI.takeScreenshot('4-' + ContextTrace.escapedTestCaseIdChain() + '.png')

I don’t like repeating myself as this. I want to make the code even simpler. I want to have a custom keyword that encapsulates the statements of calling WebUI.takeScreenshot and ContextTrace.escapedTestCaseIdChain(). So I made one more code set.

....
WebUI.openBrowser(GlobalVariable.G_SiteURL)

CustomKeywords.'my.Screenshooter.takeScreenshot'()
....

The my.Screenshooter class is a short Groovy class, as follows:

Calling my.Screenshooter.takeScreenshot() automates saving screenshot images into files properly named. It would require minimum maintenance efforts.

When I ran the app/Test Suites/TS - modularized, I got the following output in the Console:

$ tree Reports/20251004_213431
Reports/20251004_213431
└── TS - modularized
    └── 20251004_213431
        ├── 20251004_213431.csv
        ├── 20251004_213431.html
        ├── console0.log
        ├── execution.properties
        ├── execution.uuid
        ├── execution0.log
        ├── JUnit_Report.xml
        ├── snapshots
        │   ├── 1-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_modularized.png
        │   ├── 2-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_modularized,Common_Test_Cases-Login_-_modularized.png
        │   ├── 3-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_modularized.png
        │   └── 4-Main_Test_Cases-TC2_Verify_Successful_Appointment_-_modularized.png
        ├── testCaseBinding
        └── tsc_id.txt

4 directories, 13 files

This is the final result. I like it.

Conclusion

The com.kazurayam.ks.ContextTrace class enables Katalon Test Case scripts to get its own TestCaseId programatically. You can use the value returned by ContextTrace.escapedTestCaseIdChain() as a name of screenshot file. You would be able to find more usecases of it.

3 Likes