I have following scenario outline
Background:
Given customer is in hot or not page
Scenario Outline: Hot article
And customer enters <name>
And submits
And customer clicks thumbs up
Then ensure the TBD
Examples:
| name |
| Elliot |
| Florian |
and following step implementation -
#And("customer enters <name>")
public void customer_enters_name(String name) throws Throwable {
// Express the Regexp above with the code you wish you had
Thread.sleep(10000);
}
But when I execute test then I get following error -
You can implement missing steps with the snippets below:
#Given("^customer enters Elliot$")
public void customer_enters_Elliot() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
#Given("^customer enters Florian$")
public void customer_enters_Florian() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Did I implement test steps wrong?
Instead of
Scenario Outline: ...
And customer enters <name>
...
Do this (Note the double quotes)
Scenario Outline: ...
And customer enters "<name>"
...
Just to add, The same error arise when in the runner class ,we put the wrong package of the step class
#CucumberOptions(glue = {"com.wrongpackage.step"})
public class TestRunner{
}
Step class should be present and the package should be correct.
Related
I am trying to print the current step being executed in Cucumber. I am using a custom formatter to print the step definition. However, I also want to print the current adverb (Given, When, Then, And...) that is being executed. I might be missing something as well, is it possible in Cucumber? Here is my code:
Formatter:
public class MyCucumberFormatter implements ConcurrentEventListener {
#Override
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, runStartedHandler);
}
private EventHandler<TestStepStarted> runStartedHandler = new EventHandler<TestStepStarted>() {
#Override
public void receive(TestStepStarted event) {
startReport(event);
}
};
private void startReport(TestStepStarted event) {
if (!(event.testStep instanceof PickleStepTestStep)) {
return;
}
PickleStepTestStep testStep = (PickleStepTestStep) event.testStep;
log("Step: " + testStep.getStepText());
}
}
Example scenario:
Scenario: Test user life cycle: create user, activate and delete
Given A valid admin logs in
When Admin creates new user
And User is activated
Then User should successfully login
Right now, it prints as:
A valid admin logs in
Admin creates new user
User is activated
User should successfully login
I want it to print as:
Given A valid admin logs in
When Admin creates new user
And User is activated
Then User should successfully login
You can't do this in v4.x yet but you can do this in v5.0.0-RC1 by going through pickleStepTestStep.getStep().getKeyWord()
I am writing Gherkin test cases and Java step definitions in my project. I am new to Gherkin and trying to understand the meaning of nested steps. Can you please help me to understand if the 2nd scenario given involves nested steps?
In my example, I would like to reuse 1st scenario code in 2nd scenario given statement logic. Is there a best way to reuse or rewrite the logic?
Note: Below example is written just to explain my question. It may not be a good Gherkin.
Background:
Given The application is opened
Scenario: Successful Login
Given the user name and password are entered
When login button is clicked
Then user login is successful
Scenario: Add Address Successful
Given user login is successful
And Add Address button is clicked
And user city, country are entered
when Submit button is clicked
Nested steps refer to calling defined steps inside a "main" one. In your example, the first scenario has the login functionality, which will / can be used in all other scenarios that require the user to be logged in.
So, the second scenario will have a Given step which calls the login action / steps of the first scenario. There are multiple ways to do this:
1. If you are defining those steps in the same class, it's just a matter of calling the same methods inside a different step / method.
Like so:
public class TestStepsOne {
// Steps from first scenario
#Given("^the user name and password are entered$")
public void enterUsernamePassword() throws Throwable {
System.out.println("User and password entered");
}
#When("^login button is clicked$")
public void clickLoginButton() throws Throwable {
System.out.println("Clicked login button");
}
#Then("^user login is successful$")
public void isLoggedIn() throws Throwable {
System.out.println("Logged in!");
}
// All together
#Given("the user is logged in")
public void loginSuccessfully() throws Throwable {
enterUsernamePassword();
clickLoginButton();
isLoggedIn();
}
}
Now you can use the Given the user is logged in in any scenario, and it will perform the login action.
2. Using Picocontainer -> details here
First you need to add these dependencies to your pom.xml:
<dependency>
<groupId>org.picocontainer</groupId>
<artifactId>picocontainer</artifactId>
<version>2.15</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>1.2.5</version>
</dependency>
You can separate your step definitions.
Like so:
public class TestStepsOne {
// Same as above, without the nested one
}
and second class:
public class TestStepsTwo {
private final TestStepsOne testStepsOne;
public TestStepsTwo(TestStepsOne testStepsOne) {
this.testStepsOne = testStepsOne;
}
#Given("the user is logged in")
public void loginSuccessfully() throws Throwable {
testStepsOne.enterUsernamePassword();
testStepsOne.clickLoginButton();
testStepsOne.isLoggedIn();
}
}
3. Using cuke4duke -> details here , includes examples
Like so:
public class CallingSteps extends Steps {
public CallingSteps(StepMother stepMother) {
super(stepMother);
}
#When("^I call another step$")
public void iCallAnotherStep() {
Given("the user is logged in"); // This will call a step defined somewhere else.
}
}
Hope this helps
I am using Scenario Outline with Examples. Examples have many rows. E.g. 10 rows. I have an After hook where I check the outcome of scenario passsed or failed and write it to a file. Now I need to save and close that file after executing the final row. How can I determine if the current scenario is the last one?
One option would be to tag the last example explicitly and have an After hook for that tag, as follows:
#others
Examples:
|input|
| abc |
| xyz |
#last
Examples:
|input|
| pqr |
#After("#last")
public void afterScenario() {
}
You would need something like an #AfterAll Hook, this is currently not supported in cucumber, but you can use this workaround which uses a jvm shutdown hook. :
static void addShutdownHook(WebDriver driver) {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
// DO STUFF LIKE SAVING YOUR FILE
driver.quit();
}
});
}
Full example included in the shared driver example: https://github.com/cucumber/cucumber-jvm/blob/master/examples/java-webbit-websockets-selenium/src/test/java/cucumber/examples/java/websockets/SharedDriver.java
I have a Feature file which is as below:
Scenario Outline: Create ABC
Given I open the application
When I enter username as <username>
And I enter password as <password>
Then I enter title as <title>
And press submit
Examples:
| username | password | title |
| Rob | xyz1 | title1 |
| Bob | xyz1 | title2 |
This mandates me to have step definitions for each of these values. Can i instead have a
generic step definition that can be mapped for every username or password or title values in
the examples section.
i.e instead of saying
#When("^I enter username as Rob$")
public void I_enter_username_as_Rob() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
can i enter
#When("^I enter username as <username>$")
public void I_enter_username_as_username(<something to use the value passed>) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
You should use this format
Scenario Outline: Create ABC
Given I open the application
When I enter username as "<username>"
And I enter password as "<password>"
Then I enter title as "<title>"
And press submit
Which would produce
#When("^I enter username as \"([^\"]*)\"$")
public void I_enter_username_as(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
arg1 will now have your username/value passed.
Cucumber would give the missing steps in console automatically. Just make a dry run and missing steps would be shown in console.
#RunWith(Cucumber.class)
#CucumberOptions(plugin = { "pretty" }, features = { "<path_to_feature>" },
glue = { "<optional_steps_location_java_file>" }, dryRun = true,
tags = { "<optional_NOT_req_for_now>" })
public class RunMyCucumberTest {
}
See for more Cucumber options
I have a C# unit test using Selenium WebDriver to test to see if a link exists. Here's the code:
[TestMethod()]
public void RegisterLinkExistTest()
{
IWebElement registerLink = genericBrowserDriver.FindElement(By.PartialLinkText ("Register1"));
Assert.AreEqual("Register here", registerLink.Text, "Failed");
}
I wanted to see what happens if I set the PartialLinkText as "Register1" instead of "Register". MSTest failed this test with a exception thrown from Selenium. I wanted the Assert.AreEqual to execute but MSTest throws a exception on the previous line. I know I can use ExpectedException attribute to specify "OpenQA.Selenium.NoSuchElementException" but I don't want to do that way because I'm not expecting that exception. How do I go about handling this?
As #AD.Net already said, your test is working as expected.
You could catch the exception in case the link was not found but I don't see the point to do that. If the link is not found then the registerLink will be null. What's the point of asserting on a null object's property?
Your test works fine, just delete the Assert line.
However, if you also want to test the link's text try the following code:
[TestMethod()]
public void RegisterLinkExistTest()
{
try
{
IWebElement registerLink = genericBrowserDriver.FindElement(By.PartialLinkText ("Register1"));
Assert.AreEqual("Register here", registerLink.Text, "Register's link text mismatch");
}
catch(NoSuchElementException)
{
Assert.Fail("The register link was not found");
}
}
EDIT
You can seperate your test, the first test will check if the link exists and the second will assert it's properties.
[TestMethod()]
public void RegisterLinkExistTest()
{
IWebElement registerLink = genericBrowserDriver.FindElement(By.PartialLinkText ("Register1"));
}
[TestMethod()]
public void RegisterLinkTextTest()
{
IWebElement registerLink = genericBrowserDriver.FindElement(By.PartialLinkText ("Register1"));
Assert.AreEqual("Register here", registerLink.Text, "Register's link text mismatch");
}
Then use an OrderedTest and add them in that order so the RegisterLinkExistTest will be executed first. If it fails then the second test will not run.