CoginitiScript supports built-in testing capabilities that allow developers to write and execute tests for their code blocks. The testing mechanism is integrated directly into the language syntax and can be written in any language supported by CoginitiScript.
Defining a Test
Tests in CoginitiScript are defined using the #+test
directive. This makes them a specific type of code block, specifically designed for testing the logic of other blocks. A test block is structured as follows:
#+test language TestName()
#+begin
-- Your test code here
#+end
language should be replaced with the language you are writing the test in (at this time only sql is supported) and TestName()
should be replaced with a meaningful name for your test. The code inside the #+begin
and #+end
tags is the actual test code.
Test blocks can return one of three types of objects:
- Dataset
- Error
- Nil
The return value determines the test outcome:
- A test is considered successful when it returns `Nil` or an empty `Dataset`.
- If a test returns `Error` or a non-empty `Dataset`, it is considered to have failed.
Test Examples
Here is an example of a test block:
#+test sql TestCustomerData()
#+begin
SELECT * FROM {{ customerData() }} WHERE email IS NULL
#+end
In this example, the test TestCustomerData()
checks if there are any rows with NULL email values in the dataset returned by the customerData()
block. If such rows exist, the test fails and returns a non-empty Dataset.
Running Tests
Tests in CoginitiScript can be run individually or in sequence:
- To run a single test, place your cursor on the test block and execute it.
- To run all tests in sequence, execute the run all command, and it will execute each test in the order they appear in your script.
Programmatic Test Execution
CoginitiScript is implementing functionality to execute tests programmatically. This will enable running specified individual tests, or all tests within certain packages, in a straightforward and programmatic way. This functionality will be provided through a built-in package std/test and its Run(tests, packages) block.
Running Individual Tests
To execute specific tests, you can import the necessary packages and then use test.Run(tests=[...])
. In the `tests` parameter, list the tests you want to execute.
Here's an example:
#+import "customers"
#+import "std/test"
{{ test.Run(tests=[customers.Test1, customers.Test2]) }}
In the above example, Test1 and Test2 from the customers package are being executed.
Running Tests from Packages
To run all tests from a specific package, you can use test.Run(packages=[...])
. In the packages parameter, list the packages whose tests you want to run.
Here's an example:
#+import "customers"
#+import "std/test"
{{ test.Run(packages=[customers]) }}
In this case, all tests in the customers package will be executed.
Running Tests from Packages and Individual Tests
If you want to run all tests from specific packages and also specific individual tests, you can use both parameters (`tests` and `packages`) in the Run block.
Here's an example:
#+import "customers"
#+import "sales"
#+import "std/test"
{{ test.Run(tests=[customers.Test1, customers.Test2], packages=[sales]) }}
In this case, Test1 and Test2 from the customers package are being executed, as well as all tests in the sales package.
This upcoming feature will make the process of running tests more flexible and efficient, offering the ability to execute specified tests or all tests within certain packages.
Continue script execution if tests failed
When at least one test fails when running them through test.Run, then further execution of the script stops. If you want the script to continue to be executed, you can pass test.onFailure=test.Continue argument. In this case you will still get tests results (including failed tests) as well as result of other statements in your script which comes after test.Run. The other option is test.onFailure=test.Stop which instructs Coginiti application to stop script execution when there are test failures within test.Run and this is default option.
Here's an example:
#+import "customers"
#+import "sales"
#+import "std/test"
{{ test.Run(tests=[customers.Test1, customers.Test2], packages=[sales],
onFailure=test.Continue) }};
--
-- Following statements will be executed even if there are test
-- failures within test.Run
--
CREATE TABLE customers_report(
...
);
INSERT INTO customers_report AS
SELECT
...
FROM
...
;
Viewing Test Results
Test results are displayed in a separate "Test Results" tab in the output/results panel. This allows you to see the outcome of each test after they have been run.
If a test fails, you can double-click on the failed test in the "Test Results" tab. This will navigate to the source code line where the test is defined, making it easy to locate and review the test code.