Skip to content

Commit 6e034bf

Browse files
committed
Merge branch 'develop' of https://github.com/utPLSQL/utPLSQL into feature/pure_sql
2 parents 21dca2b + 80ff76c commit 6e034bf

File tree

132 files changed

+3996
-2524
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+3996
-2524
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ node_modules/
1515
utPLSQL_latest_release/
1616
utPLSQL-cli/
1717
development/env.sh
18+
development/*.jar
1819
*.log
1920

2021
# exclusions based on artifacts created via actions documented in CONTRIBUTING.md

CONTRIBUTING.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,18 @@ export CONNECTION_STR=127.0.0.1:1521/xe # Adjust the connect string
8989
export ORACLE_PWD=oracle # Adjust your local SYS password
9090
```
9191

92+
### Download Oracle JDBC drivers
93+
94+
Download `ojdbc8-xxx.jar` and `orai18n-xxx.jar` from [Oracle](https://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html).
95+
Place them in `development` directory of the project.
96+
97+
9298
### Download utPLSQL release sources and utplsq-cli
9399

94100
The below script is fetching latest release version from utPLSQL repository. Latest release version is used for self-testing.
95101
```bash
96102
development/refresh_sources.sh
97103
```
98-
> **Important notice:**
99-
> You'll have to provide the ojdbc.jar in the folder utPLSQL-cli/lib manually due to Oracle licensing restrictions.
100104

101105
### Setup local database for utPLSQL development
102106

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v3.1.3-develop
1+
v3.1.4-develop

development/refresh_sources.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ curl -Lk -o utPLSQL-cli.zip https://github.com/utPLSQL/utPLSQL-cli/releases/down
1616
# unzip utPLSQL-cli and remove the zip file
1717
unzip utPLSQL-cli.zip && chmod u+x utPLSQL-cli/bin/utplsql && rm utPLSQL-cli.zip
1818

19+
cp development/*.jar utPLSQL-cli/lib/

development/releasing.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ To create a release:
99
- wait for th build to complete successfully
1010
- merge the release branch to master and wait for master build to complete successfully
1111
- create a release from the master branch using [github releases page](https://github.com/utPLSQL/utPLSQL/releases) and populate release description using information found on the issues and pull requests since previous release.
12-
To find issues closed after certain date use [advanced filters](https://help.github.com/articles/searching-issues-and-pull-requests/#search-by-open-or-closed-state)
12+
To find issues closed after certain date use [advanced filters](https://help.github.com/articles/searching-issues-and-pull-requests/#search-by-open-or-closed-state).
13+
Example: [`is:issue closed:>2018-07-22`](https://github.com/utPLSQL/utPLSQL/issues?utf8=%E2%9C%93&q=is%3Aissue+closed%3A%3E2018-07-22+)
1314

1415
The following will happen:
1516
- build executed on branch `release/vX.Y.Z-[something]` updates files `sonar-project.properties`, `VERSION` with project version derived from the release branch name

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ The framework follows industry standards and best patterns of modern Unit Testin
1010
- [Expectations](userguide/expectations.md)
1111
- [Advanced data comparison](userguide/advanced_data_comparison.md)
1212
- [Running unit tests](userguide/running-unit-tests.md)
13+
- [Querying for test suites](userguide/querying_suites.md)
1314
- [Testing best pracitces](userguide/best-practices.md)
1415
- [Upgrade utPLSQL](userguide/upgrade.md)
1516
- Reporting

docs/userguide/expectations.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,8 @@ utPLSQL is capable of comparing compound data-types including:
683683
- Cursors, nested table and varray types are compared as **ordered lists of elements**. If order of elements differ, expectation will fail.
684684
- Comparison of compound data is data-type aware. So a column `ID NUMBER` in a cursor is not the same as `ID VARCHAR2(100)`, even if they both hold the same numeric values.
685685
- Comparison of cursor columns containing `DATE` will only compare date part **and ignore time** by default. See [Comparing cursor data containing DATE fields](#comparing-cursor-data-containing-date-fields) to check how to enable date-time comparison in cursors.
686+
- Comparison of cursor returning `TIMESTAMP` **columns** against cursor returning `TIMESTAMP` **bind variables** requires variables to be casted to proper precision. This is an Oracle SQL - PLSQL compatibility issue and usage of CAST is the only known workaround for now.
687+
See [Comparing cursor data containing TIMESTAMP bind variables](#comparing-cursor-data-containing-timestamp-bind-variables) for examples.
686688
- To compare nested table/varray type you need to convert it to `anydata` by using `anydata.convertCollection()`
687689
- To compare object type you need to convert it to `anydata` by using `anydata.convertObject()`
688690
- It is possible to compare PL/SQL records, collections, varrays and associative arrays. To compare this types of data, use cursor comparison feature of utPLSQL and TABLE operator in SQL query
@@ -987,6 +989,100 @@ In the above example:
987989
- The test `get_events_for_date_range` will succeed, as the `l_expected_bad_date` cursor contains different date-time then the cursor returned by `get_events` function call.
988990
- The test `bad_test` will fail, as the column `event_date` will get compared as DATE without TIME.
989991

992+
### Comparing cursor data containing TIMESTAMP bind variables
993+
994+
To properly compare `timestamp` column data returned by cursor against bind variable data from another cursor, a conversion needs to be done.
995+
996+
This applies to `timestamp`,`timestamp with timezone`, `timestamp with local timezone` data types.
997+
998+
Example below illustrates usage of `cast` operator to assure appropriate precision is applied on timestamp bind-variables in cursor result-set
999+
```sql
1000+
drop table timestamps;
1001+
create table timestamps (
1002+
ts3 timestamp (3),
1003+
ts6 timestamp (6),
1004+
ts9 timestamp (9)
1005+
);
1006+
1007+
create or replace package timestamps_api is
1008+
procedure load (
1009+
i_timestamp3 timestamps.ts3%type,
1010+
i_timestamp6 timestamps.ts6%type,
1011+
i_timestamp9 timestamps.ts9%type
1012+
);
1013+
end;
1014+
/
1015+
1016+
create or replace package body timestamps_api is
1017+
procedure load (
1018+
i_timestamp3 timestamps.ts3%type,
1019+
i_timestamp6 timestamps.ts6%type,
1020+
i_timestamp9 timestamps.ts9%type
1021+
)
1022+
is
1023+
begin
1024+
insert into timestamps (ts3, ts6, ts9)
1025+
values (i_timestamp3, i_timestamp6, i_timestamp9);
1026+
end;
1027+
end;
1028+
/
1029+
1030+
1031+
create or replace package test_timestamps_api is
1032+
-- %suite
1033+
1034+
-- %test(Loads data into timestamps table)
1035+
procedure test_load;
1036+
end;
1037+
/
1038+
1039+
create or replace package body test_timestamps_api is
1040+
procedure test_load is
1041+
l_time timestamp(9);
1042+
l_expected sys_refcursor;
1043+
l_actual sys_refcursor;
1044+
begin
1045+
--Arrange
1046+
l_time := systimestamp;
1047+
1048+
open l_expected for
1049+
select
1050+
cast(l_time as timestamp(3)) as ts3,
1051+
cast(l_time as timestamp(6)) as ts6,
1052+
cast(l_time as timestamp(9)) as ts9
1053+
from dual;
1054+
1055+
--Act
1056+
timestamps_api.load (
1057+
l_time, l_time, l_time
1058+
);
1059+
1060+
--Assert
1061+
open l_actual for
1062+
select ts3, ts6, ts9
1063+
from timestamps;
1064+
1065+
ut.expect (l_actual).to_equal (l_expected);
1066+
1067+
end;
1068+
end;
1069+
/
1070+
1071+
begin
1072+
ut.run ('test_timestamps_api');
1073+
end;
1074+
/
1075+
```
1076+
1077+
The execution of the above runs successfully
1078+
```
1079+
test_timestamps_api
1080+
Loads data into timestamps table [.046 sec]
1081+
1082+
Finished in .048181 seconds
1083+
1 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)
1084+
```
1085+
9901086

9911087
# Negating a matcher
9921088
Expectations provide a very convenient way to perform a check on a negated matcher.

docs/userguide/querying_suites.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Qyerying for test suites
2+
3+
4+
## Obtaining information about suites
5+
6+
utPLSQL framework provides ability to read inforamtion about unit test suites that exist in a schema.
7+
8+
Pipelined table function `ut_runner.get_suites_info(a_owner, a_package_name)` allows you to retrieve information about:
9+
10+
- all suites that exist in a given user/schema
11+
- individual test suite pacakage
12+
13+
Querying the data from function provides the follwing details:
14+
15+
- `object_owner` - the owner of test suite packages
16+
- `object_name` - the name of test suite package
17+
- `item_name` - the name of suite/test
18+
- `item_description` - the description of suite/suite item
19+
- `item_type` - the type of item (UT_SUITE/UT_SUITE_CONTEXT/UT_TEST/UT_LOGICAL_SUITE)
20+
- `item_line_no` - line_number where annotation identifying the item exists
21+
- `path` - suitepath of the item
22+
- `disabled_flag` - (0/1) indicator if item is disabled by --%disabled annotation
23+
24+
To get list of all test suites in current schema
25+
```sql
26+
select * from table(ut_runner.get_suites_info()) where item_type = 'UT_SUITE';
27+
```
28+
29+
To get list of all tests for test suite `TEST_STUFF` in current user schema
30+
```sql
31+
select * from table(ut_runner.get_suites_info(USER, 'TEST_STUFF')) where item_type = 'UT_TEST';
32+
```
33+
34+
To get a full information about suite `TEST_STUFF` including suite description, all contexts and tests in a suite
35+
```sql
36+
select * from table(ut_runner.get_suites_info(USER, 'TEST_STUFF')) where item_type = 'UT_TEST';
37+
```
38+
39+
## Checking if schema contains tests
40+
41+
Function `ut_runner.has_suites(a_owner)` returns boolean value indicating if given schema contains test suites.
42+
43+
Example:
44+
```sql
45+
begin
46+
if ut_runner.has_suites(USER) then
47+
dbms_output.put_line( 'User '||USER||' owns test suites' );
48+
else
49+
dbms_output.put_line( 'User '||USER||' does not own test suites' );
50+
end if;
51+
end;
52+
```
53+
54+
## Checking if package is a test suite
55+
56+
Function `ut_runner.is_suite(a_owner, a_package_name) ` returns boolean value indicating if given package is a test suites.
57+
58+
Example:
59+
```sql
60+
begin
61+
if ut_runner.is_suite(USER,'TEST_STUFF') then
62+
dbms_output.put_line( 'Package '||USER||'.TEST_STUFF is a test suite' );
63+
else
64+
dbms_output.put_line( 'Package '||USER||'.TEST_STUFF is not a test suite' );
65+
end if;
66+
end;
67+
```
68+
69+
## Checking if procedure is a test within a suite
70+
71+
Function `ut_runner.is_test(a_owner, a_package_name, a_procedure_name) ` returns boolean value indicating if given package is a test suites.
72+
73+
Example:
74+
```sql
75+
begin
76+
if ut_runner.is_test(USER,'TEST_STUFF','A_TEST_TO_CHECK_STUFF') then
77+
dbms_output.put_line( 'Procedure '||USER||'.TEST_STUFF.A_TEST_TO_CHECK_STUFF is a test' );
78+
else
79+
dbms_output.put_line( 'Procedure '||USER||'.TEST_STUFF.A_TEST_TO_CHECK_STUFF is not a test' );
80+
end if;
81+
end;
82+
```
83+

docs/userguide/reporters.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Example outputs from documentation reporter.
4242
# JUnit reporter
4343

4444
Most of continuous integration servers (like Jenkins) are capable of consuming unit test execution results in [JUnit](https://en.wikipedia.org/wiki/JUnit) format.
45-
The `ut_junit_reporter` in earlier version referred as ut_xunit_reporter is producing outcomes as JUnit-compatible XML unit test report, that can be used by CI servers to display their custom reports and provide metrics (like tests execution trends).
45+
The `ut_junit_reporter` in earlier version referred as `ut_xunit_reporter` is producing outcomes as JUnit-compatible XML unit test report, that can be used by CI servers to display their custom reports and provide metrics (like tests execution trends).
4646
Please note that in previous versions it was called ut_xunit_reporter and for backward compatibility that name still exists.
4747

4848
Invocation of tests with JUnit reporter.
@@ -63,7 +63,7 @@ Example of failure report details
6363

6464
# Teamcity reporter
6565

66-
[Teamcity](https://www.jetbrains.com/teamcity/) is a CI server by Jetbrains. It supports XUnit reporting and additionally has it's own format of reporting that allows tracking of progress of a CI step/task as it executes.
66+
[Teamcity](https://www.jetbrains.com/teamcity/) is a CI server by Jetbrains. It supports JUnit reporting and additionally has it's own format of reporting that allows tracking of progress of a CI step/task as it executes.
6767
The TeamCity format developed by Jetbrains is supported by utPLSQL with `ut_teamcity_reporter`.
6868

6969
Invocation of tests with Teamcity reporter.
@@ -74,11 +74,11 @@ The `ut_teamcity_reporter` doesn't accept any arguments.
7474

7575
Example of unit test report from Teamcity CI server.
7676

77-
![xunit_reporter_outputs](../images/teamcity_report_example.png)
77+
![junit_reporter_outputs](../images/teamcity_report_example.png)
7878

7979
Example of failure report details
8080

81-
![xunit_reporter_outputs](../images/teamcity_report_example_errors.png)
81+
![junit_reporter_outputs_errors](../images/teamcity_report_example_errors.png)
8282

8383

8484
# Sonar test reporter

docs/userguide/running-unit-tests.md

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Running tests
22

3-
The utPLSQL framework provides two main entry points to run unit tests from within the database:
3+
utPLSQL framework provides two main entry points to run unit tests from within the database:
44

55
- `ut.run` procedures and functions
66
- `ut_runner.run` procedures
77

88
These two entry points differ in purpose and behavior.
9-
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.
9+
Most of the time you will want to use `ut.run` as `ut_runner.run` is designed for API integration and does not display the results to the screen.
1010

1111
# Running from CI servers and command line
1212

@@ -123,14 +123,34 @@ You can execute any set of tests with any of the predefined reporters.
123123

124124
```sql
125125
begin
126-
ut.run('hr.test_apply_bonus', ut_xunit_reporter());
126+
ut.run('hr.test_apply_bonus', ut_junit_reporter());
127127
end;
128128
```
129-
Executes all tests from package _HR.TEST_APPLY_BONUS_ and provide outputs to DBMS_OUTPUT using the XUnit reporter.
129+
Executes all tests from package _HR.TEST_APPLY_BONUS_ and provide outputs to DBMS_OUTPUT using the JUnit reporter.
130130

131131

132132
For details on build-in reporters look at [reporters documentation](reporters.md).
133133

134+
## Keeping uncommited data after test-run
135+
136+
utPLSQL by default runs tests in autonomous transaction and performs automatic rollback to assure that tests do not impact one-another and do not have impact on the current session in your IDE.
137+
138+
If you would like to keep your uncommited data persisted after running tests, you can do so by using `a_force_manual_rollback` flag.
139+
Setting this flag to true has following side-effects:
140+
141+
- test execution is done in current transaction - if while running tests commit or rollback is issued your current session data will get commited too.
142+
- automatic rollback is forced to be disabled in test-run even if it was explicitly enabled by using annotation `--%rollback(manual)
143+
144+
Example invocation:
145+
```sql
146+
begin
147+
ut.run('hr.test_apply_bonus', a_force_manual_rollback => true);
148+
end;
149+
```
150+
151+
152+
This option is not anvailable when running tests using `ut.run` as a table function.
153+
134154
## ut.run functions
135155

136156
The `ut.run` functions provide exactly the same functionality as the `ut.run` procedures.
@@ -140,7 +160,7 @@ Functions provide output as a pipelined stream and therefore need to be executed
140160

141161
Example.
142162
```sql
143-
select * from table(ut.run('hr.test_apply_bonus', ut_xunit_reporter()));
163+
select * from table(ut.run('hr.test_apply_bonus', ut_junit_reporter()));
144164
```
145165

146166
# ut_runner.run procedures
@@ -158,3 +178,17 @@ The concept is pretty simple.
158178
- as a separate thread, start `ut_runner.run` and pass reporters with previously defined output_ids.
159179
- 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.
160180

181+
# Reports characterset encoding
182+
183+
To get properly encoded reports, when running utPLSQL with HTML/XML reports on data containing national characters you need to provide your client character set when calling `ut.run` functions and procedures.
184+
185+
If you run your tests using `utPLSQL-cli`, this is done automatically and no action needs to be taken.
186+
187+
To make sure that the reports will display your national characters properly when running from IDE like SQLDeveloper/TOAD/SQLPlus or sqlcl you need to provide the charaterset manualy to `ut.run`.
188+
189+
Example call with characterset provided:
190+
```sql
191+
begin
192+
ut.run('hr.test_apply_bonus', ut_junit_reporter(), a_client_character_set => 'Windows-1251');
193+
end;
194+
```

0 commit comments

Comments
 (0)