Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

...

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 with status set to "diagnostic". 

The module provides the following rules:

  • see_success - selects on test:succeeds and returns a directive with  status set to "success" along with other information about the result. 

  • see_failure - selects on test:fails and returns a directive with  status 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
theme
languagejavascriptjsConfluence
# 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
languagejavascriptthemeConfluencejs
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
theme
languagejavascriptjsConfluence
  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
languagejavascriptthemeConfluencejs
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
languagejavascriptjs
themeConfluence
# 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
languagejavascriptjs
themeConfluence
[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
languagejavascriptthemeConfluencejs
[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
languagejavascriptthemeConfluencejs
[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

...