Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Avoiding bugs pro-actively by change-oriented programming

qsoetens
March 17, 2012

Avoiding bugs pro-actively by change-oriented programming

To minimize the cost of fixing bugs, they need to be identified as soon as possible. Testing the system is a means to detect such defects. However, when all the tests are run, it is often difficult to locate the precise error that causes a test to fail. We propose to use change-oriented programming as a means to detect bugs in a system while it is being developed. Not only may this technique assists in detecting bugs sooner, it can also be used to provide the developer with fine-grained information about the places in the program and test code that relate to the defect. We believe that this will decrease the probability of introducing bugs in a system and speed up the detection of the bugs that do get in.

qsoetens

March 17, 2012
Tweet

More Decks by qsoetens

Other Decks in Research

Transcript

  1. Ansymo Antwerp Systems and Software Modelling Quinten David Soetens Pro-active

    Debugging by Change-Oriented Programming Peter Ebraert Serge Demeyer
  2. Outline • Our Vision • Change Oriented Programming (ChOP) •

    Testing with ChOP • Pro-active debugging by ChOP • Optimization • Conclusion 2
  3. package engine; import java.util.*; public class SuffixTree { int[] hdlabel

    = new int[10000]; int[] ithSuf; int ithSufLength; int ithSufBegin; int[] firstSuf; public Vertex root= null; private Vector pStringV; private int[] a; public Vector pMatches = new Vector(); Vector inputFiles; int in;//de in-de suffix public SuffixTree(Vector symbolen, Vector files) { pStringV = symbolen; inputFiles = files; ithSuf = new int[pStringV.size()]; firstSuf = new int[pStringV.size()]; } private void ithSuffix1(){//nieuwe versie, nu voor i=1 for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==false){ firstSuf[j]=s.symbool; ithSuf[j]=s.symbool; } else{ firstSuf[j]=s.dTotVorige; ithSuf[j]=s.dTotVorige; } } ithSufLength = pStringV.size(); ithSufBegin=0; } private void ithSuffix(int i){//nieuwste versie, niet voor i=1 ithSufBegin = i-1; Symbool sym = (Symbool)pStringV.elementAt(i-2); if(sym.parameter==true && sym.dTotVolgende!=0){ ithSuf[i-2+sym.dTotVolgende] = 0; } ithSufLength = pStringV.size()-i+1; // return ithSufClone;//nodig? } public void berekenDTotVorige(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int vorigePos=-1; for(int k=j-1;k>=0;k--){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {vorigePos=k;break;} }//is er een probleem als een n-par en een par dezelfde int hebben? if(vorigePos==-1) s.dTotVorige=0; else s.dTotVorige = j-vorigePos; } } } public void berekenDTotVorige2(){ Hashtable ht = new Hashtable(); for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ Integer i = new Integer(s.symbool); if(!ht.containsKey(i)){ s.dTotVorige=0; ht.put(i,new Integer(j)); } else{ int vorigeIndex = ((Integer)ht.get(i)).intValue(); ht.put(i,new Integer(j)); s.dTotVorige = j-vorigeIndex; } } } } public void berekenDTotVolgende(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int volgendePos=-1; for(int k=j+1;k<pStringV.size();k++){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {volgendePos=k;break;} } if(volgendePos==-1) s.dTotVolgende=0; else s.dTotVolgende = volgendePos-j; } Our Vision 3 TEST SUITE SOURCE CODE
  4. package engine; import java.util.*; public class SuffixTree { int[] hdlabel

    = new int[10000]; int[] ithSuf; int ithSufLength; int ithSufBegin; int[] firstSuf; public Vertex root= null; private Vector pStringV; private int[] a; public Vector pMatches = new Vector(); Vector inputFiles; int in;//de in-de suffix public SuffixTree(Vector symbolen, Vector files) { pStringV = symbolen; inputFiles = files; ithSuf = new int[pStringV.size()]; firstSuf = new int[pStringV.size()]; } private void ithSuffix1(){//nieuwe versie, nu voor i=1 for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==false){ firstSuf[j]=s.symbool; ithSuf[j]=s.symbool; } else{ firstSuf[j]=s.dTotVorige; ithSuf[j]=s.dTotVorige; } } ithSufLength = pStringV.size(); ithSufBegin=0; } private void ithSuffix(int i){//nieuwste versie, niet voor i=1 ithSufBegin = i-1; Symbool sym = (Symbool)pStringV.elementAt(i-2); if(sym.parameter==true && sym.dTotVolgende!=0){ ithSuf[i-2+sym.dTotVolgende] = 0; } ithSufLength = pStringV.size()-i+1; // return ithSufClone;//nodig? } public void berekenDTotVorige(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int vorigePos=-1; for(int k=j-1;k>=0;k--){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {vorigePos=k;break;} }//is er een probleem als een n-par en een par dezelfde int hebben? if(vorigePos==-1) s.dTotVorige=0; else s.dTotVorige = j-vorigePos; } } } public void berekenDTotVorige2(){ Hashtable ht = new Hashtable(); for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ Integer i = new Integer(s.symbool); if(!ht.containsKey(i)){ s.dTotVorige=0; ht.put(i,new Integer(j)); } else{ int vorigeIndex = ((Integer)ht.get(i)).intValue(); ht.put(i,new Integer(j)); s.dTotVorige = j-vorigeIndex; } } } } public void berekenDTotVolgende(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int volgendePos=-1; for(int k=j+1;k<pStringV.size();k++){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {volgendePos=k;break;} } if(volgendePos==-1) s.dTotVolgende=0; else s.dTotVolgende = volgendePos-j; } Our Vision 3 if(sym.symbool==s.symbool) {vorigePos=k;break;} }//is er een probleem als een n-par en een par dezelfde int hebben? FOREACH Development Action : Run Tests TEST SUITE SOURCE CODE
  5. package engine; import java.util.*; public class SuffixTree { int[] hdlabel

    = new int[10000]; int[] ithSuf; int ithSufLength; int ithSufBegin; int[] firstSuf; public Vertex root= null; private Vector pStringV; private int[] a; public Vector pMatches = new Vector(); Vector inputFiles; int in;//de in-de suffix public SuffixTree(Vector symbolen, Vector files) { pStringV = symbolen; inputFiles = files; ithSuf = new int[pStringV.size()]; firstSuf = new int[pStringV.size()]; } private void ithSuffix1(){//nieuwe versie, nu voor i=1 for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==false){ firstSuf[j]=s.symbool; ithSuf[j]=s.symbool; } else{ firstSuf[j]=s.dTotVorige; ithSuf[j]=s.dTotVorige; } } ithSufLength = pStringV.size(); ithSufBegin=0; } private void ithSuffix(int i){//nieuwste versie, niet voor i=1 ithSufBegin = i-1; Symbool sym = (Symbool)pStringV.elementAt(i-2); if(sym.parameter==true && sym.dTotVolgende!=0){ ithSuf[i-2+sym.dTotVolgende] = 0; } ithSufLength = pStringV.size()-i+1; // return ithSufClone;//nodig? } public void berekenDTotVorige(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int vorigePos=-1; for(int k=j-1;k>=0;k--){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {vorigePos=k;break;} }//is er een probleem als een n-par en een par dezelfde int hebben? if(vorigePos==-1) s.dTotVorige=0; else s.dTotVorige = j-vorigePos; } } } public void berekenDTotVorige2(){ Hashtable ht = new Hashtable(); for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ Integer i = new Integer(s.symbool); if(!ht.containsKey(i)){ s.dTotVorige=0; ht.put(i,new Integer(j)); } else{ int vorigeIndex = ((Integer)ht.get(i)).intValue(); ht.put(i,new Integer(j)); s.dTotVorige = j-vorigeIndex; } } } } public void berekenDTotVolgende(){ for(int j=0;j<=pStringV.size()-1;j++){ Symbool s = (Symbool)pStringV.elementAt(j); if(s.parameter==true){ int volgendePos=-1; for(int k=j+1;k<pStringV.size();k++){//zoek of de parameter al eerder voorkwam Symbool sym = (Symbool)pStringV.elementAt(k); if(sym.symbool==s.symbool) {volgendePos=k;break;} } if(volgendePos==-1) s.dTotVolgende=0; else s.dTotVolgende = volgendePos-j; } Our Vision 3 if(sym.symbool==s.symbool) {vorigePos=k;break;} }//is er een probleem als een n-par en een par dezelfde int hebben? FOREACH Development Action : Run Tests • We Know: • What development action caused the test(s) to fail. • Which test(s) failed • The source code that is tested by the failing test(s). TEST SUITE SOURCE CODE
  6. ChOP 4 Change-Oriented Software Engineering Peter Ebraert, Jorge Antonio Vallejos

    Vargas, Pascal Costanza, Ellen Van Paesschen, Theo D'Hondt In "Proceedings of the 2007 International Conference on Dynamic Languages", published by ACM, 2007
  7. ChOP - Logging 5 class Buffer { } int buf

    = 0; int get() { } return( buf ); void set( int x ) { } buf = x; B2 B1 B3 B4 B5 B6 B1 B2 B3 B4 B5 B6
  8. ChOP - Logging 5 class Buffer { } int buf

    = 0; int get() { } return( buf ); void set( int x ) { } buf = x; B2 B1 B3 B4 B5 B6 Buffer B1 B2 B3 B4 B5 B6
  9. Testing 6 class BufferTest extends TestCase { Buffer buffer; void

    setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } }
  10. Testing 6 BufferTest T1 T2 T4 T8 T3 T5 T6

    T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } T1 T2 T3 T5 T9 T4 T6 T7 T8 T10 T11 T12 T13 T14
  11. Pro-active Debugging 7 class Buffer { int buf = 0;

    int get(){ return (buf); } void set (int x){ buf = x; } } B3 B1 B2 B5 B4 B6 Buffer B1 B2 B3 B4 B6 B5
  12. Pro-active Debugging 7 class Buffer { int buf = 0;

    int get(){ return (buf); } void set (int x){ buf = x; } } B3 B1 B2 B5 B4 B6 Buffer B1 B2 B3 B4 B6 B5
  13. Pro-active Debugging 8 B3 B1 B2 B5 B4 B6 Buffer

    class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14
  14. Pro-active Debugging 8 B3 B1 B2 B5 B4 B6 Buffer

    class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14
  15. B1 B2 B3 B4 B6 B5 Pro-active Debugging 9 B3

    B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } }
  16. B1 B2 B3 B4 B6 B5 Pro-active Debugging 9 B3

    B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); }
  17. B1 B2 B3 B4 B6 B5 Pro-active Debugging 9 B3

    B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } R1 R2 Restore B1 B5 R3 R4 R1 R2 R3 R4
  18. B1 B2 B3 B4 B6 B5 Pro-active Debugging 9 B3

    B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } R1 R2 Restore B1 B5 R3 R4 R1 R2 R3 R4
  19. B1 B2 B3 B4 B6 B5 Pro-active Debugging 9 B3

    B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } R1 R2 Restore B1 B5 R3 R4 R1 R2 R3 R4
  20. Pro-active Debugging 10 B3 B1 B2 B5 B4 B6 Buffer

    BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 R1 R2 Restore B1 B5 R3 R4 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14
  21. Pro-active Debugging 10 B3 B1 B2 B5 B4 B6 Buffer

    BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 R1 R2 Restore B1 B5 R3 R4 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14
  22. Pro-active Debugging 10 B3 B1 B2 B5 B4 B6 Buffer

    BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 R1 R2 Restore B1 B5 R3 R4 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } testRestore T1 T2 B2 R2 S1 S2 S3 S4 S6 S8 S9 S10 S5 S7 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  23. Pro-active Debugging 10 B3 B1 B2 B5 B4 B6 Buffer

    BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 R1 R2 Restore B1 B5 R3 R4 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } testRestore T1 T2 B2 R2 S1 S2 S3 S4 S6 S8 S9 S10 S5 S7 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  24. Pro-active Debugging 10 B3 B1 B2 B5 B4 B6 Buffer

    BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 R1 R2 Restore B1 B5 R3 R4 class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } testRestore T1 T2 B2 R2 S1 S2 S3 S4 S6 S8 S9 S10 S5 S7 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  25. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  26. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  27. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  28. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  29. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  30. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  31. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  32. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  33. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  34. Pro-active Debugging 11 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 B1 B2 B3 B4 B6 B5 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  35. Pro-active Debugging 12 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 R1 R2 Restore B1 B5 R3 R4 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } B1 B2 B3 B4 B6 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8
  36. Pro-active Debugging 12 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } R1 Restore B1 B2 B5 R3 R4 B5 R5 R6 R2 back = buf; B1 B2 B3 B4 B6 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8 R5 R6
  37. Pro-active Debugging 12 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } R1 Restore B1 B2 B5 R3 R4 B5 R5 R6 R2 back = buf; B1 B2 B3 B4 B6 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8 R5 R6
  38. Pro-active Debugging 12 testRestore T1 T2 B2 R2 S1 S2

    S3 S4 S6 S8 S9 S10 S5 S7 B5 B3 B1 B2 B5 B4 B6 Buffer BufferTest T1 T2 T4 T8 T3 T5 T6 T7 T9 T10 B1 B2 B3 B5 T11 T12 T13 T14 class Buffer { int buf = 0; int get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } R1 Restore B1 B2 B5 R3 R4 B5 R5 R6 R2 back = buf; B1 B2 B3 B4 B6 B5 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 R1 R2 R3 R4 S1 S2 S3 S4 S5 S6 S7 S9 S10 S8 R5 R6
  39. Properties 13 class Buffer { int buf = 0; int

    get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); }
  40. Properties 13 class Buffer { int buf = 0; int

    get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } Small Delta’s
  41. Properties 13 class Buffer { int buf = 0; int

    get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } Small Delta’s Fine-grained
  42. Properties 13 class Buffer { int buf = 0; int

    get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } Small Delta’s Fine-grained Relations within Test Code Relations within Program Code Relations between Test & Program Code
  43. Properties 13 class Buffer { int buf = 0; int

    get(){ return (buf); } void set (int x){ buf = x; } } int back = 0; void restore() { set(back); } class BufferTest extends TestCase { Buffer buffer; void setUp(){ buffer = new Buffer(); } void tearDown(){} void testGet(){ buffer.buf = 1337; assertEquals(buffer.get(), 1337); } void testSet(){ buffer.set(7331); assertEquals(buffer.buf, 7331); } } void testRestore(){ buffer.buf= 1337; buffer.set(1338); buffer.restore(); assertEquals(buffer.buf, 1337); } Small Delta’s Fine-grained Relations within Test Code Relations within Program Code Relations between Test & Program Code Support Deletion
  44. Optimization 14 • No need to run ALL the tests

    • Only run tests relevant to change that is made • Relevant tests can be found via dependencies
  45. Take Home 15 • Change Oriented Programming (http://peter.ebraert.be) • Run

    tests in background with every change • Detect bugs while programming • Dependencies show ‘spots’ where bug could be • Optimization technique