You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cucumber报错:无法继承定义Step Definitions或hooks的类的解决方法

问题描述

遇到报错:

You're not allowed to extend classes that define Step Definitions or hooks.

需求:创建多个包含Cucumber步骤的类,以及一个带有@Before和@After的Hook类,解决上述报错。

现有代码

Hook类

public class Hook {
    public WebDriver driver;

    protected Properties properties;
    protected final String propertyFilePath = "src/main/java/Config/config.properties";

    /**
     * read data from config file
     **/
    public Hook() {
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(propertyFilePath));
            properties = new Properties();
            try {
                properties.load(reader);
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("config.properties not found at " + propertyFilePath);
        }
    }

    @Before
    /**pattern singleton*/
    public String getDriverPath() {
        String browser = properties.getProperty("browser");
        if (browser.equals("chrome")) {
            WebDriverManager.chromedriver().setup();
            driver = new ChromeDriver();
        } else if (browser.equals("firefox")) {
            WebDriverManager.firefoxdriver().setup();
            driver = new FirefoxDriver();
        } else {
            System.out.println("browser not existed");
        }
        driver.manage().window().fullscreen();
        String url = properties.getProperty("url");
        driver.get(url);
        return browser;
    }

    @After
    public void close() {
        driver.quit();
    }
}

BaseSteps类

public class BaseSteps extends Hook {

    @When("fill in Name with {string}")
    public void fillInWith(String value) {
        LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
        loginPage.typeInUserNameField(value);
    }
}
解决方案

报错原因是Cucumber禁止继承包含Hook(@Before/@After)或步骤定义的类,当前BaseSteps继承带Hook的Hook类,触发了该限制。以下两种方案可解决问题:

方式一:依赖注入(推荐)

利用Cucumber自带的PicoContainer或第三方依赖注入框架(如Spring),让步骤类和Hook类共享WebDriver实例,无需继承。

1. 修改Hook类

调整逻辑,提供WebDriver实例的获取方法:

public class Hook {
    private WebDriver driver;
    protected Properties properties;
    protected final String propertyFilePath = "src/main/java/Config/config.properties";

    public Hook() {
        // 保留原配置读取逻辑不变
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(propertyFilePath));
            properties = new Properties();
            try {
                properties.load(reader);
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("config.properties not found at " + propertyFilePath);
        }
    }

    @Before
    public void setupDriver() {
        String browser = properties.getProperty("browser");
        if (browser.equals("chrome")) {
            WebDriverManager.chromedriver().setup();
            driver = new ChromeDriver();
        } else if (browser.equals("firefox")) {
            WebDriverManager.firefoxdriver().setup();
            driver = new FirefoxDriver();
        } else {
            System.out.println("browser not existed");
        }
        driver.manage().window().fullscreen();
        String url = properties.getProperty("url");
        driver.get(url);
    }

    @After
    public void teardownDriver() {
        if (driver != null) {
            driver.quit();
        }
    }

    // 供步骤类获取driver的方法
    public WebDriver getDriver() {
        return driver;
    }
}

2. 修改BaseSteps类

通过构造方法注入Hook实例,获取WebDriver,取消继承:

public class BaseSteps {
    private WebDriver driver;

    // Cucumber会自动注入Hook实例
    public BaseSteps(Hook hook) {
        this.driver = hook.getDriver();
    }

    @When("fill in Name with {string}")
    public void fillInWith(String value) {
        LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
        loginPage.typeInUserNameField(value);
    }
}

注:确保Hook类和步骤类在Cucumber扫描路径内,默认会扫描运行类所在包及子包。

方式二:提取共享逻辑到工具类

把WebDriver初始化、配置读取等逻辑放到独立工具类,Hook类和步骤类直接调用工具类,避免继承。

1. 创建DriverUtils工具类

public class DriverUtils {
    private static WebDriver driver;
    private static Properties properties;
    private static final String propertyFilePath = "src/main/java/Config/config.properties";

    static {
        // 静态代码块加载配置
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(propertyFilePath));
            properties = new Properties();
            properties.load(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("config.properties not found at " + propertyFilePath);
        }
    }

    public static void initDriver() {
        String browser = properties.getProperty("browser");
        if (browser.equals("chrome")) {
            WebDriverManager.chromedriver().setup();
            driver = new ChromeDriver();
        } else if (browser.equals("firefox")) {
            WebDriverManager.firefoxdriver().setup();
            driver = new FirefoxDriver();
        } else {
            System.out.println("browser not existed");
        }
        driver.manage().window().fullscreen();
        String url = properties.getProperty("url");
        driver.get(url);
    }

    public static void quitDriver() {
        if (driver != null) {
            driver.quit();
        }
    }

    public static WebDriver getDriver() {
        return driver;
    }
}

2. 修改Hook类

调用工具类完成驱动初始化和销毁:

public class Hook {
    @Before
    public void setup() {
        DriverUtils.initDriver();
    }

    @After
    public void teardown() {
        DriverUtils.quitDriver();
    }
}

3. 修改BaseSteps类

直接从工具类获取WebDriver:

public class BaseSteps {
    @When("fill in Name with {string}")
    public void fillInWith(String value) {
        WebDriver driver = DriverUtils.getDriver();
        LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
        loginPage.typeInUserNameField(value);
    }
}

内容的提问来源于stack exchange,提问作者Catea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:47:01