[![latest-release](https://img.shields.io/github/release/utPLSQL/utPLSQL-maven-plugin.svg)](https://github.com/utPLSQL/utPLSQL-maven-plugin/releases) [![license](https://img.shields.io/github/license/utPLSQL/utPLSQL-maven-plugin.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![Build](https://github.com/utPLSQL/utPLSQL-maven-plugin/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/utPLSQL/utPLSQL-maven-plugin/actions/workflows/build.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=utPLSQL_utPLSQL-maven-plugin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=utPLSQL_utPLSQL-maven-plugin) # utPLSQL-maven-plugin A Maven plugin that runs [utPLSQL](https://www.utplsql.org/) v3 unit tests in an Oracle database as part of the Maven `test` phase, and writes test results and code coverage reports that CI servers and tools such as SonarQube can read. For writing tests, reporters and code coverage, see the [utPLSQL documentation](https://www.utplsql.org/utPLSQL/latest/). ## Compatibility The plugin works with utPLSQL 3.1.0 or newer installed in the database. ## Prerequisites * Java 17 or newer * Maven 3.9.9 or newer ## Quick start Add the plugin to your `pom.xml` and provide the database connection: ```xml jdbc:oracle:thin:@//localhost:1521/FREEPDB1 app app_password org.utplsql utplsql-maven-plugin 3.2.0 test ``` Then run: ```bash mvn test ``` With no further configuration, the plugin: * runs all test suites in the schema of the connected user, * maps source files from `src/main/plsql` (`**/*.*`) and test files from `src/test/plsql` (`**/*.pkg`) to database objects for coverage reporting, * prints results to the console with `UT_DOCUMENTATION_REPORTER`, * fails the build when any test fails or errors. ## Database connection The connection is configured with three properties. Each can be set in the `pom.xml` or passed on the command line: | Property | Description | Example | |----------|------------------------------------------------------------------------------|---------------------------------------------| | `dbUrl` | JDBC URL of the database | `-DdbUrl=jdbc:oracle:thin:@//host:1521/svc` | | `dbUser` | Database user; leave unset when using an [Oracle Wallet](#oracle-wallet-secure-external-password-store) | `-DdbUser=app` | | `dbPass` | Password of `dbUser` | `-DdbPass=app_password` | ```bash mvn test -DdbUrl=jdbc:oracle:thin:@//localhost:1521/FREEPDB1 -DdbUser=app -DdbPass=app_password ``` ### Oracle Wallet (Secure External Password Store) To keep the database password out of the `pom.xml` and the command line, store the credentials in an Oracle Wallet, leave `dbUser` and `dbPass` unset, and point `dbUrl` to the TNS alias of the stored credential: ```xml jdbc:oracle:thin:@MYDATABASE ``` Setup example: ```bash # create an auto-login wallet with credentials for TNS alias MYDATABASE orapki wallet create -wallet $HOME/oracle/wallet -auto_login_local mkstore -wrl $HOME/oracle/wallet -createCredential MYDATABASE someusername # point the JDBC driver to the wallet echo "oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=$HOME/oracle/wallet)))" \ > $HOME/oracle/network/admin/ojdbc.properties # tnsnames.ora with the MYDATABASE entry must be in the same directory export TNS_ADMIN=$HOME/oracle/network/admin ``` The JDBC driver looks for `tnsnames.ora` and `ojdbc.properties` in the directory given by, in order of precedence: 1. the `TNS_ADMIN` parameter in the URL, e.g. `jdbc:oracle:thin:@MYDATABASE?TNS_ADMIN=/path/to/network/admin` 2. the Java system property `oracle.net.tns_admin`, e.g. `export MAVEN_OPTS="-Doracle.net.tns_admin=/path/to/network/admin"` 3. the `TNS_ADMIN` environment variable The TNS alias used in `dbUrl` must match the alias of the credential stored in the wallet. ## Selecting tests By default, all suites in the schema of the connected user are run. Use `paths` to run specific schemas, suites, packages or procedures, and `tags` to run only tests with the given tags: ```xml app app:com.my_org.my_project fast ``` A path has one of the formats `schema[.package[.procedure]]` or `schema:suite[.suite[.suite][...]][.procedure]`, and both formats can be mixed. See [Running tests](https://www.utplsql.org/utPLSQL/latest/userguide/running-unit-tests.html) and [Run by tags](https://www.utplsql.org/utPLSQL/latest/userguide/running-unit-tests.html#run-by-tags) in the utPLSQL documentation. To detect hidden dependencies between tests, run them in [random order](https://www.utplsql.org/utPLSQL/latest/userguide/running-unit-tests.html#random-order) with `randomTestOrder`. Set `randomTestOrderSeed` to repeat a particular order. ## Reporters Reporters decide the format of the results. Each reporter writes to a file, to the console, or both: ```xml UT_DOCUMENTATION_REPORTER UT_SONAR_TEST_REPORTER utplsql/sonar-test-report.xml UT_COVERAGE_SONAR_REPORTER utplsql/coverage-sonar-report.xml true ``` * `name` is the name of a utPLSQL reporter (case-insensitive). Custom reporters installed in the database can be used as well. * `fileOutput` is the report file. Relative paths are resolved against the build directory (`target` by default). * `consoleOutput` prints the report to the console. It defaults to `true` when no `fileOutput` is given, and to `false` otherwise. * Without any `reporters`, `UT_DOCUMENTATION_REPORTER` prints to the console. Reporters provided by utPLSQL (see [Reporters](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html) for details and the reporters available in your version): | Reporter | Output | |----------------------------------|--------------------------------------------------------------------------------------------------------| | `UT_DOCUMENTATION_REPORTER` | [Human-readable test results](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#documentation-reporter) | | `UT_JUNIT_REPORTER` | [JUnit XML](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#junit-reporter) | | `UT_TFS_JUNIT_REPORTER` | [JUnit XML for TFS / Azure DevOps](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#tfs-vsts-reporter) | | `UT_TEAMCITY_REPORTER` | [TeamCity service messages](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#teamcity-reporter) | | `UT_SONAR_TEST_REPORTER` | [SonarQube generic test execution](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#sonar-test-reporter) | | `UT_TAP_REPORTER` | [Test Anything Protocol](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#tap-reporter) | | `UT_DEBUG_REPORTER` | [Diagnostic output of the test run](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#debug-reporter) | | `UT_COVERAGE_HTML_REPORTER` | [Code coverage as HTML](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#coverage-reporters) | | `UT_COVERAGE_SONAR_REPORTER` | [Code coverage for SonarQube](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#coverage-reporters) | | `UT_COVERAGE_COBERTURA_REPORTER` | [Code coverage in Cobertura format](https://www.utplsql.org/utPLSQL/latest/userguide/reporters.html#coverage-reporters) | ## Code coverage Code coverage is gathered whenever a coverage reporter is configured. How utPLSQL gathers and reports coverage is described in [Coverage](https://www.utplsql.org/utPLSQL/latest/userguide/coverage.html). ### Choosing the objects to report | Parameter | Description | |---------------------|--------------------------------------------------------------------------------------| | `includeObject` | Comma-separated list of objects to include, format `[schema.]object[,[schema.]object ...]` | | `excludeObject` | Comma-separated list of objects to exclude, same format as `includeObject` | | `includeSchemaExpr` | Regular expression for the names of schemas to include | | `excludeSchemaExpr` | Regular expression for the names of schemas to exclude | | `includeObjectExpr` | Regular expression for the names of objects to include | | `excludeObjectExpr` | Regular expression for the names of objects to exclude | The regular expression filters need a utPLSQL version that supports them. See [Coverage reporting options](https://www.utplsql.org/utPLSQL/latest/userguide/coverage.html#coverage-reporting-options). ### Mapping project files to database objects For [project based coverage](https://www.utplsql.org/utPLSQL/latest/userguide/coverage.html#project-based-coverage), utPLSQL reports coverage per source file instead of per database object. The plugin passes the files found by `sources` and `tests` to utPLSQL, which maps each file to a database object by its path: * `sources` / `tests` select the files (`directory` and `includes`). They default to `src/main/plsql` with `**/*.*` and `src/test/plsql` with `**/*.pkg`. * `sourcesOwner` / `testsOwner` set the schema owning the objects. * `sourcesRegexExpression`, `sourcesOwnerSubexpression`, `sourcesNameSubexpression` and `sourcesTypeSubexpression` (and their `tests...` counterparts) describe how the owner, name and type are read from the file path. * `sourcesCustomTypeMapping` / `testsCustomTypeMapping` map directory names or file extensions to object types. ## Skipping tests The utPLSQL tests are skipped together with other tests by Maven's standard `-DskipTests` or `-Dmaven.test.skip=true`: ```bash mvn install -DskipTests ``` To skip only the utPLSQL tests, set `skipUtplsqlTests` to `true` in the plugin configuration or on the command line: ```bash mvn install -DskipUtplsqlTests=true ``` `skipUtplsqlTests` takes precedence over `skipTests` and `maven.test.skip`. To skip other tests but run the utPLSQL tests, set it to `false`: ```bash mvn install -DskipTests -DskipUtplsqlTests=false ``` To skip the tests by default and enable them only when needed, set the property in the `pom.xml`: ```xml true ``` and override it on the command line: ```bash mvn install -DskipUtplsqlTests=false ``` To run all tests but not fail the build on test failures, set `ignoreFailure` to `true`, or pass Maven's standard `-Dmaven.test.failure.ignore=true`. ## Configuration reference All parameters are optional: ```xml 4.0.0 org.my_org my-artifact-name 1.0.0 jdbc:oracle:thin:@//localhost:1521/FREEPDB1 app app_password org.utplsql utplsql-maven-plugin 3.2.0 test app fast true 5 false false false 0 UT_DOCUMENTATION_REPORTER UT_SONAR_TEST_REPORTER utplsql/sonar-test-report.xml false UT_COVERAGE_SONAR_REPORTER utplsql/coverage-sonar-report.xml app.pkg_orders,app.pkg_customers app.pkg_logging ^APP$ ^APP_TEST$ ^PKG_ _TMP$ src/main/plsql **/*.pks **/*.pkb .*/(\w+)/(\w+)/(\w+)\.\w{3} 1 2 3 package body package_bodies src/test/plsql **/*.pks **/*.pkb .*/(\w+)/(\w+)/(\w+)\.\w{3} 1 2 3 package body package_bodies ``` ## Sample projects The plugin's integration tests double as examples, in [`src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT): * [`minimalist`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/minimalist): no plugin configuration, only the connection. * [`simple`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/simple): standard project directory structure with Sonar reporters. * [`regex`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/regex): custom directory structure, mapped to database objects with `sourcesRegexExpression`, `testsRegexExpression` and related parameters. * [`type_mapping`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/type_mapping): regular expressions combined with custom type mappings. * [`owner_param`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/owner_param): `sourcesOwner` and `testsOwner`. * [`tags`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/tags): running tests by tag. * [`include_object`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/include_object), [`exclude_object`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/exclude_object), [`include_object_expr`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/include_object_expr) and [`exclude_object_expr`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/exclude_object_expr): choosing the objects in the coverage report. * [`ora_stuck_timeout`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/ora_stuck_timeout): `oraStuckTimeout`. * [`skip`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/skip): `skipUtplsqlTests`. * [`skip_tests`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/skip_tests), [`maven_test_skip`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/maven_test_skip) and [`skip_tests_overridden_by_skip_utplsql_tests`](src/test/resources-its/org/utplsql/maven/plugin/UtPlsqlMojoIT/skip_tests_overridden_by_skip_utplsql_tests): skipping with `-DskipTests` and `-Dmaven.test.skip=true`, run with the system properties set in `UtPlsqlMojoIT`. ## Comparison with utPLSQL-cli [utPLSQL-cli](https://github.com/utPLSQL/utPLSQL-cli) runs the same tests from the command line. The table maps its [`run` command options](https://github.com/utPLSQL/utPLSQL-cli#run) to the plugin configuration: | utPLSQL-cli option | Maven configuration | |------------------------------------|----------------------------------------------------------| | `` | `dbUrl`, `dbUser`, `dbPass` | | `-p`, `--path` | `paths.path` | | `--tags` | `tags.tag` | | `-f`, `--format` | `reporters.reporter.name` | | `-o` | `reporters.reporter.fileOutput` | | `-s` | `reporters.reporter.consoleOutput` | | `-c`, `--color` | follows Maven's console color setting | | `--failure-exit-code` | not available; use `ignoreFailure` to not fail the build | | `-scc`, `--skip-compatibility-check` | `skipCompatibilityCheck` | | `-D`, `--dbms_output` | `dbmsOutput` | | `-r`, `--random-test-order` | `randomTestOrder` | | `-seed`, `--random-test-order-seed` | `randomTestOrderSeed` | | `--ora-stuck-timeout` | `oraStuckTimeout` | | `-include` | `includeObject` | | `-exclude` | `excludeObject` | | not available | `includeSchemaExpr`, `excludeSchemaExpr`, `includeObjectExpr`, `excludeObjectExpr` | | not available | `skipUtplsqlTests` | | `--coverage-schemes` | not available | | `-t`, `--timeout` | not available | | `-source_path` | `sources.source.directory` | | `-owner` | `sourcesOwner` | | `-regex_expression` | `sourcesRegexExpression` | | `-type_mapping` | `sourcesCustomTypeMapping.customTypeMapping` | | `-owner_subexpression` | `sourcesOwnerSubexpression` | | `-type_subexpression` | `sourcesTypeSubexpression` | | `-name_subexpression` | `sourcesNameSubexpression` | | `-test_path` | `tests.test.directory` | | `-owner` | `testsOwner` | | `-regex_expression` | `testsRegexExpression` | | `-type_mapping` | `testsCustomTypeMapping.customTypeMapping` | | `-owner_subexpression` | `testsOwnerSubexpression` | | `-type_subexpression` | `testsTypeSubexpression` | | `-name_subexpression` | `testsNameSubexpression` | In utPLSQL-cli, `-owner`, `-regex_expression` and the other mapping options apply to the preceding `-source_path` or `-test_path`.