TestUnit Integration

From Second Life Wiki
Revision as of 20:33, 31 March 2010 by Vektor Linden (talk | contribs) (Created page with 'This document assumes that you have already read this page: http://wiki.secondlife.com/wiki/LSL_Test_Harness, with special attention to the section called, "The Test Unit(s)". ...')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This document assumes that you have already read this page: http://wiki.secondlife.com/wiki/LSL_Test_Harness, with special attention to the

section called, "The Test Unit(s)".

First, open the Test Unit template page here: http://wiki.secondlife.com/wiki/TestUnit_TestScript.lsl

I will use the Binary Operators Test Unit in this exmaple: https://wiki.secondlife.com/wiki/TestUnit_MATH_Binary_Operators.lsl

The Test Units run tests that you create yourself, and insert into the Test Unit Template. They have 4 parts that require attention, Global Varibles,

Runtest, Report and Initialize. Before you sit down and start adding anything to a Test Unit, you need to define what you want to accomplish.

Choose an area of functionality and extract all of the data that you need to go into, and out of the test.

I will break them down the 4 major sections where you, the author, will be adding data, below:

  • Global variable declaration

This is where you place all of the variable declarations for the variables that you will use in your Test Unit script. This includes the

defaults that the script uses. It is good practice to create a pass variable for each test that you put into the Test Unit. The following is an excerpt

from the Binary Operators test script: <lsl> // Global Variables

/// These variables are used in all LSL Test Unit scripts. integer toAllChannel = -255; // (for all Test Units)general channel - linked message integer passFailChannel = -355; // test scripts channel for cummunicating pass/fail - linked message integer debug = 0; // level of debug message integer debugChannel = DEBUG_CHANNEL; // output channel for debug messages

// These variables are unique to this script. integer ArithmeticAddition_PASS; integer ArithmeticSubtraction_PASS; integer ArithmeticMultiplication_PASS; integer ArithmeticDivision_PASS; integer ArithmeticModulo_PASS; integer ArithmeticGreaterThan_PASS; integer ArithmeticLessThan_PASS; integer ArithmeticGreaterThanOrEqualTo_PASS; integer ArithmeticLessThanOrEqualTo_PASS; integer LogicalInequality_PASS; integer LogicalEquality_PASS; integer LogicalAND_PASS; integer LogicalOR_PASS; integer BitwiseAND_PASS; integer BitwiseOR_PASS; integer BitwiseLeftShift_PASS; integer BitwiseRightShift_PASS; integer BitwiseExclusiveOR_PASS; </lsl>

  • Runtest

This section is where the tests are actually run. It is broken down into three discrete parts. In most cases, the first is a series of

conditional statements against the data set that you established, where each conditional statement sets a pass bit. Here is an example, from the

Binary Operators Tetst Unit: <lsl> RunTest() { // initialize PASS variable ArithmeticAddition_PASS = 0; // Compare data against criteria in GetType function, which returns an integer corresponding to the type. if (1 + 1 == 2) { ArithmeticAddition_PASS = 1; }

// initialize PASS variable ArithmeticSubtraction_PASS = 0; // Compare data against criteria in GetType function, which returns an integer corresponding to the type. if (1 - 1 == 0) { ArithmeticSubtraction_PASS = 1; }

// initialize PASS variable ArithmeticMultiplication_PASS = 0; // Compare data against criteria in GetType function, which returns an integer corresponding to the type. if (2 * 2 == 4) { ArithmeticMultiplication_PASS = 1; }

// initialize PASS variable ArithmeticDivision_PASS = 0; // Compare data against criteria in GetType function, which returns an integer corresponding to the type. if (4 / 2 == 2) { ArithmeticDivision_PASS = 1; } </lsl> ...and so on.

The second part in the Runtest section is where you look at your PASS variables to check for any failures. If there are no failures in the

test, a global PASS variable is set for the entire Test Unit: <lsl> //check to see if any failures occured. integer pass = ArithmeticAddition_PASS & ArithmeticSubtraction_PASS & ArithmeticMultiplication_PASS & ArithmeticModulo_PASS & ArithmeticDivision_PASS & ArithmeticGreaterThan_PASS & ArithmeticLessThan_PASS & ArithmeticGreaterThanOrEqualTo_PASS & ArithmeticLessThanOrEqualTo_PASS & LogicalInequality_PASS & LogicalEquality_PASS & LogicalAND_PASS & LogicalOR_PASS & BitwiseAND_PASS & BitwiseOR_PASS & BitwiseLeftShift_PASS & BitwiseRightShift_PASS & BitwiseExclusiveOR_PASS; </lsl> The last part of the Runtest section of the Test Unit broadcases your gobal pass/fail result to the main harness, and looks like this: <lsl> // if all of the individual cases pass, test passes. if( pass ) { llMessageLinked(LINK_SET, passFailChannel, "PASS", NULL_KEY); } else { llMessageLinked(LINK_SET, passFailChannel, "FAIL", NULL_KEY); } </lsl>

  • Report

The Report mechanism takes your pass / fail data, and maps it to results output in three ways, QUIET, NORMAL, and VERBOSE. How

you set up your reporting mechanisms is up to you, but all three should be available to the Test Harness for reporting, as the Harness Coordinator

has these options built in, in the controller. For each report type, construct report strings based on what ever level you want to provide for the

data that you tested in your Test Unit. It is up to you how you will package your report data, to be sent back to the report utility in the harness.

Here is an example of what a section of the VERBOSE report string building in the Binary Operators Test Unit:

<lsl>

//VERBOSE - highest level of reporting if( reportType == "VERBOSE" ) { reportString = "///////////////////////////////////////////////////////////////////////////////////////////" + "\n"+ "// Type: ArithmeticAddition" + "\n" + "// Returns an integer representing the integer type constant" + "\n" + "// • ArithmeticAddition = 1" + "\n" + "///////////////////////////////////////////////////////////////////////////////////////////" + "\n" + "PASS/FAIL -> " + ArithmeticAddition_PASSstring + "\n\n" +

"/////////////////////////////////////////////////////////////////////////////////" + "\n" + "// Type: BitwiseExclusiveOR" + "\n" + "// Returns an integer representing the invalid data type constant" + "\n" + "// • BitwiseExclusiveOR = 0" + "\n" + "/////////////////////////////////////////////////////////////////////////////////" + "\n" + "PASS/FAIL -> " + BitwiseExclusiveOR_PASSstring + "\n\n";

} // end verbose </lsl>

This is what the section looks like that sends the report string variable to the Coordinator: <lsl> //AddUnitReport() //send to Coordinator on the broadcastChannel the selected report //format example -> AddUnitReport::unitKey::00000-0000-0000-00000::Report::Successful Completion of Test llSay( controlChannel, "AddUnitReport::unitKey::" + (string)llGetKey() + "::Report::" + reportString); </lsl>

  • Initialize

This section is used solely to place the name of your Test Unit's name in hovertext above the Test Unit in world. The following is an

example of how that looks: <lsl> Initialize() { llSetText( "MATH_BinaryOperators", <255,255,255>, 1); } </lsl>