lecture 9: debugging & testing. 9-2 microsoftintroducing cs using.netj# in visual studio.net...

26
Lecture 9: Debugging & Testing

Upload: sharlene-norton

Post on 22-Dec-2015

215 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

Lecture 9:

Debugging & Testing

Page 2: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-2MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Objectives

“Unfortunately, errors are a part of life. Some are detected by the compiler, some are detected through testing, and the remainder go uncaught. Modern languages and tools like J#, Visual Studio .NET, and NUnit provide many techniques for quickly identifying, dealing with, and eliminating errors. But you have to apply them…”

• Debugging options• Testing• Testing with NUnit

Page 3: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-3MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Part 1

• Debugging options…

Page 4: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-4MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Print debugging

• Everyone understands print debugging

• In .NET, you have various options:

– console app: System.out.println(...);

– GUI app:System.Windows.Forms.MessageBox.Show(...);

– inside VS: System.Diagnostics.Debug.WriteLine(...);

Page 5: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-5MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Source-level debugging

• Most development environments supply a debugger– allow you to debug your program line-by-line, look at vars, etc.– Visual Studio .NET contains a very sophisticated debugger

• Basic idea:– you set a breakpoint to pause your program at a certain point– run program in order to reach breakpoint– once paused, you can look at variables, single-step, etc.

click in margin to set breakpoint

Page 6: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-6MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Debug menu

• Once you reachbreakpoint, you can:

– single-step– view local vars– change values

• Example:– Watch window let’s

you expand &inspect objects!

• See Debug menu forthings you can do…

Page 7: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-7MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Examples

• When using constructors, set a breakpoint where you do “new Class1(…)”, run to hit breakpoint, and then single-step, showing how constructor is automatically called…

• When using dynamic binding, single-step through calls to see how different method implementations are called dynamically…

Page 8: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-8MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Part 2

• Testing…

Page 9: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-9MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Testing

• Good testing is a skill that students must develop:– algorithm boundary cases– single calls & sequences of calls– parameter validation– exception handling– etc.

• Good testing is automated– so there’s no reason not to do it

• Good testing is repeatable (regression testing)– so you can retest after any change to the code

Page 10: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-10MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Basic testing methodology

• For every class C, create a test harness TC to test it

– TC = one or more methods that exercise C

• Test harness should:

– exercise all fields & methods in C

– strive for 100% code coverage (exercise all paths of execution)

– generate no output other than a final testing summary• i.e. test harness should *not* rely on user to determine correctness

• user will forget what the “correct” output should be…

class Ctest

harnessTC

Page 11: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-11MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Example

• StudentsIO class reads student info from a file– returns an ArrayList of Student objects…

public class StudentsIO{ /** * Reads student info from given file, returning arraylist */ public static java.util.ArrayList read(String filename) ... { java.util.ArrayList students; students = new java.util.ArrayList(); . . .

return students; }

public class StudentsIO{ /** * Reads student info from given file, returning arraylist */ public static java.util.ArrayList read(String filename) ... { java.util.ArrayList students; students = new java.util.ArrayList(); . . .

return students; }

Page 12: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-12MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Example test harness

• Tests StudentsIO.read( ) against various input files…

public class StudentsIOTest{ // tests against an empty input file… public static void readEmpty() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!"); }

// tests against an input file with one student, "Jim Bag" public static void readOne() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("one.txt"); . . .

public class StudentsIOTest{ // tests against an empty input file… public static void readEmpty() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!"); }

// tests against an input file with one student, "Jim Bag" public static void readOne() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("one.txt"); . . .

Page 13: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-13MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Running test harness

• Common approach is to define a main method in test harness– Reconfigure VS to startup app using this main. Right-click on

project in Solution Explorer (or use Project menu), select Properties, then Common Properties, then General, and set "Startup Object" in this case to "StudentApp.StudentsIOTest".

public class StudentsIOTest{ …

public static void main(String[] args) { int failed = 0; System.out.println("** Testing StudentsIO **");

try { readEmpty(); } catch(Exception ex) { System.out.println(ex.toString()); failed++; } … }}//class

public class StudentsIOTest{ …

public static void main(String[] args) { int failed = 0; System.out.println("** Testing StudentsIO **");

try { readEmpty(); } catch(Exception ex) { System.out.println(ex.toString()); failed++; } … }}//class

Page 14: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-14MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Part 3

• Testing with NUnit…

Page 15: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-15MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

NUnit

• NUnit is based on the highly-successful Java tool JUnit

– NUnit is for .NET code

– NUnit is for testing "units", i.e. classes

– available for free from http://nunit.org/

Page 16: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-16MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

NUnit methodology

• NUnit automates the running of the test harness

– it doesn't write the test harness for you (that's our job)

– it runs the test harness & collects statistics…

.EXE / .D.EXE / .DLLLL

Page 17: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-17MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

How does NUnit help?

• NUnit helps in many ways:

– you don't have to write the code to collect & output statistics

– tells you exactly which tests failed / skipped

– catches exceptions that testing methods may throw

– provides a framework for regression testing, i.e. re-testing after source code has been modified

Page 18: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-18MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Using NUnit

• Five-step process:

1. Download & install NUnit

2. Create test harness, with instance test methods & no main( )

3. Set a reference to NUnit:• Project menu, Add Reference…• Browse…• Navigate to C:\Program Files\NUnit V2.1\bin• Open "nunit.framework.dll"• Ok

4. Add NUnit attributes to test harness, rebuild project

5. Startup Nunit-Gui via Start menu, open compiled code, & run!• "Green" light means test passed• "Yellow" light means test was skipped• "Red" light means test failed

Page 19: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-19MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Example

• Let's revisit test harness for StudentsIO.read( )…

• Same as before, except:– no main method; test methods should be instance methods– addition of NUnit attributes to identify test harness & methods

/** @attribute NUnit.Framework.TestFixture() */public class StudentsIOTest{ /** @attribute NUnit.Framework.Test() */ public void readEmpty() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!"); } . . .

/** @attribute NUnit.Framework.TestFixture() */public class StudentsIOTest{ /** @attribute NUnit.Framework.Test() */ public void readEmpty() throws java.lang.Exception { java.util.ArrayList students; students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!"); } . . .

Page 20: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-20MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Working with NUnit

• Idea:

– compile test harness, etc. in Visual Studio .NET

– startup Nunit-Gui, file >> open compiled code, run test harness• Green is good, Yellow is caution, Red is bad

– leave both tools open, compiling in VS & testing in NUnit

.EXE / .D.EXE / .DLLLL

Page 21: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-21MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Debugging with NUnit

• Visual Studio's debugger is still available• Process for debugging:

– open Visual Studio & Nunit-Gui as usual

– set breakpoints in VS as usual

– in VS, attach debugger to Nunit-Gui as follows:• Debug menu• Processes…• select "nunit-gui.exe" from list• click "Attach"• check the box for "Common Language Runtime" & click OK• close Processes window, notice that VS is now in "Run" mode

– in Nunit-Gui, click Run button!• when you are done testing/debugging, you'll need to stop VS…

Page 22: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-22MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Writing a test method

• If test method returns, counted as success• If test method throws an exception, counted as failure• Implication:

– test method must throw an exception to denote failed test…

/** @attribute NUnit.Framework.Test() */public void readEmpty() throws java.lang.Exception{ java.util.ArrayList students;

students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!");}

/** @attribute NUnit.Framework.Test() */public void readEmpty() throws java.lang.Exception{ java.util.ArrayList students;

students = StudentsIO.read("empty.txt"); if (students == null || students.size() != 0) throw new java.lang.Exception("readEmpty failed!");}

Page 23: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-23MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Assertions

• Assertions are a common way of denoting failure• Idea:

– you assert that a particular boolean condition is true– if condition turns out to be true, nothing happens– if condition turns out to be false, an exception is thrown

/** @attribute NUnit.Framework.Test() */public void readEmpty() throws java.lang.Exception{ java.util.ArrayList students;

students = StudentsIO.read("empty.txt"); System.Diagnostics.Debug.Assert(students != null); System.Diagnostics.Debug.Assert(students.size() == 0);}

/** @attribute NUnit.Framework.Test() */public void readEmpty() throws java.lang.Exception{ java.util.ArrayList students;

students = StudentsIO.read("empty.txt"); System.Diagnostics.Debug.Assert(students != null); System.Diagnostics.Debug.Assert(students.size() == 0);}

Page 24: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-24MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Part 4

• Other tools & ideas…

Page 25: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-25MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Other tools & ideas

• NUnit short demo videos by Martin Schray: http://www.msdnacademicalliance.net/curriculum/pfv.aspx?5935

• WinForms GUI testing?– NUnitForms, http://sourceforge.net/projects/nunitforms/

• Web app testing?– NUnitASP, http://sourceforge.net/projects/nunitasp/

• Other strategies?– programming with invariants, listing pre & post-conditions

– these are based on the idea of using assertions in your code:

// at this point in the program, count should be 1, if not through an exception & stop nowSystem.Diagnostics.Debug.Assert(count == 1, "Count==1 failed");

// at this point in the program, count should be 1, if not through an exception & stop nowSystem.Diagnostics.Debug.Assert(count == 1, "Count==1 failed");

Page 26: Lecture 9: Debugging & Testing. 9-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Unfortunately, errors are a part of life. Some

9-26MicrosoftIntroducing CS using .NETJ# in Visual Studio .NET

Summary

• Unfortunately, errors are a part of being human• Errors can be eliminated, but it takes a great deal of effort:

– good logic– good design– good programming– good testing

• You have the tools:– J#, Visual Studio .NET, NUnit, etc.