Running Cucumber and Spring boot in Main class - java

My requirement is to run Cucumber test cases using Spring boot to run through a Custom java main class.
I am able to run Cucumber test suite fine if i am using following config class:-
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {
"html:target/cucumber-html-report",
"json:target/cucumber.json", "pretty:target/cucumber-
pretty.txt",
"usage:target/cucumber-usage.json", "junit:target/cucumber-
results.xml" },
features = { "src/test/resources" },
tags = {"#passed"},
glue = "cucumberTest.steps")
public class RunGwMLCompareTests {
}
And following class to load
#RunWith(SpringRunner.class)
#ActiveProfiles("dev")
#SpringBootTest(classes = Application.class)
public class AbstractDefinitions {
public AbstractDefinitions() {
}
}
And when i run RunGwMLCompareTests class,Now using this config my Cucumber test cases are running , It loads my Spring boot context and then exceutes all cases defined in feature.
Now my issue is that i want to run this from seperate main java class. I have created my java class as follows :-
package cucumberTest;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CucumberMainTest {
public static void main(String[] args) throws IOException {
ClassLoader classLoader = CucumberMainTest.class.getClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new
ResourceLoaderClassFinder(resourceLoader, classLoader);
List<String> pluginList = new ArrayList<>();
pluginList.add("--plugin");
pluginList.add("html:target/cucumber-html-report");
pluginList.add("--plugin");
pluginList.add("json:target/cucumber.json");
RuntimeOptions ro = new RuntimeOptions(pluginList);
ro.getFilters().add("#passed");
ro.getFeaturePaths().add("src/test/resources");
ro.getGlue().add("cucumberTest/steps");
cucumber.runtime.Runtime runtime = new
cucumber.runtime.Runtime(resourceLoader, classFinder, classLoader,
ro);
runtime.run();
}
}
It executes my test cases but does not load my SpringContext, as a result no spring beans are loadedand i get null pointer exception.. Any help is geatly appreciated.
Regards,
Vikram Pathania

One solution i found was to run RunGwMLCompareTests class from outside which handles my Spring context automatically.
So basically i am using gradle to create batch file which does nothing but automatically creates a batch with all relative depencies in my class path and then run following command:
"%JAVA_EXE%" -classpath "%CLASSPATH%" org.junit.runner.JUnitCore
cucumberTest.runners.RunGwMLCompareTests
where,
JAVA_EXE=C:\Program Files\Java\jdk1.7.0_65/bin/java.exe
And CLASSPATH is lib folder where all jars are present.
CLASSPATH=%APP_HOME%\lib\*.jar
Now running this batch i am using
features = { "src/test/resources" } <tag>
to put my feature files outside so that it can edited on the fly.
I hope this helps somebody out there.
by doing this , i am able to run RunGwMLCompareTests class.
Now using this config my Cucumber test cases are running and It also loads my Spring boot context and then exceutes all cases defined in feature.
Regards,
Vikram Pathania

Related

Cucumber hooks are not running. I am using io.cucumber.java8

I am trying to run steps required before and after the scenarios using Cucumber hooks, but the methods in hooks class are not running. Below is the hooks class.
Used dependencies :
<cucumber.version>6.11.0</cucumber.version>
package com.neobank.hooks;
import com.neobank.core.Driver;
import io.cucumber.java8.En;
public class ScenarioHooks implements En {
public ScenarioHooks() {
Before(Driver::startAppiumDriver);
After(Driver::resetApp);
After(Driver::stopChromeDriver);
}
}
Glue Path:
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"pretty", "html:target/cucumber.html",
"json:target/cucumber.json"},
features = {"src/test/resources/features"},
glue = {"com.neobank.steps", "com.neobank.hooks"},
tags = "#Onboardingtwo"
Found out the issue here. Was trying to run the cucumber scenarios individually from feature files. If hooks are to be executed then we have to run using the runner file.

Unable to load properties with Java Spring

I am a complete newbie to Spring. I am trying to figure out how to access properties from props files injected into my app through Spring.
I wrote a simple test provided below. I run it by passing location of the properties file through environment variables provided at JRE options
$ mvn test -DSPRING_CONFIG_NAME=my_spring \
-DSPRING_CONFIG_LOCATION=file:///Users/desilets/Documents/conf
Here is the content of the my_spring.properties file
$ cat /Users/desilets/Documents/conf/my_spring.properties
my.spring.greeting=hello world
When I run the test, it fails. Yet the output indicates that the environment variables were well received:
SPRING_CONFIG_NAME=my_spring
SPRING_CONFIG_LOCATION=file:///Users/desilets/Documents/conf
greeting=null
What am I doing wrong?
Thx.
---- Code for the test ---
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
public class AccessPropertiesTest {
#Value("${my.spring.greeting}")
String greeting;
#Test
public void test__LoadProperties() throws Exception {
System.out.println("SPRING_CONFIG_NAME="+
System.getProperty("SPRING_CONFIG_NAME"));
System.out.println("SPRING_CONFIG_LOCATION="+
System.getProperty("SPRING_CONFIG_LOCATION"));
System.out.println("greeting="+greeting);
Assert.assertEquals(
"The property my.spring.greeting was not read correctly",
greeting, "hello world");
}
}
If its a spring project there would be two locations for properties
src/main/resources
src/test/resources
If you run tests it will pick from src/test/resources.
#RunWith(SpringRunner.class)
#DataJpaTest
public class AccessPropertiesTest {
#Value("${my.spring.greeting}")
String greeting;
.....
}
refer https://www.baeldung.com/spring-boot-testing
add: my.spring.greeting=anyValue into application.properties or application.properties.yaml file

Cucumber Runner Class not running Step Definitons

I am writing automated tests with Cucumber and Java.
I can run the step definitions by right-clicking on my Feature file, and running it as a Cucumber Feature, and all steps pass successfully.
But, I need to run them using a Runner Class.
My feature file is in this folder:
src/test/java/features
And my step definitons are in this folder:
src\test\java\com\abc\commercial\def\automation
My Runner Class is also stored in
src\test\java\com\abc\commercial\def\automation
And here is the Runner Class code:
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"progress",
"html:build/report/html",
"junit:build/report/junit/cucumber-report.xml",
"json:build/report/json/cucumber-report.json"
},
glue = {"src\\test\\java\\com\\abc\\commercial\\def\\automation"},
features = {"src/test/java/features"}
)
public class QARunner {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
When I run the Runner Class as a JUnit Test, I receive the following response in the console:
UUUUUUUUU
Undefined scenarios:
src/test/java/features/US46052
src/test/java/features/postFeatures.feature:43 # As the
2 Scenarios (2 undefined)
9 Steps (9 undefined)
0m0.303s
You can implement missing steps with the snippets below:
#Given("the Application...")
public void the_Application...() {
So the step definitions are not being picked up.
Does it have something to do with where my test runner is located?
I don't think it is picking up the step definitons in the automation folder
Thanks for any help
Try this : No need for main method. glue option should be in package style.
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"progress",
"html:build/report/html",
"junit:build/report/junit/cucumber-report.xml",
"json:build/report/json/cucumber-report.json"
},
glue = {"com.abc.commercial.def.automation"},
features = {"src/test/java/features"}
)
public class QARunner {
}

Unit Testing with different behaviour on existance of a file

There are some cases that the software shall behave differently according to some environmental conditions, for example whether a file exists at some place or not.
In my case, I'm developing a library, and it is configured according to a configuration file in classpath, (and falls back to default behavior if the config file does not exists).
How shall I unit test this class?
I need to write tests for evaluating the class in following cases:
the file does not exists on classpath
the file with content A exist on classpath
the file with content B exist on classpath
But I don't know how to configure environment to justify all of them. And execute the test one after each other.
By the way I'm using Java, and I have both JUnit and TestNG on the test classpath.
Edit:
One of the problems is that the config file resides in classpath, so if the normal ClassLoader finds and loads it, it returns the same content as long as the same class loader is used.
And I believe using a custom ClassLoader for testing is so complicated, that it needs tests to validate the tests!
You can use a temporary file created by your test to mock out the path in your class.
ConfigurationTest.java:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeThat;
import java.nio.file.Files;
import org.junit.Test;
public class ConfigurationTest {
private Configuration config = new Configuration();
#Test
public void testWithConfigFile() throws Exception {
config.configFile = Files.createTempFile("config_",".ini");
config.configFile.toFile().deleteOnExit();
assertFalse(config.isInDefaultMode());
}
#Test
public void testWithoutConfigFile() throws Exception {
assumeThat(Files.exists(config.configFile), is(false));
assertTrue(config.isInDefaultMode());
}
}
Configuration.java:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Configuration {
Path configFile = Paths.get("config.ini");
public boolean isInDefaultMode() {
return !Files.exists(configFile);
}
}

Cucumber:- Unable to generate step definitions by running feature file as well as testrunner class

I am trying to generate the step definitions from my feature file and as well as I have also designed test runner class but upon execution both give output on console as :-
0 scenarios
0 steps
0m0s.000s
Even though my feature file contains scenarios and steps.
Remove the colon (:) after the keywords (Given, When, etc) in your feature file.
Since you haven't shared any code or much details as to what you've done the only assumption that I can make is you have done something wrong in your testrunner class.
#RunWith(Cucumber.class)
#CucumberOptions(
features = "Feature"
,glue={"stepDefinition"}
)
public class TestRunner {
}
in the features make sure the path to your feature files is correct. i.e. if they are stored at some other directory, provide the path for the same
Ex: features = {"src/test/java/features"}
Also, please share your project structure, your feature file and your testrunner class code if possible in case this doesn't work for you.
Actually my runner class file looks like this:-
package runner;
import org.testng.annotations.Test;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
#CucumberOptions(features={"src//test//resources//featurefiles"},glue= {"im801clsteps"},plugin={"html:target/cucumber-html-report",
"json:target/cucumber.json", "pretty:target/cucumber-pretty.txt"})
#Test
public class MainRunner extends AbstractTestNGCucumberTests {
}
And I am using testng not junit to run my tests,please let me know why I am wrong?

Categories