From ebd036981c699dcebdca66ba61cd7964c807c45a Mon Sep 17 00:00:00 2001 From: john-otoole Date: Sun, 11 Jun 2017 22:32:58 +0100 Subject: [PATCH] Minor updates to the MD documentation files I've made a bunch of minor updates to the markdown files based on observations from reading them for the first time. Most of them are trivial updates, but check annotations.md in particular as was unsure about the third bullet point of section "A Suitepath can be provided in three ways". --- development/readme.md | 4 +-- development/releasing.md | 14 ++++---- docs/about/CONTRIBUTING.md | 2 +- docs/about/support.md | 4 +-- docs/userguide/annotations.md | 50 ++++++++++++++-------------- docs/userguide/best-practices.md | 26 +++++++-------- docs/userguide/running-unit-tests.md | 38 ++++++++++----------- docs/userguide/upgrade.md | 2 +- readme.md | 20 +++++------ 9 files changed, 80 insertions(+), 80 deletions(-) diff --git a/development/readme.md b/development/readme.md index 4bcea643d..5a0d0a50c 100644 --- a/development/readme.md +++ b/development/readme.md @@ -1,6 +1,6 @@ # Build Folder - Contains the build scripts that can be run locally on a developers machine to build run and test utPLSQL. + Contains the build scripts that can be run locally on a developer's machine to build, run and test utPLSQL. - These scripts are also used by Jenkins Continuous integration server to check each pull request before it is merged. + These scripts are also used by the Jenkins Continuous Integration server to check each pull request before it is merged. diff --git a/development/releasing.md b/development/releasing.md index 5e162721c..ece04df65 100644 --- a/development/releasing.md +++ b/development/releasing.md @@ -1,11 +1,11 @@ -Release process is automated in following way: -1) with every build, the build process on travis updatse files with appropriate version number before deployment into db. +The release process is automated in the following way: +1) With every build, the build process on Travis updates files with an appropriate version number before deployment into the database. This is to confirm that the update of versions works properly. -2) when build is executed on a branch named `release/v1.2.3-something` then additional steps are taken: - - project version in files: `sonar-project.properties`, `VERSION` is updated from the version number derived from release branch - - changes on those two files are committed and and pushed - this should happen only once, when the release branch is initially created on the main repo +2) When a build is executed on a branch named `release/v1.2.3-something` then additional steps are taken: + - the project version in files: `sonar-project.properties`, `VERSION` is updated from the version number derived from the release branch + - changes to those two files are committed and pushed - this should happen only once, when the release branch is initially created on the main repo 3) To create a release, just create a tag on the code to be released. The tag name must match the regex pattern: `^v[0-9]+\.[0-9]+\.[0-9]+.*$` - When a tag build is executed, the documentation is built and files are uploaded to the tag. - The version number is derived from the tag name. -4) Release version do not provide access to unversioned source files (the default zip file from github is empty). - The sources for release are provided in separate zip files delivered from travis build process. +4) The release version does not provide access to unversioned source files (the default zip file from GitHub is empty). + The sources for release are provided in separate zip files delivered from the Travis build process. diff --git a/docs/about/CONTRIBUTING.md b/docs/about/CONTRIBUTING.md index e4c757d49..51c28babe 100644 --- a/docs/about/CONTRIBUTING.md +++ b/docs/about/CONTRIBUTING.md @@ -1,6 +1,6 @@ ## How to contribute ## -The following are the guidelines, everyone should use to contribute to utPLSQL. +The following are the guidelines everyone should use to contribute to utPLSQL. Changes are welcome from all members of the Community. ## Getting Started ## diff --git a/docs/about/support.md b/docs/about/support.md index 751de7f77..579795528 100644 --- a/docs/about/support.md +++ b/docs/about/support.md @@ -1,4 +1,4 @@ # How to get support -- Feel free post questions, bugs or issues in the [issues area of GitHub](https://github.com/utPLSQL/utPLSQL/issues). -- Join developers the [utPLSQL team](http://utplsql-slack-invite.herokuapp.com) on [Slack](https://slack.com/) +- Feel free to post questions, bugs or issues in the [issues area of GitHub](https://github.com/utPLSQL/utPLSQL/issues) +- Join developers at the [utPLSQL team](http://utplsql-slack-invite.herokuapp.com) on [Slack](https://slack.com/) diff --git a/docs/userguide/annotations.md b/docs/userguide/annotations.md index 73c1c7301..386d65aa2 100644 --- a/docs/userguide/annotations.md +++ b/docs/userguide/annotations.md @@ -17,9 +17,9 @@ Procedure annotations are defined right before the procedure they reference, no If a package specification contains `%suite` annotation, it is treated as a test package and processed by the framework. -Some annotations accept parameters like `%suite`, `%test` `%displayname`. The parameters for annotations need to be placed in brackets. Values for parameters should be provided without any quotation marks. +Some annotations accept parameters like `%suite`, `%test` and `%displayname`. The parameters for annotations need to be placed in brackets. Values for parameters should be provided without any quotation marks. -# Example of annotated test package +# Example of an annotated test package ```sql create or replace package test_pkg is @@ -87,9 +87,9 @@ end test_pkg; It is very likely that the application for which you are going to introduce tests consists of many different packages or procedures/functions. Usually procedures can be logically grouped inside a package, there also might be several logical groups of procedure in a single package or even packages themselves might relate to a common module. -Lets say you have a complex insurance application the operates with policies, claims and payments. The payment module contains several packages for payment recognition, charging, planning etc. The payment recognition module among others contains a complex `recognize_payment` procedure that associates received money to the policies. +Let's say you have a complex insurance application that deals with policies, claims and payments. The payment module contains several packages for payment recognition, charging, planning etc. The payment recognition module among others contains a complex `recognize_payment` procedure that associates received money to the policies. -If you want to create tests for your application it is recommended to structure your tests similarly to the logical structure of you application. So you end up with something like: +If you want to create tests for your application it is recommended to structure your tests similarly to the logical structure of your application. So you end up with something like: * Integration tests * Policy tests * Claim tests @@ -98,7 +98,7 @@ If you want to create tests for your application it is recommended to structure * Payments set off * Payouts -The `%suitepath` annotation is used for such grouping. Even though test packages are defined in a flat structure the `%suitepath` is used by the framework to form a hierarchical structure of them. Your payments recognition test package might look like: +The `%suitepath` annotation is used for such grouping. Even though test packages are defined in a flat structure the `%suitepath` is used by the framework to form them into a hierarchical structure. Your payments recognition test package might look like: ```sql create or replace package test_payment_recognition as @@ -136,10 +136,10 @@ create or replace package test_payment_set_off as end test_payment_set_off; ``` -When you execute tests for your application, the framework constructs test suite for each test package. Then in combines suites into grouping suites by the `%suitepath` annotation value so that the fully qualified path to the `recognize_by_num` procedure is `USER:payments.test_payment_recognition.test_recognize_by_num`. If any of its expectations fails then the test is marked as failed, also the `test_payment_recognition` suite, the parent suite `payments` and the whole run is marked as failed. -The test report indicates which expectation has failed on the payments module. The payments recognition submodule is causing the failure as `recognize_by_num` has is not meeting the expectations of the test. Grouping tests into modules and submodules using the `%suitepath` annotation allows you to logically organize your projects flat structure of packages int functional groups. +When you execute tests for your application, the framework constructs a test suite for each test package. Then it combines suites into grouping suites by the `%suitepath` annotation value so that the fully qualified path to the `recognize_by_num` procedure is `USER:payments.test_payment_recognition.test_recognize_by_num`. If any of its expectations fails then the test is marked as failed, also the `test_payment_recognition` suite, the parent suite `payments` and the whole run is marked as failed. +The test report indicates which expectation has failed on the payments module. The payments recognition submodule is causing the failure as `recognize_by_num` has not met the expectations of the test. Grouping tests into modules and submodules using the `%suitepath` annotation allows you to logically organize your project's flat structure of packages into functional groups. -Additional advantage of such grouping is the fact that every element level of the grouping can be an actual unit test package containing module level common setup for all of the submodules. So in addition to the packages mentioned above you could have following package. +An additional advantage of such grouping is the fact that every element level of the grouping can be an actual unit test package containing a common module level setup for all of the submodules. So in addition to the packages mentioned above you could have the following package. ```sql create or replace package payments as @@ -153,38 +153,38 @@ create or replace package payments as end payments; ``` -A `%suitepath` can be provided in tree ways: -* schema - execute all test in the schema -* [schema]:suite1[.suite2][.suite3]...[.procedure] - execute all tests in all suites from suite1[.suite2][.suite3]...[.procedure] path. If schema is not provided, then current schema is used. Example: `:all.rooms_tests`. -* [schema.]package[.procedure] - execute all tests in the test package provided. The whole hierarchy of suites in the schema is build before, all before/after hooks of partn suites for th provided suite package are executed as well. Example: `tests.test_contact.test_last_name_validator` or simply `test_contact.test_last_name_validator` if `tests` is the current schema. +A `%suitepath` can be provided in three ways: +* schema - execute all tests in the schema +* [schema]:suite1[.suite2][.suite3]...[.procedure] - execute all tests in all suites from suite1[.suite2][.suite3]...[.procedure] path. If schema is not provided, then the current schema is used. Example: `:all.rooms_tests` +* [schema.]package[.procedure] - execute all tests in the specified test package. The whole hierarchy of suites in the schema is built before all before/after hooks or part suites for the provided suite package are executed as well. Example: `tests.test_contact.test_last_name_validator` or simply `test_contact.test_last_name_validator` if `tests` is the current schema. # Using automatic rollbacks in tests -By default, changes performed by every setup, cleanup and test procedure is isolated using savepoint. -This solution is suitable for use-cases, where the code that is getting tested as well as the unit tests themselves do not use transaction control (commit/rollback) or DDL commands. +By default, changes performed by every setup, cleanup and test procedure are isolated by savepoints. +This solution is suitable for use-cases where the code that is getting tested as well as the unit tests themselves do not use transaction control (commit/rollback) or DDL commands. In general, your unit tests should not use transaction control as long as the code you are testing is not using it too. -Keeping the transactions uncommitted allows your changes to be isolated and the execution of tests is not impacting others that might be using a shared development database. +Keeping the transactions uncommitted allows your changes to be isolated and the execution of tests does not impact others who might be using a shared development database. -If you are in situation, where the code you are testing, is using transaction control (common case with ETL code), then your tests probably should not use the default automatic transaction control. -In that case use the annotation `-- %rollback(manual)` on the suite level to disable automatic transaction control for entire suite. +If you are in a situation where the code you are testing uses transaction control (common case with ETL code), then your tests probably should not use the default automatic transaction control. +In that case use the annotation `-- %rollback(manual)` on the suite level to disable automatic transaction control for the entire suite. If you are using nested suites, you need to make sure that the entire suite all the way to the root is using manual transaction control. It is possible with utPLSQL to change the transaction control on individual suites or tests that are part of complex suite. -It is strongly recommended not to have mixed transaction control in suite. +It is strongly recommended not to have mixed transaction control in a suite. Mixed transaction control settings will not work properly when your suites are using shared setup/cleanup with beforeall, afterall, beforeeach or aftereach annotations. -Your suite will most probably fail with error or warning on execution. Some of the automatic rollbacks will most probably fail to execute depending on the configuration you have. +Your suite will most likely fail with error or warning on execution. Some of the automatic rollbacks will probably fail to execute depending on the configuration you have. -In some cases it is needed to perform DDL as part of setup or cleanup for the tests. -It is recommended to move such DDL statements to a procedure with `pragma autonomous_transaction` to eliminate implicit commit in the main session that is executing all your tests. -Doing so, allows your test to use automatic transaction control of the framework and release you from the burden of manual cleanup of data that was created or modified by test execution. +In some cases it is necessary to perform DDL as part of setup or cleanup for the tests. +It is recommended to move such DDL statements to a procedure with `pragma autonomous_transaction` to eliminate implicit commits in the main session that is executing all your tests. +Doing so allows your tests to use the framework's automatic transaction control and releases you from the burden of manual cleanup of data that was created or modified by test execution. -When you are running test of code that is performing an explicit or implicit commit, you may set the test procedure to run in autonomous transaction with `pragma autonomous_transaction`. -Keep in mind, that when your tests runs in autonomous transaction it will not see the data prepared in setup procedure unless the setup procedure committed the changes. +When you are testing code that performs explicit or implicit commits, you may set the test procedure to run as an autonomous transaction with `pragma autonomous_transaction`. +Keep in mind that when your tests runs in autonomous transaction it will not see the data prepared in setup procedure unless the setup procedure committed the changes. # Order of execution -When processing the test suite `test_pkg` defined in [Example of annotated test package](#example), the execution will be done in the following order. +When processing the test suite `test_pkg` defined in [Example of annotated test package](#example), the order of execution will be as follows. ``` create a savepoint 'beforeall' diff --git a/docs/userguide/best-practices.md b/docs/userguide/best-practices.md index 51ee5a80c..bdfcf99a7 100644 --- a/docs/userguide/best-practices.md +++ b/docs/userguide/best-practices.md @@ -1,13 +1,13 @@ # Best Practices -The following are best practices we as utPLSQL have learned about PL/SQL and Unit Testing. +The following are best practices we at utPLSQL have learned about PL/SQL and Unit Testing. ## Test Isolation and Dependency - Tests should not depend on a specific order to run - Tests should not depend on other tests to execute - - Tests should not depend on specific database state, they should setup the expected state before run - - Tests should keep environment unchanged post execution + - Tests should not depend on specific database state, they should setup the expected state before being run + - Tests should keep the environment unchanged post execution ## Writing tests @@ -21,26 +21,26 @@ The following are best practices we as utPLSQL have learned about PL/SQL and Uni - Each tested procedure/function/trigger (code block) should have more than one test - Each test should check only one behavior (one requirement) of the code block under test - Tests should be maintained as thoroughly as production code - - Every test needs to be build so that it can fail, tests that do not fail when needed are useless + - Every test needs to be built so that it can fail, tests that do not fail when needed are useless ## Gaining value from the tests - - Tests are only valuable if they are executed frequently, ideally - with every change to the project code - - Tests need to run very fast, the slower the tests - the longer you wait. Build tests with performance in mind (do you need to have 10k rows to run the tests?) - - Tests, that are not executed frequently enough get rotten pretty fast and bring burden instead of value. Maintain tests as you maintain code. - - Tests that are failing, need to be addressed immediately. How can you trust tour tests when 139 of 1000 tests are failing for a month? Will you be able to see each time that it is still the same 139 tests? + - Tests are only valuable if they are executed frequently; ideally with every change to the project code + - Tests need to run very fast; the slower the tests, the longer you wait. Build tests with performance in mind (do you really need to have 10k rows to run the tests?) + - Tests that are executed infrequently can quickly become stale and end up adding overhead rather than value. Maintain tests as you would maintain code. + - Tests that are failing need to be addressed immediately. How can you trust your tests when 139 of 1000 tests are failing for a month? Will you recognise each time that it is still the same 139 tests? ## Tests are not for production - Tests generate will generate and operate on fake data. They might insert/update and delete data. You don't want tests to run on production database and touch on real-life data. + Tests will generate and operate on fake data. They might insert, update and delete data. You don't want tests to run on a production database and affect real life data. -## Tests and their relationship to code under test. - - Code under test and tests should be in separate packages. This is fundamental separation of responsibilities. - - Test code commonly will be in the same schema as the tested code. This removes the need to manage privileges for the tests. +## Tests and their relationship to code under test + - Tests and the code under test should be in separate packages. This is a fundamental separation of responsibilities. + - It is common for test code to be in the same schema as the tested code. This removes the need to manage privileges for the tests. ## Version Control Use a version control system for your code. Don't just trust the database for code storage. This includes both the code under test, and the unit tests you develop as well. -Treat database as target, destination for your code not as a source of it. +Treat the database as a target/destination for your code, not as a source of it. diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md index 8fd5d28c4..d5bde9d77 100644 --- a/docs/userguide/running-unit-tests.md +++ b/docs/userguide/running-unit-tests.md @@ -1,17 +1,17 @@ # Running tests -utPLSQL framework provides two main entry points to run unit tests from within database: +The utPLSQL framework provides two main entry points to run unit tests from within the database: - `ut.run` procedures and functions - `ut_runner.run` procedures -Those two entry points differ in purpose and behavior. -Most of the times, you will want to use `ut.run` as the `ut_runner` is designed for API integration and does not output the results to the screen directly. +These two entry points differ in purpose and behavior. +Most of the time you will want to use `ut.run` as `ut_runner` is designed for API integration and does not output the results to the screen directly. # utPLSQL-sql-cli -If you are thinking about running you tests from a command line or from a CI server like Jenkins/Temcity the best way is to use the [utPLSQL-sql-cli](https://github.com/utPLSQL/utPLSQL-sql-cli) -You may download the latest release of the command line client automatically by using the below command (Unix). +If you are considering running your tests from a command line or from a CI server like Jenkins/Teamcity, the best way is to use the [utPLSQL-sql-cli](https://github.com/utPLSQL/utPLSQL-sql-cli). +You may download the latest release of the command line client automatically using the command below (Unix). ```bash #!/bin/bash @@ -25,17 +25,17 @@ unzip -q utplsql-sql-cli.zip # ut.run -Package `ut` contains overloaded procedures and functions `run`. -The `run` API is designed to be called directly by developer, when using IDE/SQL console to execute unit tests. +The `ut` package contains overloaded `run` procedures and functions. +The `run` API is designed to be called directly by a developer when using an IDE/SQL console to execute unit tests. The main benefit of using this API is it's simplicity. -One-line call is enough to execute a set of tests form one or multiple schemes. +A single line call is enough to execute a set of tests from one or more schemes. -The **procedures** execute specified tests and produces outputs to DBMS_OUTPUT using specified reporter -The **functions** can only be used in SELECT statements. They execute specified tests and produce outputs as a pipelined data stream to be consumed by select satement. +The **procedures** execute the specified tests and produce output to DBMS_OUTPUT using the specified reporter. +The **functions** can only be used in SELECT statements. They execute the specified tests and produce outputs as a pipelined data stream to be consumed by a select statement. ## ut.run procedures -Below examples illustrate different ways and options to invoke ut.run procedures. +The examples below illustrate different ways and options to invoke `ut.run` procedures. ```sql alter session set current_schema=hr; @@ -92,7 +92,7 @@ Using a list of items to execute allows you to execute a fine-grained set of tes **Note:** -`ut_documentation_reporter` is default reporter for all API's defined for running unit tests. +`ut_documentation_reporter` is the default reporter for all APIs defined for running unit tests. The `ut.run` procedures and functions accept `a_reporter` attribute that defines the reporter to be used in the run. You can execute any set of tests with any of the predefined reporters. @@ -112,7 +112,7 @@ For details on build-in reporters look at [reporters documentation](reporters.md The `ut.run` functions provide exactly the same functionality as the `ut.run` procedures. You may use the same sets of parameters with both functions and procedures. The only difference is the output of the results. -Functions provide outputs as pipelined stream and therefore need to be executed as select statements. +Functions provide output as a pipelined stream and therefore need to be executed as select statements. Example. ```sql @@ -121,16 +121,16 @@ select * from table(ut.run('hr.test_apply_bonus', ut_xunit_reporter())); # ut_runner.run procedures -The `ut_runner` provides API for integrating utPLSQL with other products. Maven, Jenkins, SQL Develper, PL/SQL Developer, TOAD and others can leverage this API to call utPLSQL. +The `ut_runner` package provides an API for integrating utPLSQL with other products. Maven, Jenkins, SQL Develper, PL/SQL Developer, TOAD and others can leverage this API to call utPLSQL. -The main difference as compared to `ut.run` API is that the `ut_runner.run` does not print outputs to the screen. +The main difference compared to the `ut.run` API is that `ut_runner.run` does not print output to the screen. -`ut_runner.run` accepts multiple reporters. Each reporter produces outputs into a separate output (uniquely identified by output_id). +`ut_runner.run` accepts multiple reporters. Each reporter pipes to a separate output (uniquely identified by output_id). Outputs of multiple reporters can be consumed in parallel. This allows for live reporting of test execution progress with threads and several database sessions. The concept is pretty simple. -- in the main thread (session), define the reporters to be used. Each reporter has it's output_id and so you need to extract and store those output_id's. -- as a separate thread, start the `ut_runner.run` and pass reporters with previously defined output_id's -- for each reporter start a separate thread and read outputs from `ut_output_buffer.get_lines` table function by providing the output_id defined in the main thread. +- in the main thread (session), define the reporters to be used. Each reporter has it's output_id and so you need to extract and store those output_ids. +- as a separate thread, start `ut_runner.run` and pass reporters with previously defined output_ids. +- for each reporter start a separate thread and read outputs from the `ut_output_buffer.get_lines` table function by providing the output_id defined in the main thread. diff --git a/docs/userguide/upgrade.md b/docs/userguide/upgrade.md index 79a790aa0..2105ded75 100644 --- a/docs/userguide/upgrade.md +++ b/docs/userguide/upgrade.md @@ -1,5 +1,5 @@ # How to upgrade from prior versions -utPLSQL v3 is a total rewrite of previous version. There is no automated way to migrate tests from version 2.x to version 3. +utPLSQL v3 is a total rewrite of the previous version. There is no automated way to migrate tests from version 2.x to version 3. There are plans to build a mapping/bridging solution that would allow running v2 tests using v3 framework. diff --git a/readme.md b/readme.md index 54e2bbfb9..8a1053f01 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ ---------- utPLSQL version 3 is a complete rewrite of utPLSQL v2 from scratch. Version 2 still supports older versions of Oracle that are no longer available. -The community that had developed on GitHub, decided that a new internal architecture was needed, from that version 3 was born. +The community that had developed on GitHub decided that a new internal architecture was needed, from that version 3 was born. # Introduction utPLSQL is a Unit Testing framework for Oracle PL/SQL and SQL. @@ -51,8 +51,8 @@ Full documentation of the project is automatically published on [utPLSQL github We welcome new developers to join our community and contribute to the utPLSQL project. If you are interested in helping please read our [guide to contributing](docs/about/CONTRIBUTING.md) -The best place to start is to read the documentation and get familiar existing with code base. -A [slack chat](https://utplsql.slack.com/) is the place to go isf you want to talk with team members. +The best place to start is to read the documentation and get familiar with the existing code base. +A [slack chat](https://utplsql.slack.com/) is the place to go if you want to talk with team members. To sign up to the chat use [this link](http://utplsql-slack-invite.herokuapp.com/) @@ -60,7 +60,7 @@ To sign up to the chat use [this link](http://utplsql-slack-invite.herokuapp.com __Version 2 to Version 3 Comparison__ -If you have great feature in mind, that you would like to see in utPLSQL v3 please create an [issue on GitHub](https://github.com/utPLSQL/utPLSQL/issues) or discuss it with us in the [Slack chat rooms](http://utplsql-slack-invite.herokuapp.com/). +If you have a great feature in mind, that you would like to see in utPLSQL v3 please create an [issue on GitHub](https://github.com/utPLSQL/utPLSQL/issues) or discuss it with us in the [Slack chat rooms](http://utplsql-slack-invite.herokuapp.com/). | Feature | Version 2 | Version 3 | @@ -81,7 +81,7 @@ If you have great feature in mind, that you would like to see in utPLSQL v3 plea | Unconstrained naming of Test packages | No - prefixes | Yes - name not relevant| | Require Prefix on Test procedures | No - prefixes | Yes - name not relevant| | Auto Compilation of Tests | Yes | No (Let us know if you use this) | -| Assertion Library | 30 assertions2 | 26 matchers (13 + 13 megated) | +| Assertion Library | 30 assertions2 | 26 matchers (13 + 13 negated) | | Extendable assertions | No | Yes - custom matchers | | PLSQL Record Assertions | generated code through **utRecEq** Package | [possible on Oracle 12c](https://oracle-base.com/articles/12c/using-the-table-operator-with-locally-defined-types-in-plsql-12cr1) using [cursor matchers](docs/userguide/expectations.md#comparing-cursors)| | Test Skeleton Generation | Yes | On Roadmap | @@ -111,13 +111,13 @@ If you have great feature in mind, that you would like to see in utPLSQL v3 plea 2 **utAssert2** package - Contains 59 Assertions - 2 Not implemented = 57, 28 are duplicated only change on outcome_in parameter 57-28 = 29, **utPipe** package - Contains 1 Assertion 29 + 1 = 30 -3 Test execution comparison is in a single call so the results are combined. We know it was always possible group in any way with multiple calls. But that may not be desired under CI system where you want a single JUnit XML Output. +3 Test execution comparison is in a single call so the results are combined. We know it was always possible to group in any way with multiple calls. But that may not be desired under a CI system where you want a single JUnit XML Output. # Installation To simply install the utPLSQL into a new database schema and grant it to public, execute the script `install_headless.sql`. -This will create a new user `UT3` with password `UT3`, grant all needed privileges to that user and create PUBLIC synonyms needed tu sue the utPLSQL framework. +This will create a new user `UT3` with password `UT3`, grant all required privileges to that user and create PUBLIC synonyms needed to use the utPLSQL framework. Example invocation of the script from command line: ```bash @@ -130,9 +130,9 @@ For detailed instructions on other install options see the [Install Guide](docs/ # Example unit test packages The below test package is a fully-functional Unit Test package for testing a [`betwnstr` function](examples/between_string/betwnstr.sql). -Package specification is [annotated](docs/userguide/annotations.md) with special comments. -Annotations define that a package is a unit test suite, they also allow defining a description for the suite as well as the test itself. -Package body consists of procedures containing unit test code. To validate [an expectation](docs/userguide/expectations.md) in test, use `ut.expect( actual_data ).to_( ... )` syntax. +The package specification is [annotated](docs/userguide/annotations.md) with special comments. +The annotations define that a package is a unit test suite, they also allow defining a description for the suite as well as the test itself. +The package body consists of procedures containing unit test code. To validate [an expectation](docs/userguide/expectations.md) in test, use `ut.expect( actual_data ).to_( ... )` syntax. ```sql create or replace package test_between_string as