Testing and Debugging Your Application

Lesson 1

Error Types

 

Syntax Errors

  • Compiler cannot process provided source code – e.g. keyword wrongly typed
  • Build project -> errors detected, underlined and added to task list
  • Double click error in task list – associated code highlighted
  • Obtain help by pressing F1
  • Minimal syntax checking provided whilst typing in code

 

Run Time

  • App performs illegal operation
    • Divide by zero
    • Security exceptions
  • Exception describing error is thrown – write code to handle it

 

Logical

  • Correct execution but unexpected results
  • e.g. calculate pay but multiply hours per week by 400, not 40

 

Break Mode

  • Halt program execution and step through line at a time
  • Enter on following conditions:
    • Choose to Step Into, Over or Out
    • Execution reaches breakpoint
    • Execution reaches stop statement
    • Unhandled exception thrown

 

Breakpoints

  • Function – stop at specified location in function
    • Click grey bar to left of code line to stop at
    • Right click on desired line and insert breakpoint
    • Insert via Debug menu
  • File – specified location in file
  • Address – when specified memory address accessed
  • Breakpoint window
    • manage all breakpoints
    • display information
    • create, delete or disable

 

Debugging Windows

  • Output – command line output, debug and trace statements
  • Locals (all vars), Autos (current and previous line vars), Watch (chosen vars) – monitor program variables
  • Command – execute procedures, evaluate expressions, change vars
    • Cannot accept data declarations
    • In Break mode
      • if enter statement / method call IDE switches to runtime, executes statement, return to break mode
      • print variable values – use ? operator

 

Lesson 2

Debug and Trace

  • Debug class – log messages during execution (of debug code)
  • Trace class – log messages during execution (both debug and release code)
  • Both classes contain static methods to test conditions and log data
  • Class output sent to listeners (and Output window)

 

Methods

  • Write – write to listeners unconditionally
  • WriteLine – write to listeners unconditionally followed by CR
  • WriteIf – write to listeners if Boolean expression true
  • WriteLineIf - write to listeners unconditionally followed by CR if Boolean expression true
  • Assert – displays message box and writes to listeners if Boolean expression false
  • Fail – displays message box and writes to listeners

 

Listeners Collection

  • Listeners collection organises and  exposes classes that can receive trace output
  • Listeners collection initialised with DefaultTraceListener class – receives messageseven if no other listeners attached
  • DefaultTraceListener directs trace to IDE output window
  • 2 base trace classes
    • EventLogTraceListener – directs output to event log
    • TextWritertraceListener – directs output to stream or TextWriter

 

// Open (or create) file

System.IO.FileStream myLog = new System.IO.FileStream(“C:\\myfile.txt”, System.IO.FileMode.OpenOrCreate);

 

// Create TraceListener logging to specified file

TextWriterTraceListener myListener = new TextWriteTraceListener(myLog);

 

// Add to listeners collection

Trace.Listeners.Add(myListener);

 

  • To write to file must flush, either by explicitly calling trace method or setting AutoFlush property to true
  • Using EventLogTraceListener similar
    • Create new EventLog
    • Create EventLogTraceListener class
    • Add to listeners collection

 

// Create event log entitled “DebugLog”

EventLog myLog = new EventLog(“Debug Log”);

 

// Set EventLog source property (avoid error)

myLog.source = “Trace Output”;

 

// Create EventLogTraceListener

EventLogTraceListener = new EventLogTraceListener(myLog);

 

Trace Switches

  • 2 types – BooleanSwitch class (on or off) and TraceSwitch class (five values)
  • Both classes require DisplayName (its name in configuration file) and Description

 

BooleanSwitch myBoolSwitch = newBooleanSwitch(“Switch1”, “Control Data Tracing”);

 

TraceSwitch myTraceSwitch = new TraceSwitch(“Switch2”, “Control Form Tracing”);

 

  • TraceSwitch = 5 settings, exposed by TraceSwitch.Level property
    • TraceLevel.Off
    • TraceLevel.Error
    • TraceLevel.Warning
    • TraceLevel.Info
    • TraceLevel.Verbose
  • TraceSwitch class exposed four Boolean properties corresponding to trace levels of same name, e.g. if TraceSwitch.Level = TraceLevel.Info then TraceSwitch.TraceInfo is true (as are TraceSwitch.TraceError and TraceSwitch.TraceWarning) while TraceSwitch.TraceVerbose is false
  • No auto hook-up between trace switches and statements, use TraceSwitch to test if output required:

 

Trace.WriteIf(myBoolSwitch.Enabled == true, “error”);

Trace.WriteIf(myTraceSwitch.TraceInfo == true, “type mismatch”);

 

Configure Trace Switches

  • Configured within XML application .config file
  • Config file located in executables folder
  • Config file called appname.exe.config
  • May need to create config file (not all apps have them)
  • When app creates trace switch it checks .config file for info on switch (identified by DisplayName)
  • To create file

o       Add new item from project menu

o       Choose text file and name appropriately

o       Type following

 

<?xml version=”1.0” encoding=”Windows-1252”?>

<configuration>

  <system.diagnostics>

       <switches>

            <add name=”myBoolSwitch” value=”0”/>

            <add name=”myTraceSwitch” value=”3”/>

       </switches>

  </system.diagnostics>

</configuration>

 

Lesson 3

Unit Test Plan

  • Run-time and logical error snot detected without thorough testing
  • Testing and debugging separate but related activities
    • Debug = finding and correcting code errors
    • Testing = process by which errors found
  • Testing usually broken down by method, exercised using variety of params – termed unit testing
  • Cannot test all permutations – use representative examples (test cases)

 

Test Case Design

  • Minimum = exercise all lines of code
  • Design cases to work through all decision branches
  • App should behave as expected when normal params provided
  • App should degrade gracefully when parms outside bounds provided
    • Boundary conditions – minimum and maximum and off by one
    • Bad data – values well outside range (0, negative, etc.)
    • Data combinations – test all method parms at boundary, bad values, etc
  • Determine expected test case results prior to actual test
  • Compare obtained results with those expected

 

Lesson 4

Exceptions

  • Structured Exception Handling means of recovering gracefully from errors
  • Exception = instance of specialist class deriving from System.Exception
    • Message property = human readable description of error
    • StackTrace property = stack trace to pinpoint error location
  • Run time error occurs
    • Exception generated and passed up call stack to caller
    • If exception handler encountered it is handled, otherwise passed up stack to next method… and so on
    • If no handler found default used – message box displayed and app stopped

 

Exception Handler

  • Implemented on method basis – i.e. individually tailored to it and exceptions likely to be thrown
    • Wrap code associated with handler in try block
    • Add 1+ catch blocks to handle exceptions
    • Add code that must always be executed in finally block

 

public void Parse(string a string)

{

  try

  {

       double aDouble;

       aDouble = Double.Parse(aString);

  }

 

  catch (System.ArgumentNullException e)

  {

       // Code to handle null argument – e

       // contains ref to exception (access to

// its info)

  }

 

  catch

  {   

       // Catch any other exception

  }

 

  finally

  {   

       // Code that must be executed

  }

}

 

  • After code in (only one) catch block executed, the finally block is run
  • Write catch blocks in order from most to least specific
  • Can omit catch block (exception handled further up call stack) but still include finally block to execute any code in method that must run before return

 

Throwing Exceptions

  • 2 situations
    • Only partially handled exception and want to bubble it up call stack
    • Unacceptable condition occurred that cannot be handled locally and must be communicated to parent – throw standard or custom exception

 

  • Rethrow exception by using throw

 

try

{

}

 

catch (System.NullReferenceException e)

{

     // Assuming exception can not be handled

// rethrow

     throw e;

}

 

  • Can pass additional information on when rethrowing, e.g. to provide informative message around original exception

 

throw new NullReferenceException(“Widget A is not set”, e);

 

  • Custom exception – only for exceptional circumstances – not for use as communication between client and components (use events). Only use when conditions mean execution can not proceed without intervention
  • Custom exceptions derive from System.ApplicationException, e.g.

 

public class WidgetException:System.ApplicationException

{

     // Var to hold widget

     Widget mWidget;

 

     public Widget ErrorWidget

     {

          get

          {

              return mWidget;   

          }

     }

 

     // Constructor takes widget and string

//describing error conditions

     public WidgetException(Widget W, string S) : base(S)

     {

          mWidget = W;

     }

}

 

Widget Alpha;

throw new WidgetException(Alpha,”Alpha is corrupt”);

 

Tuition

home
home
tuition
index
Last updated: 26th December 2006.
copyright © 2000 Greystoke Systems Ltd.
Web address: http://www.gsys.biz/Documents/Services/Tuition/MCP/70-316/ApplicationDeployment.htm