BDD with "variables" and multiple profiles

I’ve only quite recently jumped on the BDD+KatalonStudio bandwagon and am investing quite some time and effort into getting a solution up & running with BDD. Every now-and-then i notice that i have to do some customization for which i created some CustomKeywords. I also implemented a few Cucumber hooks, to do some magic to not pollute my feature/scenario’s.

But i think i’m beginning to take it too far with the “magic”. But i don’t see another solution yet. For which i’m posting this topic.I think the bottomline is that i want to use “Keyword” variables in my Feature files.

My situation is somewhat like this (fictive + simplified):

The company i work for develops+hosts a few searchengine-websites: Google, Yahoo and Bing.
I want to have BDD-tests for all these websites and usem them to test the various hosting-stages (local, test, acceptance, production).

To be able to directly run a Feature-file in Katalon-Studio targeting a specific website on a specific stage, i’ve chosen to have “per website” a profile “per stage”: Google - Acc, Google - Tst, etc…
This gives me the opportunity to define a profile-variable “baseUrl” to contain the host-name which varies per website+stage: www.google.local, tst.google.com, acc.google.com, www.google.com.

Some features are equal for all websites, but differ in a technical sense way. On Google the search-button to click has to be identified differently (id=‘btnSearch’) than the other search-buttons on the other sites. Per website i thus created “Test Objects”, which i then reference from the Profile as a variable “SearchButton”. In my step-code i can click on the SearchButton-TestObject. Other variables are equal for all stages for the same website. Which i prefer to have a defined only once.

You probably are seeing the complexity already.

I did get everything working by implementing a hook which runs before each Scenario by fetching the Variables from a specific Test Case and registering them as Global Variables. In the profile the variable “VariablesTestCaseID” is a String which contains the Test Case ID to get the variables from.

	@Before
	def beforeLoadVariables(Scenario scenario) {
		// Initialize the variables only once
		if (GlobalVariable.metaClass.hasProperty(GlobalVariable, "VariablesLoaded") == false) {
			custom.Helper.addGlobalVariable("VariablesLoaded",true)

			if (GlobalVariable.metaClass.hasProperty(GlobalVariable, "VariablesTestCaseID") == false) {
				return
			}

			TestCase testCase = TestCaseFactory.findTestCase(GlobalVariable.VariablesTestCaseID)
			def shell = new GroovyShell()
			for (int index = 0; index <= testCase.variables.size() - 1 ; index++) {
				Variable variable = testCase.variables[index]
				Object value = shell.evaluate (
					"import static com.kms.katalon.core.testdata.TestDataFactory.findTestData\n" +
					"import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint\n"+
					"import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase\n" +
					"import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject\n" +
					"return " + variable.defaultValue)
				custom.Helper.addGlobalVariable(variable.name,  value )
			}
		}
	}

This way i’m able to:

  • Directly run a Feature for a specific website on a specific stage (example: profile “Google - TST”)
  • Profile-variables have values which are website-and-stage-specific
  • In a “Dummy” Test Case per website, i can define variables which are equal on all stages for that website.
  • I can have one feature which can be ran against multiple websites on multiple stages but using website-specific Test Objects.

Any advice on how i can reduce the complexity?