Calling Keyword from another Keyword not working good (Steps & Substeps)

Thanks soooooo much, you helped me a lot :slight_smile:

But still, how you hijack those internals? How to make Katalon Studio work with any of my modifications?
How you made your TestCaseExecutor work with Katalon Studio?

Do you create a plugin to use your own TestCaseExecutor?

And also, the code in that repository https://github.com/katalon-studio/katalon-studio-testing-framework
is probably already outdated, so when I make my modifications, it might not work correctly with the rest of the system. So I am curious how exactly you did it :smiley:

You have a misunderstanding. It is @Russ_Thomas who wrote “you can hijack the internals”, not me @kazurayam. I just pointed you to the URL of Katalon source codes.

Aha sorry, my bad :smiley:

Yes, you can easily find that the repository was last updated at Dec, 2020.

You are theoretically correct.

But I believe that the com.kms.katalon.core.main.TestCaseExecutor in the ver 8.1.0 would stay the same as the Dec 2020 version. So practically the Dec 2020 source code would be good enough to learn the internal of Katalon Studio.

Ok, thank you for your help, I appreciate it very much :slight_smile: :heart:

Just for your information, let me introduce one of my artifacts (published 2 years and 6 months ago) to you.

This artifact shows how I dynamically modified the internal of Katalon Studio using Groovy’s Metaprogramming technique.

I do not understand what you @peter.hevesi want to do, so I am not sure if this artifact is informative for you. May be not.

1 Like

I used the Groovy’s metaprogramming techinque in my Keyword class implementation. The class is invoked by the TestExecutor built-in Katalon Studio. Here comes a timing issue. Since the built-in TestExecutor object is already instantiated and in action, any Metaprogramming done by a TestCase (+custom keyword class) in action will never be able to modify the TestExecutor instance.

So, I believe, my article is NOT informative for you @peter.hevesi

It is totally informative, I can’ thank you enough :smiley:
There is no doubt we should call you Katalon King :smiley: :slight_smile:

Aha, you just wrote, that I can’t replace that instance :smiley:
Nevermind, maybe it won’t help me in what I am trying to achieve, but still I am very glad that you sent me that project :slight_smile:

But actually, what you are saying is, that I can’t replace TestExecutor from TestCase, because it is already created and running, but I probably should replace it from TestListener?
All I want to do is to modify the behavior of “logging and reporting” so to say and I want to do it gloabaly for each TestCase, so I actually think I may be able to do it :smiley:

I don’t think it is not likely. It depends on the life cycle of TestCaseExecutor, TestListener etc. These are controlled by the Katalon Studio’s core engine, of which source code is not publicly disclosed. Only Katalon team knows; we can not know it.

@duyluong

any comment?

But

you can try it.

I am sure, the team will say “Do it at your own risk, do not raise any questions about it”.

So you think it isn’t possible to do it even from TestListener? Because TestListener can run before TestCase

I still do not understand what you want to do. I am afraid, Katalon Team does not as well.

It would be pointless to talk about how to replace the TestCaseExecutor instance, before making it clear what you mean by saying “logging and reporting”.

I chose the word HIJACK deliberately - HIJACK does NOT mean REPLACE.

When a test case starts, you can seize control of what happens next. That is, you can HIJACK the normal progress of a test case wherein you might write your own reports and process your steps yourself.

// Imports...

// Start of test case under normal Katalon Executor control

try {

  // Steps ...

  // ...

  // This test is a pass
  passThisTest()

} catch (...) {
  // This test is a fail
  failThisTest()
}

// End of test case return to Katalon Executor control

The try-catch allows you to seize control of what happens during your test. You can execute test steps, call reporting functions and throw your own errors and exceptions.

That is the HIJACK - nothing is replaced.

Before the executor starts, you would use listeners to prepare for the test case. You might for example prepare a report file.

1 Like

I have some problems I want to solve:

  1. When I create custom keyword and throw exception in it, it still shows as passed in LogViewer, which is very strange. If there only is a way of marking that keyword in LogViewer as failed, but I can’ find any. I thought, that KeywordUtil should be used to mark keyword as passed in LogViewer, but it is not working at all. I just want failed “Steps” to be marked as failed, that’s actually all I want :smiley:

  2. When I create a keyword (I call it TestStep, because I call it directly in TestCase), inside which I call another keywords (I call them TestSubStep), I see only TestStep in LogViewer but I am not able to expand this Step to see substeps to be able to see exactly where it fails. Or this exact same pattern of TestStep & TestSubSteps I have, when I do POM, because it is a method, which calls some keywords but this method is then called from TestCase, and again, I can’t see exactly where it fails inside the method, I just see that whole method fails)

  3. There aren’t any TestData in TestReports, so I can’t see what where the actual data, the Test Case was called with when it fails.

I am heavily frustrated from Katalon Studio, because it is not working as it should.
Neither data-binding (because everything is binding as a string)[This problem I solved only partially] and nor these other problems I wrote above. I hope I can solve these problems with your trick :smiley:

I’m throwing StepFailedException. The Test Case is not passed - but maybe that’s because I handle the errors myself:

I do not see what you mean.
I need to see the code.
Could you make a small KS project where you put a custom keyword and a test case that calls it?

Somehow you can throw an Exception anywhere inside your TestSubSteps, TestSubSubSteps, TestSubSubSubSteps, … ; and catch that Exception in your TestCase and call:

try {
    call TestStep
} catch (Exception e) {
    e.printStackTrace()
}

In the printed StackTrace you would see the exact name of your keyword class and line# where you threw the Exception.

Isn’t it enough?

1 Like

The built-in Basic Report is designed to meet the needs of ordinary people. If it is not enough for you, you should develop your own one for yourself. Just for your reference, see the following post:



You want the LogViewer to show all the execution logs of a TestCase > what you call “TestSteps” > what you call “TestSubStep” > … .

I can mimic what you want to see. Please have a look at the following screenshot.

In the above “LogViewer”, you can find the names of TestSteps and TestSubSteps: “registerNewUser”, “setDate”, “checkMessage”. You enumerated these names in the original post

I suppose, this is what you want to see.

Here I attache a zip which contains a Katalon Studio project. You can reproduce the above LogViewer by executing the “Test Cases/TC1”.

peter_hevesi_wants_this.zip (38.0 KB)



The demo has a set of Test Cases.

  • TC1
  • modules/registerNewUser
  • modules/setDate
  • modules/checkMessage

These 4 names appear in the LogViewer because these are Test Cases. The LogViewer is designed to trace how Test Cases worked. …

Well, I should exchange the subject and predicate. Test Cases emits its execution log into the LogViewer; nothing else comes up in the “LogViewer” pane. The “classes” that work inside TestCases does not emit “Step Execution Logs”. Therefore you would not see the name “registerNewUser”, “setDate” and “checkMessage” if these are “classes” not “Test Cases”.


I do not think it is a good idea to make the LogViewer too much verbose because it makes tests run slow.

I did an experiment. I modified the TC1 silightly so that it calls the modules/registerNewUser 300 times repeatedly. I named it TC1_multitude.

// TC1_multitude
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase

import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

def members = [
	["Username": "Bob", "Password": ".S~2jM2PtnVd"],
	["Username": "Alice", "Password": ")u/t_nW!Af6%"],
	["Username": "Charlie", "Password": "D2B+J(FQWT4p"]
	]

def multitude = members * 100

multitude.each { cred ->
	WebUI.callTestCase(
		findTestCase("modules/registerNewUser"), 
		["Username": cred["Username"], "Password": cred["Password"]]
	)
}

When I ran this version, TC1_multitude took 12 minutes to finish.

It runs slow because Katalon Studio is forced to display so many lines of step execution logs. Displaying thousands of lines in the LogViewer consumes significant CPU load and takes long time to finish.

I would prefer implementing the “registerNewUser”, “setDate” and “checkMessage” as classes under the Keywords directory because classes don’t emit logs in the LogViewer at all.

I did an experiment. See the TC2 in the zip. The TC2 does calling the same scenario: call App.registerNewUser() method 300 times. When I ran the TC2, the LogViewer was quiet enough and finished in 1 minute.

Faster program is better than slow one. Isn’t it?

1 Like

Wow, you are so awesome man !!! Thanks soooo much for all your help!!! :slight_smile:
I will now try to process and learn all the information you gave me and try to solve my challenges and if I produce something that may be useful for others, I’ll definitely post it back to this wonderful community :slight_smile:
Thanks again bro :slight_smile: