diff --git a/karate-core/src/main/java/com/intuit/karate/Runner.java b/karate-core/src/main/java/com/intuit/karate/Runner.java index a8b4fc72d..0dd4418d9 100644 --- a/karate-core/src/main/java/com/intuit/karate/Runner.java +++ b/karate-core/src/main/java/com/intuit/karate/Runner.java @@ -34,10 +34,11 @@ import com.intuit.karate.http.HttpClientFactory; import com.intuit.karate.report.SuiteReports; import com.intuit.karate.resource.ResourceUtils; +import org.slf4j.LoggerFactory; + import java.io.File; import java.util.*; import java.util.stream.Collectors; -import org.slf4j.LoggerFactory; /** * @@ -112,6 +113,7 @@ public static class Builder { boolean outputCucumberJson; boolean dryRun; boolean debugMode; + boolean failWhenNoScenariosFound; Map systemProperties; Map callSingleCache; Map callOnceCache; @@ -145,6 +147,7 @@ public synchronized Builder copy() { b.outputCucumberJson = outputCucumberJson; b.dryRun = dryRun; b.debugMode = debugMode; + b.failWhenNoScenariosFound = failWhenNoScenariosFound; b.systemProperties = systemProperties; b.callSingleCache = callSingleCache; b.callOnceCache = callOnceCache; @@ -436,6 +439,11 @@ public T debugMode(boolean value) { debugMode = value; return (T) this; } + + public T failWhenNoScenariosFound(boolean value) { + failWhenNoScenariosFound = value; + return (T) this; + } public T callSingleCache(Map value) { callSingleCache = value; diff --git a/karate-core/src/main/java/com/intuit/karate/Suite.java b/karate-core/src/main/java/com/intuit/karate/Suite.java index eb1aa5b4b..265112d77 100644 --- a/karate-core/src/main/java/com/intuit/karate/Suite.java +++ b/karate-core/src/main/java/com/intuit/karate/Suite.java @@ -28,8 +28,6 @@ import com.intuit.karate.core.FeatureCall; import com.intuit.karate.core.FeatureResult; import com.intuit.karate.core.FeatureRuntime; -import com.intuit.karate.driver.DriverRunner; -import com.intuit.karate.report.ReportUtils; import com.intuit.karate.core.Scenario; import com.intuit.karate.core.ScenarioCall; import com.intuit.karate.core.ScenarioResult; @@ -37,27 +35,23 @@ import com.intuit.karate.core.Step; import com.intuit.karate.core.SyncExecutorService; import com.intuit.karate.core.Tags; +import com.intuit.karate.driver.DriverRunner; import com.intuit.karate.http.HttpClientFactory; +import com.intuit.karate.report.ReportUtils; import com.intuit.karate.report.SuiteReports; import com.intuit.karate.resource.Resource; import com.intuit.karate.resource.ResourceUtils; +import org.slf4j.LoggerFactory; + import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.slf4j.LoggerFactory; import static java.util.function.Predicate.not; @@ -78,6 +72,7 @@ public class Suite implements Runnable { public final String tagSelector; public final boolean dryRun; public final boolean debugMode; + public final boolean failWhenNoScenariosFound; public final File workingDir; public final String buildDir; public final String reportDir; @@ -135,6 +130,7 @@ public Suite(Runner.Builder rb) { if (rb.forTempUse) { dryRun = false; debugMode = false; + failWhenNoScenariosFound = false; backupReportDir = false; outputHtmlReport = false; outputCucumberJson = false; @@ -179,6 +175,7 @@ public Suite(Runner.Builder rb) { outputJunitXml = rb.outputJunitXml; dryRun = rb.dryRun; debugMode = rb.debugMode; + failWhenNoScenariosFound = rb.failWhenNoScenariosFound; classLoader = rb.classLoader; clientFactory = rb.clientFactory; env = rb.env; diff --git a/karate-junit5/src/main/java/com/intuit/karate/junit5/Karate.java b/karate-junit5/src/main/java/com/intuit/karate/junit5/Karate.java index 85475215a..0d5ad194b 100644 --- a/karate-junit5/src/main/java/com/intuit/karate/junit5/Karate.java +++ b/karate-junit5/src/main/java/com/intuit/karate/junit5/Karate.java @@ -25,7 +25,6 @@ import com.intuit.karate.Runner; import com.intuit.karate.Suite; -import com.intuit.karate.core.Feature; import com.intuit.karate.core.FeatureCall; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DynamicContainer; @@ -68,7 +67,7 @@ public Iterator iterator() { DynamicNode node = DynamicContainer.dynamicContainer(testName, featureNode); list.add(node); } - if (list.isEmpty()) { + if (suite.failWhenNoScenariosFound && list.isEmpty()) { Assertions.fail("no features or scenarios found: " + this); } return list.iterator(); diff --git a/karate-junit5/src/test/java/karate/NoFeatureNoScenarioTest.java b/karate-junit5/src/test/java/karate/NoFeatureNoScenarioTest.java new file mode 100644 index 000000000..78bf7a015 --- /dev/null +++ b/karate-junit5/src/test/java/karate/NoFeatureNoScenarioTest.java @@ -0,0 +1,22 @@ +package karate; + +import com.intuit.karate.junit5.Karate; + +class NoFeatureNoScenarioTest { + + @Karate.Test + Karate testHasScenariosWithFailWhenNoScenariosFound() { + return Karate.run("noFeatureNoScenario") + .tags("@smoke") + .failWhenNoScenariosFound(true) + .relativeTo(getClass()); + } + + @Karate.Test + Karate testNoScenarios() { + return Karate.run("noFeatureNoScenario") + .tags("@tagnotexist") + .failWhenNoScenariosFound(false) + .relativeTo(getClass()); + } +} diff --git a/karate-junit5/src/test/java/karate/noFeatureNoScenario.feature b/karate-junit5/src/test/java/karate/noFeatureNoScenario.feature new file mode 100644 index 000000000..b94c0acfa --- /dev/null +++ b/karate-junit5/src/test/java/karate/noFeatureNoScenario.feature @@ -0,0 +1,5 @@ +Feature: ignoreJunitNoScenariosAssertion argument for Karate runner + + @smoke + Scenario: smoke + * print 'smoke'