...
...
...
...
...
...
...
Note |
---|
This page described a way to do TDD in the Classic pico-engine. It needs to be updated to work with pico-engine 1.X. |
General Setup
The general setup for doing TDD with KRL on SquareTag is as follows:
Create an account for doing the testing.
Ensure it's CloudType is set to developer (See the (Classic) Quickstart for SquareTag for more information)
Install the Kynetx Developer Kit (KDK) and Test Module from the AppStore.
Install any other modules and rulesets necessary for the testing. These generally include the ruleset being tested and the ruleset that contains the tests. (note: more than one ruleset and testing ruleset can be installed in an account.)
Use the KDK to get an ECI for configuring the tests (see Test Harness below)
Tools
There are several tools that make TDD easier with KRL.
Test Module
The test module provides functions, actions, and rules for doing TDD in KRL. The code for the module is located on Github and is registered as ruleset b503129x0
on the Kynetx-hosted instance of KRE.
The module provides the following actions
diag()
- returns a directive withstatus
set to "diagnostic".
The module provides the following rules:
see_success
- selects ontest:succeeds
and returns a directive withstatus
set to "success" along with other information about the result.see_failure
- selects ontest:fails
and returns a directive withstatus
set to "failure" along with other information about the result.
Test Harness
The test harness is a perl program that raises appropriate events to a test account interprets directives from the test module. The code for the test harness is located on Github.
The test harness uses a test configuration file to know what tests to run. The
test config file looks like this:
Code Block | ||||
---|---|---|---|---|
| ||||
# cloudos_test@kynetx.com/for_testing eci: 07E6569E-6CE9-11E3-81D7-05AFD88E7806A rules_engine: kibdev.kobj.net rids: - b16x44 test_1: desc: "AWS Module Test" domain: test type: store_item attributes: foo: bar rids: - b22342x1.prod |
The eci
is a channel to a pico where the test rulesets, the rulesets to be tested, and the test module ruleset have been installed. If no ECI is given, then the event is raised with the Blue event API, otherwise the Sky event API is used.
The rules engine will default to kibdev
if not specified.
...
The rids
array specifes a RID list for all the tests. Rid specifications in each test can override the general delcaration.
Each test is in a structure with a name that starts with test_
. And structure with a name with that prefix will be run. In this case, there’s just one that raises the event test:store_item. You can add attributes. If a rids
array is present the event will be raised for those rids rather than generally to all installed rulesets.
Writing Tests
Tests look like rulesets. In general, rules in the ruleset can be used to set up the test and check whether or not it succeeded. Here are a few hints for writing rules that act as tests:
Include the Test Module - The test ruleset should use the test module in its meta block. I give it the alias show_test
so that actions I use from it are easy to find.
Code Block | ||||
---|---|---|---|---|
| ||||
use module b503129x0 alias show_test |
...
The following two rules test the request token response in the Dropbox module. The first rule, get_request_token_test
is selected on test:get_request_token
. The first rule doesn't perform a test, but rather sets it up. The action dropbox:get_request_token
autoraises an http:post
event when the action is performed.
Code Block | ||||
---|---|---|---|---|
| ||||
rule get_request_token_test { select when test get_request_token pre { values = {'tokens' : my_tokens, 'header' : dropbox:return_header(my_tokens) }; } if(not authorized) then { dropbox:get_request_token(); show_test:diag("test initiation", values); } } |
The second rule, process_request_token
, responds to the http:post
event, processes the HTTP response by decoding the content to retrieve the tokens, and tests the tokens to ensure they aren't empty.
Code Block | ||||
---|---|---|---|---|
| ||||
rule process_request_token { select when http post label "request_token" pre { test_desc = << Checks to make sure we got request tokens back from Dropbox >>; tokens = event:attr("status_code") eq '200' => dropbox:decode_content(event:attr('content')) | {}; url = dropbox:generate_authorization_url(tokens{'oauth_token'} || 'NO_TOKEN'); values = {'request_tokens' : tokens, 'authorization_url' : url, 'http_response' : event:attrs() }; } if(not tokens{'oauth_token'}.isnull() && not tokens{'oauth_token'}.isnull()) then { show_test:diag("processing request token", values); } fired { raise test event succeeds with test_desc = test_desc and rulename = meta:ruleName() and msg = "request tokens are defined" and details = values; set ent:request_token_secret tokens{'oauth_token_secret'}; set ent:request_token tokens{'oauth_token'}; } else { raise test event fails with test_desc = test_desc and rulename = meta:ruleName() and msg = "request tokens are empty" and details = values; } } |
...
The test configuration file to run this test looks like this:
Code Block | ||||
---|---|---|---|---|
| ||||
# global eci: <eci_for_test_account> rules_engine: kibdev.kobj.net # tests test_1: desc: "Dropbox module test" domain: test type: get_request_token rids: - b16x6.prod # RID for the test ruleset |
If the Test module, Dropbox module, and Dropbox Test ruleset are installed in the pico pointed to by the ECI in the test configuration file, then running the test harness produces the following output:
Code Block | ||||
---|---|---|---|---|
| ||||
[pjw Dropbox-module]$ ../../test_harness/krl-test.pl -c test_config.yml Dropbox module test: 1 succeeded, 0 failed, 2 diagnostic messages |
The test harness also supports the verbose (v) switch that prints our the success and failure messages:
Code Block | ||||
---|---|---|---|---|
| ||||
[pjw Dropbox-module]$ ../../test_harness/krl-test.pl -c test_config.yml -v success: b503129x0:process_request_token: Checks to make sure we got request tokens back from Dropbox Dropbox module test: 1 succeeded, 0 failed, 2 diagnostic messages |
With the detail (d) switch added to the verbose (v) switch, the detailed logging information is also printed out:
Code Block | ||||
---|---|---|---|---|
| ||||
[pjw Dropbox-module]$ ../../test_harness/krl-test.pl -c test_config.yml -vd diagnostic: test initiation { "tokens" : { "access_token_secret" : "", "access_token" : "" }, "header" : "OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\", oauth_consumer_key=\"<redacted>\", oauth_signature=\"<redacted>\"" } diagnostic: processing request token { "http_response" : { "content_length" : null, "content_type" : "application/x-www-form-urlencoded", "_generatedby" : "b16x6.prod", "status_code" : "200", "content" : "oauth_token_secret=<redacted>&oauth_token=<redacted>", "label" : "request_token", "status_line" : "200 OK" }, "authorization_url" : "https://www.dropbox.com/1/oauth/authorize?oauth_token=<redacted>&oauth_callback=http://kibdev.kobj.net/blue/event/oauth/response/b16x6/920843", "request_tokens" : { "oauth_token" : "<redacted>", "oauth_token_secret" : "<redacted>" } } success: b503129x0:process_request_token: Checks to make sure we got request tokens back from Dropbox { "http_response" : { "content_length" : null, "content_type" : "application/x-www-form-urlencoded", "status_code" : "200", "_generatedby" : "b16x6.prod", "content" : "oauth_token_secret=<redacted>&oauth_token=<redacted>", "label" : "request_token", "status_line" : "200 OK" }, "authorization_url" : "https://www.dropbox.com/1/oauth/authorize?oauth_token=37cpizF52lMC0rvu&oauth_callback=http://kibdev.kobj.net/blue/event/oauth/response/b16x6/920843", "request_tokens" : { "oauth_token" : "<redacted>", "oauth_token_secret" : "<redacted>" } } Dropbox module test: 1 succeeded, 0 failed, 2 diagnostic messages |
...