330 likes | 444 Views
CSC 213 – Large Scale Programming. Lecture 6: Do I HAVE TO Test IT? Why ?. Why Do We Test?. But the Problem Is…. Can We Get Best Of Both?. Can We Get Best Of Both?. Testing To The Rescue. Before we start coding, write solid set of tests Best, worst, & average cases examined in tests
E N D
CSC 213 – Large Scale Programming Lecture 6:Do I HAVE TO Test IT? Why?
Testing To The Rescue • Before we start coding, write solid set of tests • Best, worst, & average casesexamined in tests • Includes tests for all possible boundary conditions • Tests drive the code & set pace of the coding • Code only written to be good enough to pass tests • Debugging simplified using the simple failed cases • Once system can pass all tests, we’re golden
Testing To The Rescue • Before we start coding, write solid set of tests • Best, worst, & average casesexamined in tests • Includes tests for all possible boundary conditions • Tests drive the code & set pace of the coding • Code only written to be good enough to pass tests • Debugging simplified using the simple failed cases • Once system can pass all tests, we’re golden
Testing To The Rescue • Before we start coding, write solid set of tests • Best, worst, & average casesexamined in tests • Includes tests for all possible boundary conditions • Tests drive the code & set pace of the coding • Code only written to be good enough to pass tests • Debugging simplified using the simple failed cases • Once system can pass all tests, we’re golden
Oops… • Design we created has lots of side effects • Results printed out at the end of void methods • Other methods just update values of object’s fields • Add special methods that allow field access • Not a big deal & needed to test affect on fields' values
OOPS… • Stuck with BIG issue: how to check I/O correct? • How to test screen to verify warning are printed? • How to insure file has correct values before & after?
OOPS… • Stuck with BIG issue: how to check I/O correct? • How to test screen to verify warning are printed? • How to insure file has correct values before & after? • Cannot skip tests since correctness important • Always want to be correct, but cannot test online
OOPS… • Stuck with BIG issue: how to check I/O correct? • How to test screen to verify warning are printed? • How to insure file has correct values before & after? • Cannot skip tests since correctness important • Always want to be correct, but cannot test online And it monitors a nuclear reactor
Laziness Depends on Design • Well-planned design makes testable methods • Testable methods leads to good tests • Good tests leads to easy coding & debugging • Easy coding & debugging leads to free time • Free time leads to laziness
Design Methods For Testing • Start by defining method for each calculation • Method returns result once it is calculated • As needed, create other methods to output results • Easy to test & debug methods with observable results
Design Methods For Testing • Start by defining method for each calculation • Method returns result once it is calculated • As needed, create other methods to output results • Easy to test & debug methods with observable results versus
Mock Objects To Win • Some things just cannot be tested with JUnit • Failed nuclear plant tests a bit of a problem • Some times its impossible to access or use classes • File or network I/O required, but cannot test offline • These situations leave limited options • Whine about it being unfair • Leave code untested and say "oops" a lot • Prove correctness mathematically • Create stand-ins called mock objects
Getting Ready for Mocks • Use interfaces in place of hard-to-use classes • Interface defines minimum number of methods • Update old classto implement this interface • Must modify code when hard-to-use class alloc'd • Pass instance to method & eliminate new command • If instance was field, set using constructor's parameter
Original Example public class ThreeMileIsland {private NuclearReactor reactor;public ThreeMileIsland() {reactor= new NuclearReactor("SNPP");}public booleancheckForBreach() { if (!reactor.withinLimits()) {return reactor.alarmSounding(); } return false;} }
New Interface public interface NRInterface {public booleanwithinLimits();public booleanalarmSounding(); } public class ThreeMileIsland {// More code went herepublic booleancheckForBreach() { if (!reactor.withinLimits()) {return reactor.alarmSounding(); } return false;} }
Rewrite From This… public class ThreeMileIsland {private NuclearReactor reactor;public ThreeMileIsland() {reactor= new NuclearReactor("SNPP");}public booleancheckForBreach() { if (!reactor.withinLimits()) {return reactor.alarmSounding(); } return false;} }
Rewrite From This… …To This public class ThreeMileIsland {private NRInterface reactor;public ThreeMileIsland(NRInterface nm) {reactor= nm;}public booleancheckForBreach() { if (!reactor.withinLimits()) {return reactor.alarmSounding(); } return false;} }
Why We Write Mock Classes! Testing ThreeMileIslandnotNuclearReactor
Create Mock Class • Write classes needed to test code fully • Testing ThreeMileIsland notNuclearReactor • ONLY purpose is testing other classes code • May hard-code values; write as simply as possible • Store parameters in Sequences to check calls correct • Do not use files or network, mock to avoid these needs • Duct tape & mock classes are similar • Useful & pretty, but not the real thing
Writing Mock Class public interface NRInterface {public booleanwithinLimits();public booleanalarmSounding(); } public class MeltdownMock implements NRInterface{public booleanwithinLimits() {return false; }public booleanalarmSounding() {return true; } }
Using Mock Class • Now run original method in two different ways • Provide and use mock objects when testing code • Actual classes during execution so still works • Remember: Testing ThreeMileIslandnot mock class
Writing Mock Class public class MeltdownMock implements NRInterface {public booleanwithinLimits() {return false; }public booleanalarmSounding() {return true; } } @Test public void testTMI() {NRInterfacemltdn= new MeltdownMock();ThreeMileIslandtmi = new ThreeMileIsland(mltdn);assertTrue(tmi.checkForBreach()); }
Mock Class Coding Review • Use interfaces in place of hard-to-use classes • Interface defines minimum number of methods • Update old classto implement this interface • Must modify code when hard-to-use class alloc'd • Pass instance to method & eliminate new command • If instance was field, set using constructor's parameter • Test original using specially written mock classes • Mock classes should be simple, often return a constant • Not testing mocking, but if class can handle its result
Testing Printing To Screen • Java already thought of this & created solution • Only need to set static field in Systemclass • System.setOut(PrintStream)does this for us • Instance passed as parameter will be sent all output • No new classes required for this to work • Can add code to method run before each test • @Beforemethod needed to contain this code
Writing Code to Test Output import java.io.PrintStream; public class TestCode {private OutputStreamos;String nl = System.getProperty("line.separator"); @Beforepublic void setUp() {os= new ByteArrayOutputStream();System.setOut(new PrintStream(os));}@Testpublic void testPrintln() {callMethodWith_println_Hi();assertEquals(os.toString(), "Hi" +nl);}
Writing Code to Test Output import java.io.PrintStream; public class TestCode {private OutputStreamos;String nl = System.getProperty("line.separator"); @Beforepublic void setUp() {os= new ByteArrayOutputStream();System.setOut(new PrintStream(os));}@Testpublic void testPrintln() {callMethodWith_println_Hi();assertEquals(os.toString(), "Hi" +nl);}
Writing Code to Test Output import java.io.PrintStream; public class TestCode {private OutputStreamos;String nl = System.getProperty("line.separator"); @Beforepublic void setUp() {os= new ByteArrayOutputStream();System.setOut(new PrintStream(os));}@Testpublic void testPrintln() {callMethodWith_println_Hi();assertEquals(os.toString(), "Hi" +nl);}
For Next Lecture • Next weekly assignment available online • Due as usual tomorrow at 5PM • Give me notes on reading to delay this due date • Reading on event-driven programming • How to code if we do not know what will happen? • What error is found most starting GUI programs? • How can I make my code finish within my lifetime? • (Design notes for ActionListener okay for extension)