如何从命令行动态传递Feature文件路径?含Cucumber+TestNG场景
Hey there! Let's tackle your two questions about dynamically passing Cucumber Feature file paths from the command line—first for plain Cucumber execution, then specifically within the TestNG framework.
When running Cucumber directly via its command-line runner, you can use the --features parameter to dynamically specify your Feature file path(s). Here's how to do it smoothly:
Basic Command Structure
For Java projects, the core command looks like this (replace placeholders with your project's paths):java -cp "path/to/classes:path/to/dependencies/*" cucumber.api.cli.Main --features <FEATURE_FILE_PATH> --glue <STEP_DEFINITIONS_PACKAGE>Dynamic Path via Environment Variable
If you want to reuse the path across commands, store it in an environment variable:
On Linux/macOS:export FEATURE_PATH="src/test/resources/features/login.feature" java -cp "target/test-classes:target/dependency/*" cucumber.api.cli.Main --features $FEATURE_PATH --glue com.example.stepdefsOn Windows (Command Prompt):
set FEATURE_PATH=src\test\resources\features\login.feature java -cp "target\test-classes;target\dependency\*" cucumber.api.cli.Main --features %FEATURE_PATH% --glue com.example.stepdefsMultiple Paths or Wildcards
You can pass multiple Feature paths separated by commas, or use wildcards to select all features in a directory:# Multiple specific files java -cp ... cucumber.api.cli.Main --features src/test/resources/features/login.feature,src/test/resources/features/payment.feature --glue com.example.stepdefs # All features in a directory java -cp ... cucumber.api.cli.Main --features src/test/resources/features/ --glue com.example.stepdefs
When using TestNG, we need to bridge command-line arguments to Cucumber's configuration. Here are two reliable approaches:
Approach 1: System Properties (-D) + Cucumber System Property
TestNG lets you pass system properties via the command line, which we can forward to Cucumber's cucumber.features property.
Step 1: Configure Your TestNG Runner Class
import io.cucumber.testng.CucumberOptions; import io.cucumber.testng.CucumberTestNG; import org.testng.annotations.BeforeSuite; @CucumberOptions( glue = "com.example.stepdefs", features = "" // Leave empty; we'll set this dynamically ) public class CucumberTestNgRunner extends CucumberTestNG { @BeforeSuite public void setupFeaturePath() { // Fetch path from command-line system property String featurePath = System.getProperty("feature.path"); if (featurePath != null && !featurePath.isEmpty()) { // Override Cucumber's feature path System.setProperty("cucumber.features", featurePath); } } }
Step 2: Run via Command Line
Using Maven:
mvn test -Dfeature.path="src/test/resources/features/checkout.feature"
Or directly with TestNG:
java -cp "target/test-classes:target/classes:lib/*" org.testng.TestNG testng.xml -Dfeature.path="src/test/resources/features/checkout.feature"
Approach 2: TestNG Parameters + RuntimeOptionsBuilder
If you prefer using TestNG's built-in parameter system (e.g., with a default path in testng.xml), inject the path and build Cucumber's runtime options dynamically.
Step 1: Update TestNG Runner with @Parameters
import io.cucumber.testng.CucumberOptions; import io.cucumber.testng.CucumberTestNG; import io.cucumber.testng.RuntimeOptionsBuilder; import org.testng.annotations.Parameters; import org.testng.annotations.BeforeSuite; @CucumberOptions(glue = "com.example.stepdefs") public class CucumberTestNgRunner extends CucumberTestNG { @Parameters("featurePath") @BeforeSuite public void setupFeaturePath(String featurePath) { RuntimeOptionsBuilder builder = new RuntimeOptionsBuilder(); // Add the dynamic feature path builder.addFeatures(java.nio.file.Paths.get(featurePath)); // Set the configured options for Cucumber setRuntimeOptions(builder.build()); } }
Step 2: Optional: Define Default Path in testng.xml
Set a fallback path in your TestNG config:
<suite name="Cucumber Suite"> <parameter name="featurePath" value="src/test/resources/features/default.feature"/> <test name="Cucumber Tests"> <classes> <class name="com.example.CucumberTestNgRunner"/> </classes> </test> </suite>
Step 3: Override via Command Line
To replace the default path:
mvn test -DfeaturePath="src/test/resources/features/custom.feature"
Or with TestNG directly:
java -cp ... org.testng.TestNG testng.xml -DfeaturePath="src/test/resources/features/custom.feature"
Note for Cucumber v7+
If you're using Cucumber 7.x or later, the API has minor changes, but the system property approach still works seamlessly. You can also use the constant FEATURES_PROPERTY_NAME for clarity:
import io.cucumber.testng.CucumberOptions; import io.cucumber.testng.CucumberTestNG; import static io.cucumber.junit.platform.engine.Constants.FEATURES_PROPERTY_NAME; @CucumberOptions(glue = "com.example.stepdefs") public class CucumberTestNgRunner extends CucumberTestNG { @BeforeSuite public void setup() { String featurePath = System.getProperty("feature.path"); if (featurePath != null) { System.setProperty(FEATURES_PROPERTY_NAME, featurePath); } } }
内容的提问来源于stack exchange,提问作者satya prakash mukhi

