cancel
Showing results for 
Search instead for 
Did you mean: 

how to use a feature file within another

rezza
Occasional Contributor

how to use a feature file within another

Hi

I want to create a complete login feature file and write its unit tests.
And I could run that unit tests, whenever I want.
After, I want to create another feature file (let's call it filling a form) and write its unit test.

 

But in my case, only logged-in users can fill out that form.
So I want to use the login feature file inside the filling form feature file.
Of course, both feature files must be complete and separate from each other, and I could run them simultaneously.

 

4 REPLIES 4
rezza
Occasional Contributor

Re: how to use a feature file within another

please guide me.

what can I do?

Re: how to use a feature file within another

Hello,

 

You cannot "call" a feature file, or a scenario, from within another feature or scenario.

 

You can still arrange your code for doing that under the hood.

 

The code you have in your step definition which actually login the user should be extracted from your step definition into support code, or library. You will then be able to call those methods from anywhere in your tests, background or hooks.

 

 

rezza
Occasional Contributor

Re: how to use a feature file within another

@aurelien-reeves 
Hi again

I created this feature file for the login:

 

 

  Scenario Outline: Login into account with correct credentials
    And User clicks on the login button on homepage
    And User enters a valid username "<username>"
    And User enters a valid password "<password>"
    When User clicks on the login button
    Examples:
      | username | password |
      | user1    | 123456   |

 

 

And this is the step definition for the login:

 

 

 @Given("User clicks on the login button on homepage$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_login_button_on_homepage() {
        loginPage!!.clickOnSignInButton()
    }
    @Given("^User enters a valid username \"([^\"]*)\"$")
    @Throws(Throwable::class)
    fun user_enters_a_valid_username(username: String?) {
        loginPage!!.enterUserName(username)
    }
    @Given("^User enters a valid password \"([^\"]*)\"$")
    @Throws(Throwable::class)
    fun user_enters_a_valid_password(password: String?) {
        loginPage!!.enterPassword(password)
    }
    @When("User clicks on the login button$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_login_button() {
        loginPage!!.clickOnSubmitButton()
    }

 

 

 

I used the login functions inside the step definition of the form, in this way:

 

 

    @Given("^User logged in with valid username and password$")
    @Throws(Throwable::class)
    fun user_logged_in_with_valid_and() {
        LoginSteps().user_clicks_on_the_login_button_on_homepage()
        LoginSteps().user_enters_a_valid_username()
        LoginSteps().user_enters_a_valid_password()
        LoginSteps().user_clicks_on_the_login_button()
    }
    @Then("^User clicks on the processes page$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_processes_page() {
        fillingFormPage!!.clickOnProcessesPage()
    }

 

 

But I have a problem that says no value passed for parameter username and password, which is right.

So, I changed the step definition for the form like this:

 

 

    @Given("^User logged in with valid username and password$")
    @Throws(Throwable::class)
    fun user_logged_in_with_valid_and(username: String?, password: String?) {
        LoginSteps().user_clicks_on_the_login_button_on_homepage()
        LoginSteps().user_enters_a_valid_username(username)
        LoginSteps().user_enters_a_valid_password(password)
        LoginSteps().user_clicks_on_the_login_button()
    }
    @Then("^User clicks on the processes page$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_processes_page() {
        fillingFormPage!!.clickOnProcessesPage()
    }

 

 

But also when I run the test, I face this problem:

 

 

feature (Fill the form)
cucumber.runtime.CucumberException: cucumber.runtime.CucumberException: Arity mismatch: Step Definition 'void stepDefinitions.FillingFormSteps.user_logged_in(String,String) in file:/###/target/classes/' with pattern [^User logged in$] is declared with 2 parameters. However, the gherkin step has 0 arguments []. 
Step: Given User logged in with valid username and password
  at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:69)
  at cucumber.api.testng.AbstractTestNGCucumberTests.feature(AbstractTestNGCucumberTests.java:21)
Caused by: cucumber.runtime.CucumberException: Arity mismatch: Step Definition 'void stepDefinitions.FillingFormSteps.user_logged_in(String,String) in file:/###/target/classes/' with pattern [^User logged in$] is declared with 2 parameters. However, the gherkin step has 0 arguments []. 
Step: Given User logged in with valid username and password
  at cucumber.runtime.StepDefinitionMatch.arityMismatch(StepDefinitionMatch.java:102)
  at cucumber.runtime.StepDefinitionMatch.transformedArgs(StepDefinitionMatch.java:60)
  at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
  at cucumber.runtime.Runtime.runStep(Runtime.java:300)
  at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
  at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
  at cucumber.runtime.model.CucumberScenario.runBackground(CucumberScenario.java:59)
  at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:42)
  at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
  at cucumber.api.testng.TestNGCucumberRunner.runCucumber(TestNGCucumberRunner.java:63)
  ... 29 more

 

 


So, I had to change the feature file of the form from this:

 

 

Feature: Fill the form
  Existing user should be able to log in using correct credentials and fill the form

  Background: : logged in user
    Given User logged in with valid username and password

  Scenario: Login into account with correct credentials and fill the form
    And User clicks on the processes page

 

 

 

to this:

 

 

Feature: Fill the form
  Existing user should be able to log in using correct credentials and fill the form

  Background: : logged in user
    Given User logged in with valid "<username>" and "<password>"

  Scenario: Login into account with correct credentials and fill the form
    And User clicks on the processes page

 


also, I had to change the step definition of the form from this:

 

 

    @Given("^User logged in with valid username and password$")
    @Throws(Throwable::class)
    fun user_logged_in_with_valid_and(username: String?, password: String?) {
        LoginSteps().user_clicks_on_the_login_button_on_homepage()
        LoginSteps().user_enters_a_valid_username(username)
        LoginSteps().user_enters_a_valid_password(password)
        LoginSteps().user_clicks_on_the_login_button()
    }
    @Then("^User clicks on the processes page$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_processes_page() {
        fillingFormPage!!.clickOnProcessesPage()
    }

 

 

to this:

 

 

    @Given("^User logged in with valid \"([^\"]*)\" and \"([^\"]*)\"$")
    @Throws(Throwable::class)
    fun user_logged_in_with_valid_and(username: String?, password: String?) {
        LoginSteps().user_clicks_on_the_login_button_on_homepage()
        LoginSteps().user_enters_a_valid_username(username)
        LoginSteps().user_enters_a_valid_password(password)
        LoginSteps().user_clicks_on_the_login_button()
    }
    @Then("^User clicks on the processes page$")
    @Throws(Throwable::class)
    fun user_clicks_on_the_processes_page() {
        fillingFormPage!!.clickOnProcessesPage()
    }

 

 

But, when I run the test, the username and password fields, filled with these values:
username: <username>
password: <password>


But I want them to be filled with these values:

username: user1
password: 123456

Which I defined in the feature file of the login.


What can I do to pass the correct values???

Re: how to use a feature file within another

If you need a dedicated test for your login form, your first example was fine.

 

For your other scenario, you could have a before hook which do all the login at once using support code, no steps.

Your login/password may be part of that support code, it is not relevant to appear in your features.

 

That may look like the following pseudo-code:

 

// A before hook:
Before {
LoginUserAs('user-1', '123456')
}

// In some support code
function LoginUserAs(username, password) {
// Do all the steps to login a user:
// - Open the login page
// - Fill the form
// - Submit the form
// - ...
}

 

New Here?
Join us and watch the welcome video: