Cucumber DataTable Error - io.cucumber.datatable.U

2019-07-27 06:02发布

Trying to run a scenario with cucumber/selenium/java/intelliJ, but getting an error regarding the DataTable in one of the steps. The dataTable was working fine and converting the arguments for the step correctly before I started using a test runner and changed some things around, but I just can't get this to work.

This is the error:

cucumber.runtime.CucumberException: Could not convert arguments for step [^I enter the following login details:$] defined at 'Steps.MaStepdefs.iEnterTheFollowingLoginDetails(DataTable) in file:/C:/Users/Kristian.Senior/Desktop/CukesReporting/target/test-classes/'.
It appears you did not register a data table type. The details are in the stacktrace below.
    at cucumber.runner.PickleStepDefinitionMatch.registerTypeInConfiguration(PickleStepDefinitionMatch.java:59)
    at cucumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:44)
    at cucumber.runner.TestStep.executeStep(TestStep.java:63)
    at cucumber.runner.TestStep.run(TestStep.java:49)
    at cucumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:43)
    at cucumber.runner.TestCase.run(TestCase.java:45)
    at cucumber.runner.Runner.runPickle(Runner.java:40)
    at cucumber.runtime.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:146)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:68)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:23)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:73)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:122)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:64)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at cucumber.api.junit.Cucumber$1.evaluate(Cucumber.java:131)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: io.cucumber.datatable.UndefinedDataTableTypeException: Can't convert DataTable to cucumber.api.DataTable.
Please register a DataTableType with a TableTransformer, TableEntryTransformer or TableRowTransformer for cucumber.api.DataTable.
    at io.cucumber.datatable.UndefinedDataTableTypeException.singletonNoConverterDefined(UndefinedDataTableTypeException.java:15)
    at io.cucumber.datatable.DataTableTypeRegistryTableConverter.toSingleton(DataTableTypeRegistryTableConverter.java:106)
    at io.cucumber.datatable.DataTableTypeRegistryTableConverter.convert(DataTableTypeRegistryTableConverter.java:75)
    at io.cucumber.datatable.DataTable.convert(DataTable.java:362)
    at io.cucumber.stepexpression.StepExpressionFactory$3.transform(StepExpressionFactory.java:73)
    at io.cucumber.stepexpression.DataTableArgument.getValue(DataTableArgument.java:19)
    at cucumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:41)
    ... 29 more

Here is my scenario:

Feature: LoginFeature
  This deals with logging in

  Scenario: Log in with correct username

    Given I navigate to the login page
    And I enter the following login details:
      | username | password |
      | cukey    | passwoid |
    And I click the login button
    Then I should land on the newest page

Here's my step definitions:

package Steps;

import Base.BaseUtil;
import Pages.LoginPageObjeks;
import cucumber.api.DataTable;
import cucumber.api.PendingException;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.ArrayList;
import java.util.List;


public class MaStepdefs extends BaseUtil {
    private BaseUtil base;

    public MaStepdefs(BaseUtil base) {
        this.base = base;
    }

    @And("^I click the login button$")
    public void iClickTheLoginButton() throws Throwable {
        LoginPageObjeks page = new LoginPageObjeks(base.Driver);
        page.ClickLogin();

    }

    @Given("^I navigate to the login page$")
    public void iNavigateToTheLoginPage() throws Throwable {

        base.Driver.navigate().to("http://www.executeautomation.com/demosite/Login.html");

    }

    @And("^I enter the following login details:$")
    public void iEnterTheFollowingLoginDetails(DataTable table) throws Throwable {

        List<User> users = new ArrayList<User>();

        users = table.asList(User.class);

        LoginPageObjeks page = new LoginPageObjeks(base.Driver);

        for (User user : users) {
            page.Login(user.username, user.password);

            //base.Driver.findElement(By.name("UserName")).sendKeys(user.username);
            //base.Driver.findElement(By.name("Password")).sendKeys(user.password);

            Thread.sleep(2000);


        }
    }
        @Then("^I should land on the newest page$")
        public void iShouldLandOnTheNewestPage () throws Throwable {
            Assert.assertEquals("It's not displayed", base.Driver.findElement(By.id("Initial")).isDisplayed(), true);
        }



    }

    class User {
        public String username;
        public String password;

        public User(String userName, String passWord) {
            username = userName;
            password = passWord;
        }
    }

Here is my pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>ownCukes</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>4.2.6</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>3.2.0</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>4.2.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>4.2.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>4.2.6</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-core -->

        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>


    </dependencies>


</project>

And here's my TestRunner:

package Runner;


import cucumber.api.CucumberOptions;
import org.junit.runner.RunWith;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features = {"src/test/java/features"}, glue = "Steps")

public class TestRunner {
}

I'm not sure what a data table type is or how to register one? I've tried messing around with DataTableType and TypeRegistry but I'm not an expert. Any help would be appreciated, thanks

1条回答
虎瘦雄心在
2楼-- · 2019-07-27 06:05

You are using outdated version, it is now:

import io.cucumber.datatable.DataTable;

See CHANGELOG for cucumber jvm, quote:

[Core] Replace DataTable with io.cucumber.datatable.DataTable (#1248 M.P. Korstanje, Björn Rasmusson, Marit van Dijk) Custom data table types can be defined by implementing the TypeRegistryConfigurer.

There is slightly different way of using it now, example:

Sample gherkin step:

And I update ADDRESS tab data in building form
  | Input         | Value        |
  | Building name | New name     |
  | Ref           | Some ref     |

Step implementation:

@And("^some test step$")
public void someTestStep(DataTable table)
{
    List<List<String>> data = table.asLists(String.class);
    String buildingName = data.get(1).get(1);
    String reference = data.get(2).get(1);
}
查看更多
登录 后发表回答