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
相关产品推荐
相关产品推荐

