Introduction to Testing, SUnit and Error Handling CS2340 Fall 2004
Blackbox Testing Going to get the theory from 2335. Treat code as a “black box” Base test cases on specification Two major techniques: Equivalence Partitions Boundary Value Tests Exhaustive testing not possible Fall 2004
Equivalence Partitions Treat sets of data as same (if one test succeeds all tests succeed) For ranges, pick one test in range, one test on each end. For sets, pick one in set, one not in set. For unique values, pick value, not value. Fall 2004
Examples Must accept years between 1-2050. Test cases: 0, 1876 , 2076. Passwords must be 6-8 chars long: Test cases: ab, abcdef, abcdegujswidn Leap years are divisible by four: Test cases: 16, 99 Phone exchanges must not begin with 555. Test cases: 555, 498 Fall 2004
Boundary Value Tests Most of the errors happen on the boundaries between sets Must accept years between 1-2050. Test cases: 0, 1, 2050, 2051. Boundary Value Tests compliment Equivalence Partitions Fall 2004
Writing your tests We could just write workspace code and DoIt over and over… Hoping that we don’t ever close window Checking transcript manually to ensure results are what we want. We could write a custom class to do our test and result checking We can use the SUnit framework. Fall 2004
SUnit Testing framework for creating and running unit tests (regression tests) automatically in Smalltalk Originally developed by Kent Beck Implementations exist for many languages JUnit for Java A framework is a collection of classes that can be used and extended for a particular domain. Fall 2004
SUnit Advantages Self-checking and reporting Check results against expected results Report which test is broken Built-in initialize before a test and clean-up after a test setUp is called before each method test tearDown is called after each method test Fall 2004
When to use SUnit? Extreme Programming Used for regression testing Create unit test before the code Helps you understand what the code must do Helps you to know when the code is done Used for regression testing Did you break anything when making changes? Maintenance Once you find a bug create a unit test to make sure it is fixed and stays fixed Fall 2004
Using SUnit Derive class from TestCase Do any set up (initialize variables) in setUp Do any clean up in tearDown Create methods testXxxx Use: self assert: expr_that_evals_true self deny: expr_that_evals_false self should: [ block that evals to true ]. self shouldnt: [block that evals to false ]. TestRunner open. Fall 2004
TestRunner You can look at the current tests in Squeak using TestRunner and run any by clicking on “Run”. There is an example ExampleSetTest to learn from. Fall 2004
Example: Assume we have a class Muppet with method: name: aName And: name testName | oscar | oscar := Muppet new. oscar name: 'oscar'. self assert: oscar name = ’oscar'. self should: [oscar name = ’oscar']. self deny: oscar name = ’ocsar'. TestCase subclass: #TestMuppet instanceVariableNames: ‘ ‘ classVariableNames: ‘ ‘ poolDictionaries: ‘ ‘ category: ‘Muppet Classes’ . Fall 2004
Key steps For each ‘real’ class X, have a test class TestX derived from TestCase Decide how to test functionality For functionality Y in class X, have a test method testY in class TestX. Run TestRunner to evaluate tests automatically (TestRunner open) May use SqueakMap to download TestBrowser if desired (more later) By ‘real’ class we mean a class that represents something in the domain or a model class. You don’t have to have a test per method but you do want to test important functions. Fall 2004
Testing Set Functionality Notice that not every method of Set has a test method. The main functionality that is being tested is add, grow, includes, remove, no duplicates, and exceptions. Fall 2004
Testing with Exceptions Check for exceptions self should: [boolean] raise: Exception Make sure no exceptions self shouldnt: [boolean] raise: Exception Fall 2004
Exception Handling in Squeak Class Exception and its subclasses provided for use. Can emulate try/catch block in other languages Exceptions pass up inheritance hierarchy. If not handled, get default handler at Object. Look at the hierarchy to see the subclasses of Exception including predefined exceptions like ZeroDivide Fall 2004
[x / y] “like a try block” on: ZeroDivide “exception class” Example | x y | x:=7. y:=0. [x / y] “like a try block” on: ZeroDivide “exception class” do: [ :exception | Transcript show: exception description ; cr. 0 ]. This basically means execute the code in the block with an exception handler. If the exception occurs during the code execution and an object of the class given on the on: is created then execute the code in the do: block. Fall 2004
Example | f | [f:=FileStream fileNamed: 'fred'. f nextPutAll: 'Test'. f close. ] on: FileDoesNotExistException do: [:exception | Transcript show: exception description. ]. Fall 2004
Example: Testing with Exceptions Fall 2004
SqueakMap Software package distribution mechanism with Squeak http://coweb.cc.gatech.edu/cs2340/1407 http://minnow.cc.gatech.edu/squeak/2726 World Menu -> Open… -> Package Loader Asks if you want to install SqueakMap; say yes Eventually fires up SM Package Loader Fall 2004
Package Loader Select “TestBrowser” in SqueakMap Right-click, choose “install” from menu Fall 2004
TestBrowser TestBrowser open Fall 2004
Next on the Menu Read chapter 3 “Joe the Box” – simple 2D graphics UML Fall 2004