Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 46e0a8e

Browse filesBrowse files
authored
Merge pull request #1250 from utPLSQL/feature/1042_add_and_to_tags
Feature/1042 add and to tags
2 parents 69092f2 + 46ffe73 commit 46e0a8e
Copy full SHA for 46e0a8e

25 files changed

+1250
-187
lines changed

‎docs/userguide/annotations.md

Copy file name to clipboardExpand all lines: docs/userguide/annotations.md
+10-78
Original file line numberDiff line numberDiff line change
@@ -1616,93 +1616,25 @@ or
16161616

16171617
Tags are defined as a comma separated list within the `--%tags` annotation.
16181618

1619-
When executing a test run with tag filter applied, the framework will find all tests associated with the given tags and execute them.
1620-
The framework applies `OR` logic to all specified tags so any test / suite that matches at least one tag will be included in the test run.
1621-
1622-
When a suite/context is tagged, all of its children will automatically inherit the tag and get executed along with the parent. Parent suite tests are not executed, but a suitepath hierarchy is kept.
1623-
1624-
1625-
Sample test suite package with tags.
1626-
```sql linenums="1"
1627-
create or replace package ut_sample_test is
1628-
1629-
--%suite(Sample Test Suite)
1630-
--%tags(api)
1631-
1632-
--%test(Compare Ref Cursors)
1633-
--%tags(complex,fast)
1634-
procedure ut_refcursors1;
1635-
1636-
--%test(Run equality test)
1637-
--%tags(simple,fast)
1638-
procedure ut_test;
1639-
1640-
end ut_sample_test;
1641-
/
1642-
1643-
create or replace package body ut_sample_test is
1644-
1645-
procedure ut_refcursors1 is
1646-
v_actual sys_refcursor;
1647-
v_expected sys_refcursor;
1648-
begin
1649-
open v_expected for select 1 as test from dual;
1650-
open v_actual for select 2 as test from dual;
1651-
1652-
ut.expect(v_actual).to_equal(v_expected);
1653-
end;
1654-
1655-
procedure ut_test is
1656-
begin
1657-
ut.expect(1).to_equal(0);
1658-
end;
1659-
1660-
end ut_sample_test;
1661-
/
1662-
```
1663-
1664-
Execution of the test is done by using the parameter `a_tags`
1665-
1666-
```sql linenums="1"
1667-
select * from table(ut.run(a_path => 'ut_sample_test',a_tags => 'api'));
1668-
```
1669-
The above call will execute all tests from `ut_sample_test` package as the whole suite is tagged with `api`
1670-
1671-
```sql linenums="1"
1672-
select * from table(ut.run(a_tags => 'complex'));
1673-
```
1674-
The above call will execute only the `ut_sample_test.ut_refcursors1` test, as only the test `ut_refcursors1` is tagged with `complex`
1675-
1676-
```sql linenums="1"
1677-
select * from table(ut.run(a_tags => 'fast'));
1678-
```
1679-
The above call will execute both `ut_sample_test.ut_refcursors1` and `ut_sample_test.ut_test` tests, as both tests are tagged with `fast`
1619+
When a suite/context is tagged, all of its children will automatically inherit the tag and get executed along with the parent, unless they are excluded explicitly at runtime with a negated tag expression.
1620+
See [running unit tests](running-unit-tests.md) for more information on using tags to filter test suites that are to be executed.
16801621

16811622
#### Tag naming convention
16821623

16831624
Tags must follow the below naming convention:
16841625

16851626
- tag is case sensitive
1686-
- tag can contain special characters like `$#/\?-!` etc.
1687-
- tag cannot be an empty string
1627+
- tag must not contain any of the following reserved characters:
1628+
- comma (,)
1629+
- left or right parenthesis ((, ))
1630+
- ampersand (&)
1631+
- vertical bar (|)
1632+
- exclamation point (!)
1633+
- tag cannot be null or blank
16881634
- tag cannot start with a dash, e.g. `-some-stuff` is **not** a valid tag
16891635
- tag cannot contain spaces, e.g. `test of batch`. To create a multi-word tag use underscores or dashes, e.g. `test_of_batch`, `test-of-batch`
16901636
- leading and trailing spaces are ignored in tag name, e.g. `--%tags( tag1 , tag2 )` becomes `tag1` and `tag2` tag names
1691-
1692-
1693-
#### Excluding tests/suites by tags
1694-
1695-
It is possible to exclude parts of test suites with tags.
1696-
In order to do so, prefix the tag name to exclude with a `-` (dash) sign when invoking the test run.
1697-
1698-
Examples (based on above sample test suite)
1699-
1700-
```sql linenums="1"
1701-
select * from table(ut.run(a_tags => 'api,fast,-complex'));
1702-
```
1703-
The above call will execute all suites/contexts/tests that are marked with any of tags `api` or `fast` except those suites/contexts/tests that are marked as `complex`.
1704-
Given the above example package `ut_sample_test`, only `ut_sample_test.ut_test` will be executed.
1705-
1637+
- tag cannot be one of two reserved words: `none` and `any`. `none` and `any` as a tag will be treated as no tag
17061638

17071639

17081640
### Suitepath

‎docs/userguide/running-unit-tests.md

Copy file name to clipboardExpand all lines: docs/userguide/running-unit-tests.md
+203-7
Original file line numberDiff line numberDiff line change
@@ -319,22 +319,218 @@ select * from table(ut.run('hr.test_apply_bonus', a_random_test_order_seed => 30
319319

320320
In addition to the path, you can filter the tests to be run by specifying tags. Tags are defined in the test / context / suite with the `--%tags`-annotation ([Read more](annotations.md#tags)).
321321
Multiple tags are separated by comma.
322-
The framework applies `OR` logic to all specified tags so any test / suite that matches at least one tag will be included in the test run.
322+
323+
324+
### Tag Expressions
325+
326+
Tag expressions are boolean expressions created by combining tags with the `!`, `&`, `|` operators. Tag expressions can be grouped using `(` and `)` braces. Grouping tag expressions affects operator precedence.
327+
328+
Two reserved keywords, `any` and `none`, can be used when creating a tag expression to run tests.
329+
- `any` keyword represents tests and suites with any tags
330+
- `none` keyword represents tests and suites without tags
331+
332+
These keywords may be combined with other expressions just like normal tags.
333+
334+
!!! note
335+
When specifying `none`, be aware that it will exclude any tests/suites/contexts contained within a tagged suite.
336+
337+
| Operator | Meaning |
338+
| -------- | --------|
339+
| ! | not |
340+
| & | and |
341+
| \| | or |
342+
343+
If you are tagging your tests across multiple dimensions, tag expressions help you to select which tests to execute. When tagging by test type (e.g., micro, integration, end-to-end) and feature (e.g., product, catalog, shipping), the following tag expressions can be useful.
344+
345+
346+
| Tag Expression | Selection |
347+
| -------- | --------|
348+
| product | all tests for product |
349+
| catalog \| shipping | all tests for catalog plus all tests for shipping |
350+
| catalog & shipping | all tests that are tagged with both `catalog` and `shipping` tags |
351+
| product & !end-to-end | all tests tagged `product`, except the tests tagged `end-to-end` |
352+
| (micro \| integration) & (product \| shipping) | all micro or integration tests for product or shipping |
353+
354+
355+
Taking the last expression above `(micro | integration) & (product | shipping)`
356+
357+
| --%tags |included in run |
358+
| -------- | --------|
359+
| micro | no |
360+
| integration | no |
361+
| micro | no |
362+
| product | no |
363+
| shipping | no |
364+
| micro | no |
365+
| micro, integration | no |
366+
| product, shipping | no |
367+
| micro, product | yes |
368+
| micro, shipping | yes |
369+
| integration, product | yes |
370+
| integration, shipping | yes |
371+
| integration, micro, shipping | yes |
372+
| integration, micro, product | yes |
373+
| integration, shipping ,product | yes |
374+
| micro, shipping ,product | yes |
375+
| integration, micro, shipping ,product | yes |
376+
377+
378+
### Sample execution of test with tags.
379+
380+
Execution of the test with tag expressions is done using the parameter `a_tags`.
381+
Given a test package `ut_sample_test` defined below
323382

324383
```sql linenums="1"
325-
begin
326-
ut.run('hr.test_apply_bonus', a_tags => 'test1,test2');
327-
end;
384+
create or replace package ut_sample_test is
385+
386+
--%suite(Sample Test Suite)
387+
--%tags(api)
388+
389+
--%test(Compare Ref Cursors)
390+
--%tags(complex,fast)
391+
procedure ut_refcursors1;
392+
393+
--%test(Run equality test)
394+
--%tags(simple,fast)
395+
procedure ut_test;
396+
397+
end ut_sample_test;
398+
/
399+
400+
create or replace package body ut_sample_test is
401+
402+
procedure ut_refcursors1 is
403+
v_actual sys_refcursor;
404+
v_expected sys_refcursor;
405+
begin
406+
open v_expected for select 1 as test from dual;
407+
open v_actual for select 2 as test from dual;
408+
409+
ut.expect(v_actual).to_equal(v_expected);
410+
end;
411+
412+
procedure ut_test is
413+
begin
414+
ut.expect(1).to_equal(0);
415+
end;
416+
417+
end ut_sample_test;
418+
/
328419
```
420+
329421
```sql linenums="1"
330-
select * from table(ut.run('hr.test_apply_bonus', a_tags => 'suite1'))
422+
select * from table(ut.run(a_path => 'ut_sample_test',a_tags => 'api'));
331423
```
424+
The above call will execute all tests from `ut_sample_test` package as the whole suite is tagged with `api`
332425

333-
You can also exclude specific tags by adding a `-` (dash) in front of the tag
426+
```sql linenums="1"
427+
select * from table(ut.run(a_tags => 'fast&complex'));
428+
```
429+
The above call will execute only the `ut_sample_test.ut_refcursors1` test, as only the test `ut_refcursors1` is tagged with `complex` and `fast`
334430

335431
```sql linenums="1"
336-
select * from table(ut.run('hr.test_apply_bonus', a_tags => '-suite1'))
432+
select * from table(ut.run(a_tags => 'fast'));
337433
```
434+
The above call will execute both `ut_sample_test.ut_refcursors1` and `ut_sample_test.ut_test` tests, as both tests are tagged with `fast`
435+
436+
### Excluding tests/suites by tags
437+
438+
It is possible to exclude parts of test suites with tags.
439+
In order to do so, prefix the tag name to exclude with a `!` (exclamation) sign when invoking the test run which is equivalent of `-` (dash) in legacy notation.
440+
Examples (based on above sample test suite)
441+
442+
```sql linenums="1"
443+
select * from table(ut.run(a_tags => '(api|fast)&!complex'));
444+
```
445+
446+
or
447+
448+
```sql linenums="1"
449+
select * from table(ut.run(a_tags => '(api|fast)&!complex&!test1'));
450+
```
451+
452+
which is equivalent of exclusion on whole expression
453+
454+
```sql linenums="1"
455+
select * from table(ut.run(a_tags => '(api|fast)&!(complex|test1)'));
456+
```
457+
458+
The above calls will execute all suites/contexts/tests that are marked with any of tags `api` or `fast` except those suites/contexts/tests that are marked as `complex` and except those suites/contexts/tests that are marked as `test1`.
459+
Given the above example package `ut_sample_test`, only `ut_sample_test.ut_test` will be executed.
460+
461+
462+
### Sample execution with `any` and `none`
463+
464+
Given a sample test package:
465+
466+
```sql linenums="1"
467+
create or replace package ut_sample_test is
468+
469+
--%suite(Sample Test Suite)
470+
471+
--%test(Compare Ref Cursors)
472+
--%tags(complex,fast)
473+
procedure ut_refcursors1;
474+
475+
--%test(Run equality test)
476+
--%tags(simple,fast)
477+
procedure ut_test;
478+
479+
--%test(Run equality test no tag)
480+
procedure ut_test_no_tag;
481+
482+
end ut_sample_test;
483+
/
484+
485+
create or replace package body ut_sample_test is
486+
487+
procedure ut_refcursors1 is
488+
v_actual sys_refcursor;
489+
v_expected sys_refcursor;
490+
begin
491+
open v_expected for select 1 as test from dual;
492+
open v_actual for select 2 as test from dual;
493+
494+
ut.expect(v_actual).to_equal(v_expected);
495+
end;
496+
497+
procedure ut_test is
498+
begin
499+
ut.expect(1).to_equal(0);
500+
end;
501+
502+
procedure ut_test_no_tag is
503+
begin
504+
ut.expect(1).to_equal(0);
505+
end;
506+
507+
end ut_sample_test;
508+
/
509+
```
510+
511+
```sql linenums="1"
512+
select * from table(ut.run(a_path => 'ut_sample_test',a_tags => 'none'));
513+
```
514+
515+
The above call will execute tests `ut_test_no_tag`
516+
517+
```sql linenums="1"
518+
select * from table(ut.run(a_path => 'ut_sample_test',a_tags => 'any'));
519+
```
520+
521+
The above call will execute tests `ut_test` and `ut_refcursors1`
522+
523+
```sql linenums="1"
524+
select * from table(ut.run(a_path => 'ut_sample_test',a_tags => 'none|simple'));
525+
```
526+
527+
The above call will execute tests `ut_test_no_tag` and `ut_test`
528+
529+
```sql linenums="1"
530+
select * from table(ut.run(a_tags => 'none|!simple'));
531+
```
532+
533+
The above call will execute tests `ut_test_no_tag` and `ut_refcursors1`
338534

339535
## Keeping uncommitted data after test-run
340536

‎source/api/ut_runner.pkb

Copy file name to clipboardExpand all lines: source/api/ut_runner.pkb
+3-10
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ create or replace package body ut_runner is
7878
l_run ut_run;
7979
l_coverage_schema_names ut_varchar2_rows;
8080
l_paths ut_varchar2_list;
81-
l_random_test_order_seed positive;
82-
l_tags ut_varchar2_rows := ut_varchar2_rows();
81+
l_random_test_order_seed positive;
8382
begin
8483
ut_event_manager.initialize();
8584
if a_reporters is not empty then
@@ -118,12 +117,6 @@ create or replace package body ut_runner is
118117
l_coverage_schema_names := ut_suite_manager.get_schema_names(l_paths);
119118
end if;
120119

121-
122-
if a_tags is not null then
123-
l_tags := l_tags multiset union distinct ut_utils.convert_collection(
124-
ut_utils.trim_list_elements(ut_utils.filter_list(ut_utils.string_to_table(a_tags,','),ut_utils.gc_word_no_space))
125-
);
126-
end if;
127120
l_run := ut_run(
128121
a_run_paths => l_paths,
129122
a_coverage_options => ut_coverage_options(
@@ -140,10 +133,10 @@ create or replace package body ut_runner is
140133
a_test_file_mappings => set(a_test_file_mappings),
141134
a_client_character_set => a_client_character_set,
142135
a_random_test_order_seed => l_random_test_order_seed,
143-
a_run_tags => l_tags
136+
a_run_tags => a_tags
144137
);
145138

146-
ut_suite_manager.configure_execution_by_path(l_paths, l_run.items, l_random_test_order_seed, l_tags);
139+
ut_suite_manager.configure_execution_by_path(l_paths, l_run.items, l_random_test_order_seed, a_tags);
147140
if a_force_manual_rollback then
148141
l_run.set_rollback_type( a_rollback_type => ut_utils.gc_rollback_manual, a_force => true );
149142
end if;

‎source/core/types/ut_run.tpb

Copy file name to clipboardExpand all lines: source/core/types/ut_run.tpb
+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ create or replace type body ut_run as
2424
a_test_file_mappings ut_file_mappings := null,
2525
a_client_character_set varchar2 := null,
2626
a_random_test_order_seed positive := null,
27-
a_run_tags ut_varchar2_rows := null
27+
a_run_tags varchar2 := null
2828
) return self as result is
2929
begin
3030
self.run_paths := a_run_paths;

‎source/core/types/ut_run.tps

Copy file name to clipboardExpand all lines: source/core/types/ut_run.tps
+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ create or replace type ut_run under ut_suite_item (
2121
project_name varchar2(4000),
2222
items ut_suite_items,
2323
run_paths ut_varchar2_list,
24-
run_tags ut_varchar2_rows,
24+
run_tags varchar2(4000),
2525
coverage_options ut_coverage_options,
2626
test_file_mappings ut_file_mappings,
2727
client_character_set varchar2(100),
@@ -34,7 +34,7 @@ create or replace type ut_run under ut_suite_item (
3434
a_test_file_mappings ut_file_mappings := null,
3535
a_client_character_set varchar2 := null,
3636
a_random_test_order_seed positive := null,
37-
a_run_tags ut_varchar2_rows := null
37+
a_run_tags varchar2 := null
3838
) return self as result,
3939
overriding member procedure mark_as_skipped(self in out nocopy ut_run,a_skip_reason in varchar2),
4040
overriding member function do_execute(self in out nocopy ut_run) return boolean,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.