Advanced
Debugging and testing
TROIKA.ASP Framework is easy to test and debug. To enable debugging set this following line in global.asa:
Application.Contents("debug") = 1;
Also, make sure that IIS web server custom 500-100 error handler is set to URL:
/500-100.asp
Every time you have an unhandled error thrown by any of the classes you will see the error information. For example in out SecretAction class we want to throw an error:
throw new Error("Testing Error");
The browser will show:
DEBUG=ON, see Application.Contents("debug") in global.asa
ASP Code=
Number=-2146823266
Source=
Category=Microsoft JScript runtime
File=../WEB-INF/classes/commands/SecretAction.js
Line=55
Column=-1
Description=Testing Error
ASPDescription=
When debugging is enabled each rendered html page has a commented out XML which has been transformed into the HTML. Just right click and view source you might see something like this:
<HashMap>
<values>
<requestCtx>
<action>secretAction</action>
</requestCtx>
<responseCtx>
<errors>
<elements></elements>
</errors>
<models>
<values>
<loginVO>
<loginId>1</loginId>
<memberId>4</memberId>
<username>johns</username>
<password>password</password>
<securityRole>admin</securityRole>
<secretInfo>
hello there - secretInfo
</secretInfo>
</loginVO>
<memberVO>
<memberId>4</memberId>
<firstName>John</firstName>
<lastName>Smith</lastName>
<age>33</age>
</memberVO>
<sessionId>210221947</sessionId>
<securityRole>
<elements>
<e0>admin</e0>
</elements>
</securityRole>
</values>
</models>
<forward>
<path>/views/secret.xsl</path>
</forward>
</responseCtx>
</values>
</HashMap>
This is handy when debugging or testing. It shows all data available to XSL templates. Also, the XML could be used to develop XSL templates off-line.
Another great feature of TROIKA.ASP framework is ability to unit test all classes including Commands off-line. You will need Microsoft Windows Script Host Version 5.6 in order to run test scripts from command line.
Have a look at some of the test script for testing LoginAction and SecretAction Commands: c:/troika-asp/build/tests.wsf
There are four jobs:
- dao – testing MemberDAO class
- secret – testing SecretAction command
- login – testing LoginAction command
- helloworld – testing HelloAction command
As you can see in tests.wsf there is a list of all classes in bootstrapped at the beginning of each test.
<script language="javascript" runat="server" src="../WEB-INF/classes/base/Object.js"></script>
…
<script language="javascript" runat="server" src="../WEB-INF/classes/framework/MockEnvironment.js"></script>
…
<script language="javascript" runat="server" src="../WEB-INF/classes/framework/FrontController.js"></script>
<script language="javascript" runat="server" src="./util.js"></script>
This is done so that we can refer to any class in the application otherwise an error will occur. To obtain this list simply run the following in c:/troika-asp/build directory
>build jslint **/*.js
This will search for all JavaScript files in c:/troika-asp/WEB-INF/classes and it’s subdirectories performing code formatting and syntax checking.
If there is an error in code syntax the build will fail. For example, if I make a syntax error in SecretAction.js – omitting a round bracket I will get the following error in build output:
Processing: c: \troika-asp\WEB-INF\classes\commands\SecretAction.js
id: (error)
reason: Expected ')' and instead saw ';'.
character: 41
evidence: result.models.put("loginVO", loginVO;
line: 52
id: (error)
reason: Missing ';'
character: 42
evidence: result.models.put("loginVO", loginVO;
line: 52
The syntax checking and JavaScript formatting is implemented in jslint.js file and it is based on “The JavaScript Verifier” www.jslint.com work. See build_out/jslint_report.html for detailed report on the syntax of your JavaScript classes.
To stop jslint target from checking your code just use the following special comment on the line:
Response.Cookies(name) = value;///jslint:ignore
Every time you run the build with jslint target build_out/troika.asp file will be generated and copied to c:/troika-asp/WWW/troika.asp. The file troika.asp lists all application classes in the right order. For example MemberDAO depends on MemberVO; MemberVO will be loaded before MemberDAO by troika.asp and so on.
Note that when you copy and paste the list of the classes into tests.wsf you need to replace Environment.js with MockEnvironment.js. The class MockEnvironment provides mock implementations for all native ASP intrinsic objects – request, response, session, and server.
The JavaScript util.js contains utility functions:
- setup – sets up the framework and loads config.xml
- setRequest – adds name/value to the mock request object
- setSession – adds name/value to the mock session object
- showOutput – shows either redirected URI with contents of the mock session object or HTML output
Running login test script you will get this following output:
c:\troika-asp\build>cscript //nologo tests.wsf //job:login
Redirect: /troika.asp?cmd=secretAction
Session: {"security.role":"admin","loginId":1,"memberId":4}
If you comment out a line of code in job=”login” in test.wsf:
//setRequest("userName", "johns");
You will get this HTML output with the error message (‘Username’ required):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Login Form</title>
</head>
<body>
<h1>
Login Form
</h1>
<font color="red">
<h2>Error(s):</h2>
<ul>
<li>'Username' required</li>
</ul>
</font>
<form action="troika.asp" method="post"><input type="hidden" name="cmd" value="login">
Username:
<br><input name="userName"><br>
Password:
<br><input name="password"><br><br><input type="submit" name="submit" value="submit"></form>
</body>
</html>
<!--<HashMap>
<values>
<requestCtx>
<action>login</action>
<password>password</password>
</requestCtx>
<responseCtx>
<errors>
<elements>
<e0>
<name>Error</name>
<description>'Username' required</description>
<message>'Username' required</message>
</e0>
</elements>
</errors>
<models>
<values>
<sessionId>12345678</sessionId>
<securityRole>guest</securityRole>
</values>
</models>
<forward>
<path>/views/login.xsl</path>
</forward>
</responseCtx>
</values>
</HashMap>
-->
As you can see unit testing each Command object is very easy. It requires no web server - just command line script interpreter. Please feel free to play with the existing tests and add your own.