Chapter 5
How to test and debug
a JavaScript application
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 1
Objectives
Applied
1. Develop test plans for the applications that you develop.
2. Use top-down coding and testing to simplify debugging.
3. Use Chrome’s developer tools to debug applications by setting
breakpoints, viewing the values of data items, and stepping through
the execution of statements.
4. Trace the execution of an application with console.log statements.
5. View the source code for a web page.
6. Validate the HTML for a web page.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 2
Objectives (cont.)
Knowledge
1. Distinguish between the goals of testing and debugging.
2. Distinguish between syntax, runtime, and logic errors.
3. In general terms, describe the way you create a test plan.
4. Describe the type of debugging problem that can occur when you use
floating-point numbers in arithmetic expressions, and describe one
way to fix this problem.
5. Describe the type of debugging problem that can occur if you don’t
use script mode so JavaScript treats undeclared variables as global
variables.
6. Explain how top-down coding and testing can simplify debugging.
7. Describe the procedure for tracing the execution of an application
with console.log statements.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 3
Testing vs. debugging
The goal of testing
To find all errors before the application is put into production.
The goal of debugging
To fix all errors before the application is put into production.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 4
The three types of errors that can occur
Syntax errors
Runtime errors
Logic errors
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 5
The Future Value application with a logic error
This calculation shows an incorrect result, which can be
hard to identify.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 6
Common syntax errors
Misspelling keywords, like coding getElementByID instead of
getElementById.
Omitting required parentheses, quotation marks, or braces.
Not using the same opening and closing quotation mark.
Omitting the semicolon at the end of a statement.
Misspelling or incorrectly capitalizing an identifier, like defining a
variable named salesTax and referring to it later as salestax.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 7
Problems with HTML references
Referring to an attribute value or other HTML component
incorrectly, like referring to an id as salesTax when the id is
“sales_tax”.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 8
Problems with data and comparisons
Not testing to make sure that a user entry is the right data type
before processing it.
Not using the parseInt() or parseFloat() method to convert a user
entry into a numeric value before processing it.
Using one equals sign instead of two when testing for equality.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 9
Problems with floating-point arithmetic
Floating-point numbers can lead to arithmetic results that are
imprecise.
var salesAmount = 74.95;
salesTax = salesAmount * .1;
// result is 7.495000000000001
One way to fix this potential problem is to round the result and
then convert it back to a floating-point number:
salesTax = salesTax.toFixed(2)
// result is 7.50 as a string
salesTax = parseFloat(salesTax.toFixed(2));
// result is 7.50 as a number
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 10
Problems with undeclared variables
that are treated as global variables
If you don’t use strict mode and you assign a value to a variable
that hasn’t been declared, the JavaScript engine treats it as a
global variable, as in this example:
var calculateTax = function(subtotal, taxRate) {
var salesTax = subtotal * taxRate;
// salesTax is local
salestax = parseFloat(salesTax.toFixed(2));
// salestax is global
return salesTax;
// salesTax isn't rounded but salestax is
};
The solution to this type of problem is to always use strict mode.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 11
The Future Value application with valid data
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 12
The Future Value application with invalid data
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 13
The two critical test phases
1. Test the application with valid input data to make sure the results
are correct.
2. Test the application with invalid data or unexpected user actions.
Try everything you can think of to make the application fail.
How to make a test plan for the critical phases
1. List the valid entries that you’re going to make and the correct
results for each set of entries. Then, make sure that the results are
correct when you test with these entries.
2. List the invalid entries that you’re going to make. These should
include entries that test the limits of the allowable values.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 14
Two common testing problems
Not testing a wide enough range of entries.
Not knowing what the results of each set of entries should be and
assuming that the results are correct because they look correct.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 15
The user interface for a Future Value application
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 16
Top-down coding and testing
Phase 1: No data validation
var $ = function(id) {
return document.getElementById(id);
};
var calculateFV = function(investment,rate,years) {
// calculate and return future value
};
var calculateClick = function() {
var investment = parseFloat( $("investment").value );
var rate = parseFloat( $("rate").value );
var years = parseInt( $("years").value );
$("future_value").value =
calculateFV(investment,rate,years);
};
window.onload = function() {
$("calculate").onclick = calculateClick;
};
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 17
Top-down coding and testing (cont.)
Phase 2: Add data validation for just the first entry
var error = "";
if (isNaN(investment) || investment <= 0 || investment > 100000)
{
error = "Investment must be a number greater than zero"
+ " and less than or equal to 100,000";
}
else {
$("future_value").value = calculateFV(investment,rate,years);
}
Phase 3: Add data validation for the other entries
// Add data validation for the other entries
Phase 4: Add the finishing touches
// Add finishing touches like moving the focus to the
// first text box or the text box that contains an error
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 18
Terms
test
debug
bug
throw an exception
throw an error
top-down coding and testing
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 19
Chrome with an open Console panel
that shows an error
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 20
Three ways to open Chrome’s developer tools
Press F12
Press Ctrl+Shift+I
Click on the Menu button in the upper right corner of the browser
and select More ToolsDeveloper Tools
Two ways to close Chrome’s developer tools
Click on the X in the upper right corner of the tools panel
Press F12
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 21
The Sources panel after the link
in the Console panel has been clicked
How to find the statement that caused the error
Open the Console panel by clicking on the Console tab. You
should see an error message along with the line of code that
caused the error.
Click on the link to the right of the error message that indicates
the line of code. That will open the Sources panel with the portion
of JavaScript code that contains the statement displayed and the
statement highlighted.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 22
A breakpoint in the Sources panel
How to set or remove a breakpoint
Click on the Sources tab to display the Sources panel. Then, click
on the JavaScript file that you want to debug.
In the center pane, click on a line number in the bar to the left of a
statement. This will add a breakpoint or remove an existing one.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 23
The buttons and keys for stepping through
the JavaScript code
Button Key Description
Step Into F11 Step through the code one line at a time.
Step Over F10 Run any called functions without
stepping through them.
Step Out SHIFT+F11 Execute the rest of a function without
stepping through it.
Resume F8 Resume normal execution.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 24
How to view the current data values at each step
Hover the mouse pointer over a variable name in the center.
View the current variables in the ScopeLocal section of the
right-hand pane.
Click the ► symbol in the Watch section of the right-hand pane,
click the plus sign that appears, and type the variable name or
expression that you want to watch.
The values are also displayed to the right of the variable
declarations in the center pane.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 25
Terms
developer tools
F12 tools
breakpoint
step through code
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 26
JavaScript with two log statements
that trace the execution of the code
var calculateFV = function(investment,rate,years) {
console.log("calculateFV function has started");
var futureValue = investment;
for (var i = 1; i < years; i++ ) {
futureValue += futureValue * rate / 100;
console.log("i = " + i + " future value = " +
futureValue);
}
futureValue = futureValue.toFixed(2);
return futureValue;
};
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 27
The log messages in the Console panel
of Chrome’s developer tools
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 28
Some of the HTML in a browser
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 29
How to view the source code for a web page
in any browser
If it’s available, use a menu command like ViewSource or
ViewPage Source.
You can also right-click on the page and select a command like
Source, View Source, or View Page Source.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 30
Some of the JavaScript code in a browser
How to view the JavaScript code in an external file
In Chrome or Firefox, click on the script element that refers to it.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 31
The home page for the W3C validator
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 32
The validation results with one error
How to use the W3C Markup Validation Service
Go to the URL that follows:
http://validator.w3.org/
Identify the file to be validated.
Click the Check button.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 33
How to validate an HTML file from Aptana
Select the file.
Select the CommandsHTMLValidate Syntax (W3C)
command.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 34
Short 5-1 Debug the Email List application
Estimated time: 5 to 15 minutes.
Use Chrome’s develop tools to debug this application,
and then fix the error.
© 2017, Mike Murach & Associates, Inc.
Murach's JavaScript and jQuery (3rd Ed.) C5, Slide 35