From 8c1516cc41778b2ddf50647c5ded5eb1f01b9b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacek=20G=C4=99bal?= Date: Sat, 17 Oct 2026 23:25:18 +0300 Subject: [PATCH] Add coverage filter options by regular expression Expose the utPLSQL coverage filters as `run` command options: -include-schema-expr, -exclude-schema-expr, -include-object-expr and -exclude-object-expr. Documented the options and their semantics in the README. --- README.md | 17 +++++++ src/main/java/org/utplsql/cli/RunAction.java | 4 ++ .../org/utplsql/cli/RunPicocliCommand.java | 32 +++++++++++++ .../utplsql/cli/config/RunCommandConfig.java | 46 +++++++++++++++++-- .../utplsql/cli/PicocliRunCommandTest.java | 10 +++- .../utplsql/cli/RunCommandArgumentsTest.java | 17 +++++++ ...ConfigParamsArePassedToTestRunnerTest.java | 15 ++++++ 7 files changed, 137 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f536690..48d3d79 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,17 @@ The TNS alias used in the connect string must match the alias of the credential -exclude=pckg_list - Comma-separated object list to exclude from the coverage report. Format: [schema.]package[,[schema.]package ...]. See coverage reporting options in framework documentation. + +-include-schema-expr=regex - Regular expression matching the names of schemas to include in the coverage report. +-exclude-schema-expr=regex - Regular expression matching the names of schemas to exclude from the coverage report. +-include-object-expr=regex - Regular expression matching the names of objects to include in the coverage report. +-exclude-object-expr=regex - Regular expression matching the names of objects to exclude from the coverage report. + Case-insensitive. Object expressions are matched against the object name without the schema. + Anchor them with `^` and `$`, otherwise any partial match counts. + If an include expression is given, `-include` and `--coverage-schemes` are ignored. + All exclude options are always applied and can be combined. + Ignored when `-source_path` is used (file mapping defines the coverage scope). + See https://www.utplsql.org/utPLSQL/latest/userguide/coverage.html#filtering-objects-in-coverage-reports -q - Does not output the informational messages normally printed to console. (--quiet) Default: false @@ -247,6 +258,12 @@ Invokes all Unit tests from schema/package "hr_test" with two reporters: Invokes all unit test suites from schema "hr". Results are displayed to screen using default ut_documentation_reporter. +``` +> utplsql run hr/hr@xe -p=hr_test -f=ut_coverage_html_reporter -o=coverage.html -include-schema-expr=^HR$ -exclude-object-expr=_TMP$ +``` + +Runs the tests from "hr_test" and writes an HTML coverage report that covers all objects in schema "HR" except those whose name ends with "_TMP". + ### info `utplsql info []` diff --git a/src/main/java/org/utplsql/cli/RunAction.java b/src/main/java/org/utplsql/cli/RunAction.java index f79e63d..7433d9e 100644 --- a/src/main/java/org/utplsql/cli/RunAction.java +++ b/src/main/java/org/utplsql/cli/RunAction.java @@ -167,6 +167,10 @@ TestRunner newTestRunner(List reporterList) { .randomTestOrderSeed(config.getRandomTestOrderSeed()) .addTags(Arrays.asList(config.getTags())) .addCoverageSchemes(Arrays.asList(config.getCoverageSchemes())) + .includeSchemaExpr(config.getIncludeSchemaExpr()) + .excludeSchemaExpr(config.getExcludeSchemaExpr()) + .includeObjectExpr(config.getIncludeObjectExpr()) + .excludeObjectExpr(config.getExcludeObjectExpr()) .oraStuckTimeout(config.getOraStuckTimeout()); } diff --git a/src/main/java/org/utplsql/cli/RunPicocliCommand.java b/src/main/java/org/utplsql/cli/RunPicocliCommand.java index 2908cf2..4285549 100644 --- a/src/main/java/org/utplsql/cli/RunPicocliCommand.java +++ b/src/main/java/org/utplsql/cli/RunPicocliCommand.java @@ -81,6 +81,34 @@ public class RunPicocliCommand implements IRunCommand { private String excludeObjects = null; + @Option( + names = {"-include-schema-expr"}, + description = "Regular expression to include in the coverage report schemas whose name matches the expression. " + + "See coverage reporting options in framework documentation" + ) + private String includeSchemaExpr; + + @Option( + names = {"-exclude-schema-expr"}, + description = "Regular expression to exclude from the coverage report schemas whose name matches the expression. " + + "See coverage reporting options in framework documentation" + ) + private String excludeSchemaExpr; + + @Option( + names = {"-include-object-expr"}, + description = "Regular expression to include in the coverage report objects whose name matches the expression. " + + "See coverage reporting options in framework documentation" + ) + private String includeObjectExpr; + + @Option( + names = {"-exclude-object-expr"}, + description = "Regular expression to exclude from the coverage report objects whose name matches the expression. " + + "See coverage reporting options in framework documentation" + ) + private String excludeObjectExpr; + @Option( names = {"-D", "--dbms_output"}, description = "Enables DBMS_OUTPUT for the TestRunner (default: DISABLED)" @@ -249,6 +277,10 @@ public RunCommandConfig getRunCommandConfig() { .tags(tags.toArray(new String[0])) .coverageSchemes(coverageSchemes.toArray(new String[0])) .oraStuckTimeout(oraStuckTimeout) + .includeSchemaExpr(includeSchemaExpr) + .excludeSchemaExpr(excludeSchemaExpr) + .includeObjectExpr(includeObjectExpr) + .excludeObjectExpr(excludeObjectExpr) .create(); } diff --git a/src/main/java/org/utplsql/cli/config/RunCommandConfig.java b/src/main/java/org/utplsql/cli/config/RunCommandConfig.java index 218466b..1bc1632 100644 --- a/src/main/java/org/utplsql/cli/config/RunCommandConfig.java +++ b/src/main/java/org/utplsql/cli/config/RunCommandConfig.java @@ -24,9 +24,13 @@ public class RunCommandConfig extends ConnectionConfig { private final String[] tags; private final String[] coverageSchemes; private final Integer oraStuckTimeout; + private final String includeSchemaExpr; + private final String excludeSchemaExpr; + private final String includeObjectExpr; + private final String excludeObjectExpr; - @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourceMapping", "testMapping", "logConfigLevel", "timeoutInMinutes", "dbmsOutput", "randomTestOrder", "randomTestOrderSeed", "tags", "coverageSchemes", "oraStuckTimeout"}) - public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, FileMapperConfig sourceMapping, FileMapperConfig testMapping, ConfigLevel logConfigLevel, Integer timeoutInMinutes, boolean dbmsOutput, boolean randomTestOrder, Integer randomTestOrderSeed, String[] tags, String[] coverageSchemes, Integer oraStuckTimeout) { + @ConstructorProperties({"connectString", "suitePaths", "reporters", "outputAnsiColor", "failureExitCode", "skipCompatibilityCheck", "includePackages", "excludePackages", "sourceMapping", "testMapping", "logConfigLevel", "timeoutInMinutes", "dbmsOutput", "randomTestOrder", "randomTestOrderSeed", "tags", "coverageSchemes", "oraStuckTimeout", "includeSchemaExpr", "excludeSchemaExpr", "includeObjectExpr", "excludeObjectExpr"}) + public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfig[] reporters, boolean outputAnsiColor, Integer failureExitCode, boolean skipCompatibilityCheck, String[] includePackages, String[] excludePackages, FileMapperConfig sourceMapping, FileMapperConfig testMapping, ConfigLevel logConfigLevel, Integer timeoutInMinutes, boolean dbmsOutput, boolean randomTestOrder, Integer randomTestOrderSeed, String[] tags, String[] coverageSchemes, Integer oraStuckTimeout, String includeSchemaExpr, String excludeSchemaExpr, String includeObjectExpr, String excludeObjectExpr) { super(connectString); this.suitePaths = suitePaths; this.reporters = reporters; @@ -45,6 +49,10 @@ public RunCommandConfig(String connectString, String[] suitePaths, ReporterConfi this.tags = tags; this.coverageSchemes = coverageSchemes; this.oraStuckTimeout = oraStuckTimeout; + this.includeSchemaExpr = includeSchemaExpr; + this.excludeSchemaExpr = excludeSchemaExpr; + this.includeObjectExpr = includeObjectExpr; + this.excludeObjectExpr = excludeObjectExpr; } public String[] getSuitePaths() { @@ -113,6 +121,14 @@ public String[] getCoverageSchemes() { public Integer getOraStuckTimeout() { return oraStuckTimeout; } + public String getIncludeSchemaExpr() { return includeSchemaExpr; } + + public String getExcludeSchemaExpr() { return excludeSchemaExpr; } + + public String getIncludeObjectExpr() { return includeObjectExpr; } + + public String getExcludeObjectExpr() { return excludeObjectExpr; } + public static class Builder { private String connectString; @@ -133,6 +149,10 @@ public static class Builder { private String[] tags = new String[0]; private String[] coverageSchemes = new String[0]; private Integer oraStuckTimeout; + private String includeSchemaExpr; + private String excludeSchemaExpr; + private String includeObjectExpr; + private String excludeObjectExpr; public Builder connectString(String connectString) { this.connectString = connectString; @@ -224,8 +244,28 @@ public Builder oraStuckTimeout(Integer oraStuckTimeout) { return this; } + public Builder includeSchemaExpr(String includeSchemaExpr) { + this.includeSchemaExpr = includeSchemaExpr; + return this; + } + + public Builder excludeSchemaExpr(String excludeSchemaExpr) { + this.excludeSchemaExpr = excludeSchemaExpr; + return this; + } + + public Builder includeObjectExpr(String includeObjectExpr) { + this.includeObjectExpr = includeObjectExpr; + return this; + } + + public Builder excludeObjectExpr(String excludeObjectExpr) { + this.excludeObjectExpr = excludeObjectExpr; + return this; + } + public RunCommandConfig create() { - return new RunCommandConfig(connectString, suitePaths, reporters, outputAnsiColor, failureExitCode, skipCompatibilityCheck, includePackages, excludePackages, sourceMapping, testMapping, logConfigLevel, timeoutInMinutes, dbmsOutput, randomTestOrder, randomTestOrderSeed, tags, coverageSchemes, oraStuckTimeout); + return new RunCommandConfig(connectString, suitePaths, reporters, outputAnsiColor, failureExitCode, skipCompatibilityCheck, includePackages, excludePackages, sourceMapping, testMapping, logConfigLevel, timeoutInMinutes, dbmsOutput, randomTestOrder, randomTestOrderSeed, tags, coverageSchemes, oraStuckTimeout, includeSchemaExpr, excludeSchemaExpr, includeObjectExpr, excludeObjectExpr); } } } diff --git a/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java b/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java index 475ca82..b81e46e 100644 --- a/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java +++ b/src/test/java/org/utplsql/cli/PicocliRunCommandTest.java @@ -49,11 +49,19 @@ void runCommandAllArguments() throws Exception { "-owner_subexpression=1", "-type_subexpression=2", "-name_subexpression=3", - "--coverage-schemes=schema1,other_schema"); + "--coverage-schemes=schema1,other_schema", + "-include-schema-expr=^APP$", + "-exclude-schema-expr=^APP_TEST$", + "-include-object-expr=^PKG_", + "-exclude-object-expr=_TMP$"); assertNotNull(config.getConnectString()); assertThat( config.getSuitePaths(), is(new String[]{"app.betwnstr", "app.basic"})); assertThat( config.getTags(), is(new String[]{"tag1", "tag.2"})); + assertEquals( "^APP$", config.getIncludeSchemaExpr() ); + assertEquals( "^APP_TEST$", config.getExcludeSchemaExpr() ); + assertEquals( "^PKG_", config.getIncludeObjectExpr() ); + assertEquals( "_TMP$", config.getExcludeObjectExpr() ); assertTrue( config.isOutputAnsiColor() ); assertEquals( LoggerConfiguration.ConfigLevel.NONE, config.getLogConfigLevel()); assertEquals( 10, config.getFailureExitCode()); diff --git a/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java b/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java index 63be6e2..77c455c 100644 --- a/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java +++ b/src/test/java/org/utplsql/cli/RunCommandArgumentsTest.java @@ -8,6 +8,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; public class RunCommandArgumentsTest { @@ -69,6 +70,22 @@ void provideTags() { assertThat( testRunner.getOptions().tags, contains("tag1", "tag.2") ); } + @Test + void provideExpressionFilters() { + IRunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), + "-include-schema-expr=^APP$", + "-exclude-schema-expr=^APP_TEST$", + "-include-object-expr=^PKG_", + "-exclude-object-expr=_TMP$" + ); + + TestRunner testRunner = runCmd.newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().includeSchemaExpr, equalTo("^APP$") ); + assertThat( testRunner.getOptions().excludeSchemaExpr, equalTo("^APP_TEST$") ); + assertThat( testRunner.getOptions().includeObjectExpr, equalTo("^PKG_") ); + assertThat( testRunner.getOptions().excludeObjectExpr, equalTo("_TMP$") ); + } + @Test void provideCoverageSchemes() { IRunCommand runCmd = TestHelper.createRunCommand(TestHelper.getConnectionString(), diff --git a/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java b/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java index 95d146a..d3b5194 100644 --- a/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java +++ b/src/test/java/org/utplsql/cli/RunCommandConfigParamsArePassedToTestRunnerTest.java @@ -39,4 +39,19 @@ void oraStuckTimeout() { TestRunner testRunner = new RunAction(config).newTestRunner(new ArrayList<>()); assertThat( testRunner.getOptions().oraStuckTimeout, equalTo(2) ); } + + @Test + void expressionFilters() { + RunCommandConfig config = new RunCommandConfig.Builder() + .includeSchemaExpr("^APP$") + .excludeSchemaExpr("^APP_TEST$") + .includeObjectExpr("^PKG_") + .excludeObjectExpr("_TMP$") + .create(); + TestRunner testRunner = new RunAction(config).newTestRunner(new ArrayList<>()); + assertThat( testRunner.getOptions().includeSchemaExpr, equalTo("^APP$") ); + assertThat( testRunner.getOptions().excludeSchemaExpr, equalTo("^APP_TEST$") ); + assertThat( testRunner.getOptions().includeObjectExpr, equalTo("^PKG_") ); + assertThat( testRunner.getOptions().excludeObjectExpr, equalTo("_TMP$") ); + } }