I am working on my first feature file/selenium project.
I have created a feature file and runner class.
package cucumberpkg2;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions
(features="Features")
public class Runner {
}
I have the feature file test.feature
Feature: Login screen
Scenario Outline: Successful login
Given User is on Login page
When User enters valid UserName and Password
And Clicks the login button
Then User landed on the home page
But whenever I try to run the TestRunner class as a JUnit test, I get the error:
Test class not found in selected project.
Here is the solution to your Question:
As per the current documentation of Cucumber you may require to change the keyword Scenario Outline to Scenario in test.feature file.
Though you mentioned about TestRunner class but your code speaks about Runner class being implemented as public class Runner, be sure which class file are you executing as JUnit test.
You may require to change #CucumberOptions to #Cucumber.Options for previous versions (recent versions work with #CucumberOptions)
Put the following 2 parts in a single line as #Cucumber.Options
(features="Features")
As you would be mentioning #Cucumber.Options(features="Features") ensure that your feature file is placed inside Features sub-directory within the Project Directory.
So you will be having, test.feature file within Features sub-directory with the following code:
Feature: Login screen
Scenario: Successful login
Given User is on Login page
When User enters valid UserName and Password
And Clicks the login button
Then User landed on the home page
Your Runner class will look like:
import org.junit.runner.RunWith;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(features="Features")
public class Runner {
}
Finally when you will execute Runner class as a JUnit test you will see the following message on your console:
You can implement missing steps with the snippets below:
#Given("^User is on Login page$")
public void User_is_on_Login_page() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
#When("^User enters valid UserName and Password$")
public void User_enters_valid_UserName_and_Password() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
#When("^Clicks the login button$")
public void Clicks_the_login_button() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
#Then("^User landed on the home page$")
public void User_landed_on_the_home_page() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
These warnings can be taken care easily by implementing the glue options to Cucumber.
Let me know if this Answers your Question.
you need to provide full path of the feature file as mentioned below.
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/resources/com/gaurang/steps/demo.feature",
"src/test/resources/com/gaurang/steps/demo1.feature"
}
)
public class RunAllTest {
}
or if you have too many feature files the best way is to provide tags to feature file and then use those tags to run as mentioned below .
#userRegistrations
Feature: User Registration
RunAllTest.java
#RunWith(Cucumber.class)
#CucumberOptions(tags={"#userRegistrations"})
public class RunAllTest {
}
And you can use multiple tags
Related
I have a feature with a number of steps but the first one is the only working and the rest are working fine. Now when I add new steps to the same feature there not working either its very confusing. Its lis like half the feature is working but the other half is no working.
Please see test runner below:
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(features = "src/test/java/features", glue = {"stepDefinitions"})
public class TestRunner {
}
Folder structure:
Error message:
You can implement this step using the snippet(s) below:
#Given("Add Place Payload with {string} {string} {string}")
public void add_place_payload_with(String string, String string2, String string3) {
// Write code here that turns the phrase above into concrete actions
throw new io.cucumber.java.PendingException();
}
I am also getting a red exclamation mark on the feature:
I have 14 features in total.
One of them is for cleaning (teardown), so I want that to run in the end.
But when I run my suite, it actually runs in the middle and hence breaks the suite.
How can we run the features in a specific order?
If it's truly a one time execution at the end you could let JUnit take care of this step by adding #AfterClass
The below example shows where you can add your before and after code.
#RunWith(Karate.class)
#CucumberOptions(features = "classpath:features")
public class TestRunner {
#BeforeClass
public static void beforeClass() {
System.out.println("BEFORE");
}
#AfterClass
public static void afterClass() {
System.out.println("AFTER");
}
}
Currently the ordering of feature execution is down to the underlying Cucumber implementation.
Karate currently uses cucumbers MultiLoader to load the features from the file system or classpath.
The cucumber version is 1.2.5 as of karate release 0.8.1, and the ordering is determined by the Java ClassLoader.getResources https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResources(java.lang.String)
You're going to have to worry about your directory structure and the naming of files within the folders.
(On a side note, a cleaner way would be for each feature to be completely independent from other features).
If you really want to force the order of feature execution, a "Karate way" would be to execute just one feature, and have this feature call the features you want after each other i.e:
Specify the Runner to only execute your orchestrator feature:
#RunWith(Karate.class)
#CucumberOptions(features = "classpath:features/orchestrator.feature")
public class TestRunner {
#BeforeClass
public static void beforeClass() {
System.out.println("BEFORE");
}
#AfterClass
public static void afterClass() {
System.out.println("AFTER");
}
}
Define the test orchestrator that will call the other features in order:
Feature: Test orchestration feature
Scenario: Run all of the tests in order
* call read('first.feature')
* call read('second.feature')
* call read('third.feature')
Here are sample features that are called - first:
Feature: First feature
Scenario: First
* print "first"
second:
Feature: Second feature
Scenario: Second
* print "Second"
and third:
Feature: Third feature
Scenario: Third
* print "Third"
I am currently building a framework to test a Rest-API endpoint. As I am planning to write a lot of test cases, I decided to organize the project to allow me to reuse common Step Definition methods.
The structure is as follows;
FunctionalTest
com.example.steps
-- AbstractEndpointSteps.java
-- SimpleSearchSteps.java
com.example.stepdefinitions
-- CommonStepDefinition.java
-- SimpleSearchStepDefinition.java`
However when I try to call SimpleSearchSteps.java methods I get a NullPointerException
CommonStepDefinition Code
package com.example.functionaltest.features.stepdefinitions;
import net.thucydides.core.annotations.Steps;
import com.example.functionaltest.steps.AbstractEndpointSteps;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class CommonStepDefinition {
#Steps
private AbstractEndpointSteps endpointSteps;
#Given("^a base uri \"([^\"]*)\" and base path \"([^\"]*)\"$")
public void aBaseUriAndBasePath(String baseURI, String basePath) {
endpointSteps.givenBasepath(baseURI, basePath);
}
#When("^country is \"([^\"]*)\"$")
public void countryIs(String country)
{
endpointSteps.whenCountry(country);
}
#Then("^the status code is (\\d+)$")
public void theStatusCodeIs(int statusCode) {
endpointSteps.executeRequest();
endpointSteps.thenTheStatusCodeIs200(statusCode);
}
}
SimpleSearchStepDefinition.java
package com.example.functionaltest.features.stepdefinitions;
import net.thucydides.core.annotations.Steps;
import com.example.functionaltest.steps.EndpointSteps;
import cucumber.api.java.en.When;
public class SimpleSearchStepDefinition {
#Steps
private SimpleSearchSteps searchSteps;
#When("^what is \"([^\"]*)\"$")
public void whatIs(String what) {
searchSteps.whenWhatIsGiven(what);
}
}
Looks like you are missing holder class for Cucumber annotation, something like this you should have so that cucumber knows and identified that steps and features of yours:
#RunWith(Cucumber.class)
#CucumberOptions(
glue = {"com.example.functionaltest.features.steps"},
features = {"classpath:functionaltest/features"}
)
public class FunctionalTest {
}
Note that, in your src/test/resources you should have functionaltest/features folder with your .feature files according to this sample, you can ofc, change it by your design
Can you take a look at Karate it is exactly what you are trying to build ! Since you are used to Cucumber, here are a few things that Karate provides as enhancements (being based on Cucumber-JVM)
built-in step-definitions, no need to write Java code
re-use *.feature files and call them from other scripts
dynamic data-driven testing
parallel-execution of tests
ability to run some routines only once per feature
Disclaimer: I am the dev.
I solved this issue by using a static instance of RequestSpecBuilder in the AbstractEndpointSteps instead of RequestSpecification.
Therefore, I was able to avoid duplication of StepDefinitions and NPE issues altogether
I just created feature file which is open google and enter some values in search engine and validated the search result. Also, I created a steps class file which contains given, when, and then annotations. Now, I wanna create a test runner which is used to drive the steps class file according to story file. But In my case I wanna use TestNG instead of Junit framework. I googled there are several sites were explained how to integrate the Jbehave+Junit. But So, far I didn't find any site where is the combination of Jbehave+TestNG. Since I'm trying by myself I just need some clarity on this. Can somebody give me a sample code which help me to understand better.
Please find Sample Story:
scenario: Check the google search engine
Given : Open the google home page www.google.com
When : Enter test automation in search box
Then : Proper result should be displayed in results page
Steps class file:
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class GoogleSearchEngine {
public static WebDriver driver;
#Given("Open the google home page $url")
public static void openUrl(String url) throws Exception {
try {
driver = new FirefoxDriver();
driver.get(url);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#When("Enter $searchKeyword in search box")
public static void searchKeyword(String searchKeyword) throws Exception {
try {
driver.findElement(By.xpath(".//*[#id='gs_htif0']")).sendKeys(searchKeyword);
driver.findElement(By.xpath(".//*[#id='tsf']/center/input[1]")).click();
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Then("Proper result should be displayed in results page")
public static void result() throws Exception {
try {
driver.quit();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Then I need to develop testrunner which used to drive the story file.
Can somebody help me to create a test runner class file using TestNG framework?
I had to do something similar recently and was pleasantly surprised to discover it was NBD. See my answer to another SO JBehave question for sample code describing how to setup JBehave. From there, simply create a testNG suite file for your JBehave tests like so:
<test name="all JBehave tests">
<packages>
<package name="com.foo.tests.jbehave.test1"/>
<package name="com.foo.tests.jbehave.test2"/>
<package name="com.foo.tests.jbehave.test3"/>
</packages>
</test>
Remember that the JBehave's JUnitStory and JUnitStories make JBehave stuff look like JUnit stuff, so from TestNG's perspective, it's just running JUnit stuff. One thing to watch out for is integrating reporting between the two.
I think I have misunderstood something about the Play 2 framework.
In my Application Controller I fetch a Company object from the DB
and I would like to make some operations on it in my view.
companyView.scala.html:
#(company: Company)
#main("Welcome to Play 2.0") {
<h1>#{company.name}</h1>
}
Application Controller:
package controllers;
import models.Company;
import play.*;
import play.mvc.*;
import views.html.*;
public class Application extends Controller {
public static Result company(String rest) {
Company company =
Company.find.where().ilike("restfulIdentifier.identifier", rest).findUnique();
return ok(companyView.render(company));
}
}
But return ok(companyView.render(company)); results in compilation error since companyView.render wants a string.
If I look at the forms sample application:
/**
* Handle the form submission.
*/
public static Result submit() {
Form<Contact> filledForm = contactForm.bindFromRequest();
if(filledForm.hasErrors()) {
return badRequest(form.render(filledForm));
} else {
Contact created = filledForm.get();
return ok(summary.render(created));
}
}
There is no problem with rendering an object. I guess that the solution is fairly simple and
that I have missed some crucial part of the documentation. Please explain this to me!
My steps in this case would be as follows:
Change the scala template, we hve to tell the scala templates the our Company belongs to the model class: (but also change to #company.name as suggested by Jordan.
#(company: models.Company)
#main("Welcome to Play 2.0") {
<h1>#company.name</h1>
}
run command play clean
Then run play debug ~run
By executing play debug ~run you will trigger to compile the the play application on each SAVE of one of your project files.
NOTE: The Play templates are basically functions. These functions needs to be compiled and everything used in these functions needs to be declared before use. Just as in regular Java development.
The fact that the your render object wants a string could be the result of:
#(company: Company) could not be resolved to the model Company.
The last compilation had a #(company: String)
Good luck!
I don't know if this will fix your problem or not but it's worth a try. Try removing changing:
#{company.name}
to:
#company.name