Using a NewTestListener in a keyword util class

Important context

Long ago, I followed these steps to create a test listener.

I have since then, some time ago, split out two important methods, that are needed in test suite setup/teardown hooks: setUpDriver() and closeDriver().

I can use these successfully in a test suite setUp() or tearDown() method hook, for example:

@TearDown
def tearDown() {
	NewTestListener listener = new NewTestListener();
	
	listener.setUpDriver();
	PracticePage.DeleteContractsIfNeeded(GlobalVariable.practiceProfile);
	
	GlobalVariable.practiceProfile = defaultProfile;
	PracticeProfileHandler.GetInstance().close();
	
	listener.closeDriver();
	
}

OK, what’s the problem?

Problem is that I am using these across multiple test suites, just jumped back into reviewing my code for two of the test suites whose tearDown methods I had to update…

…and to do that update, I had to open another test suite that’s using the NewTestListener in their methods, just to copy and paste the NewTestListener stuff…

It’s time to abstract that out!

I try that…

// all the other imports
import NewTestListener;

public final class SMDTestCaseUtils {
    // ...other methods in this class...

    public static void DoListenableAction(Closure onAction) {
        NewTestListener listener = new NewTestListener();

        listener.setUpDriver();
        onAction();

        listener.closeDriver();
    }
}

After the attempt, I face the error:

Groovy:unable to resolve class NewTestListener

I know that this NewTestListener that Katalon created for me, is in default package…my utils class, obviously is not…

…so what is the issue with bringing it in the test case utils keyword class?

Welp, it looks like I found my answer: what I am trying to do, literally is not possible with Groovy / Java.

I sure hope that I am wrong on this…because alternative would be what? Writing some separate util class/method in that default package, just to be able to touch the NewTestListener?

1 Like

I do not understand the way you use TestListener at all.

What I usually do is to create Test Listeners/TL1 with code like

import com.kms.katalon.core.annotation.AfterTestSuite
import com.kms.katalon.core.annotation.BeforeTestSuite
import com.kms.katalon.core.context.TestSuiteContext

class TL1 {
	
	@BeforeTestSuite
	def beforeTestSuite(TestSuiteContext testSuiteContext) {
		setupDriver()
	}

	@AfterTestSuite
	def afterTestSuite(TestSuiteContext testSuiteContext) {
		closeDriver()
	}
	
	def setupDriver() {
		// do something for WebDriver
	}
	
	def closeDriver() {
		// do something for WebDriver
	}
}

And let me assume I have multiple Test Suites: TS1, TS2 and TS3.

When I run TS1, then Katalon Studio will automatically invoke TL1’s @BeforeTestSuite-annotated method before executing TS1, and will invoke TL1’s @AfterTestSuite-annotated method after TS1 finished.

When I run TS2, then Katalon Studio will automatically invoke TL1’s @BeforeTestSuite-annotated method before executing TS2, and will invoke TL1’s @AfterTestSuite-annotated method after TS2 finished.

When I run TS3, then Katalon Studio will automatically invoke TL1’s @BeforeTestSuite-annotated method before executing TS3, and will invoke TL1’s @AfterTestSuite-annotated method after TS3 finished.

Here I would NOT use Test Suite’s @SetUp and @TearDown hooks at all, because Katalon Studio invokes TL1’s @BeforeTestSuite and @AfterTestSuite hooks for every test suites.

@mwarren04011990

I do not understand why you want to utilize Test Suite’s @SetUp and @TearDown hooks.

The thing here, and the primary reason why we’re doing some setup of the web driver ourselves, is because of business concerns that were established well before, and during the time that, I got my hands on this project: that we have to set up the web driver with some custom options, before we can open up any windows.

Now, it just so happens that we have some test suites, that I have written to clean up after themselves. That, of course, requires the following:

  • test suite setUp()
    • if we need to fetch some initial number of records in the system:
      • set up the web driver
      • do that unit of work (i.e. get the initial number of records in the system)
      • close the web driver
  • test suite tearDown()
    • set up the web driver
    • do some unit of work (i.e. delete any records that were left behind)
    • close the web driver

The set up and tear down concerns vary from test suite to test suite, with some of the test suites not needing to set up the web driver prior to first test case start (which is going to do that anyways), and others not needing to even do that in the tear down!

Currently you have setupDriver() and closeDriver() methods as a part of a TestListener class.

Alternatively you can externalize the setupDriver() and closeDriver() methods as a utility class with some valid package name; e.g, “com.foo.DriverUtil”. You can locate the DriverUtil class in the Keywords folder.

Both of the TestListener and the TestSuites’ hooks should be able to call DriverUtil class.

In this way, you can workaround the difficulty caused by “default package” of TestListener. — Is it what you want?

1 Like

Thanks! Ima do this, as it will separate concerns!

The programmer in me should have had this as instinct!