R&D Dept.
Switching Division
Testing Team




      Design for Testability

            Prepared By:
                                 -
                           Amr Medhat
                                  -
                            13 - 4 - 2006
                                  -
Outline
     Testability: what, why, how and when?
     The Design Dilemma
     Testability Features
     Techniques for Developing Quality-
      Oriented Software



Design for Testability
Testability .. What?
     Testability = controllability & visibility




           Controllability: the ability to apply inputs to s/w
            under test & place it in specified states

           Visibility: the ability to observe states and outputs
            [what we see is what we test]

Design for Testability
Testability .. Why?
     Improve software quality

     Ease the test process and more support
      for test automation

     Cost reduction
        The average software company spends 60-80% of
         its development costs on supporting [Lidor Wyssocky]
Design for Testability
Testability .. How?
         Investing more time in design
          [A good design is a testable design]

         Adding testability features

         Using special techniques throughout
          the development process
Design for Testability
Testability .. When?
                          From Day 1 

     Testers has to be engaged early in the
      product development cycle

     The product has to be open for design
      changes to meet the testing requirements


Design for Testability
The Design Dilemma
           The time given for design.... ?!
           Using the perfect tools....
                           But in the wrong way ... !!!
                               ?
                                                modularity?
 Polymorphism
                                                scalability?
Encapsulation                                   reliability?
                                                reusability?
   Inheritance
                                                maintainability?

Data Abstraction



     Design for Testability
Design Weakness: How &
        Why
     Symptoms of a bad design
           Rigidity
           Fragility
           Immobility
           Viscosity
     Causes of a bad design
           Lack of Abstraction
           Violation of Encapsulation
           Interdependence {between Objects & Layers}
Design for Testability
Abstraction & Interfaces
     Separate interface from its implementation
     use overriding to support polymorphism
     When deriving a class,
      inherit interface
      not implementation

     Implementation is either Extended
     Or, Overridden  Polymorphism

Design for Testability
Encapsulation
     Data are Private, Methods are Public…,
      & Implementation Details are Hidden
     Encapsulating the data and the functions
      operating on this data.
          myThing[] things = thingManager.getThingList();
          for (int i = 0; i < things.length; i++) {
           myThing thing = things[i];
                                                            
           if (thing.getName().equals(thingName)) {
             return thingManager.delete(thing); } }


         return thingManager.deleteThingNamed(thingName);   
Design for Testability
Interdependence
     The Acyclic Dependencies Principle
      (ADP)
         Dependencies must not form cycles


     3 ways of communication
           Invoke Method  Superiority Relation
           Raise Trigger  Inferiority Relation
           Message Passing  Peer Relation
Design for Testability
Class Design Principles
     The Single Responsibility Principle
      (SRP) class has only one responsibility
        Each


     The Open-Closed Principle extension
       A module should be open for (OCP)
                         but closed for modification


     The Liskov Substitution Principle (LSP)
       Subclasses should be substitutable for
                              their base classes
Design for Testability
Copy
               Reader           Writer
              Keyboard          Printer         Disk
               Reader           Writer          Writer
                Read             Write           Write
              Keyboard          Printer          Disk
OCP Example




                                          Printer
                                           Write




                                                             Design for Testability
                                                     Write
               Copy




                                                     Disk
                                          Keyboard
                                            Read
LSP Example
  class Bird {                                           class Penguin : public Bird {
    public: virtual void fly();                            public: void fly() {
  };                                                         error (“Penguins don’t fly!”); }
                                                         };
  class Parrot : public Bird {
    public: virtual void mimic();
  };

                           void PlayWithBird (Bird& abird) {
                              abird.fly(); // OK if Parrot.
                              // if bird happens to be Penguin...OOOPS!!
                           }

 Does not model: “Penguins can’t fly”
 It models “Penguins may fly, but if they try it is error”
 Run-time error if attempt to fly → not desirable
  Design for Testability
Testability Features
     Logging events & verbose mode
      support
     Assertions {make assumptions explicit}
     Test points (fault injection hooks)
     Scriptable installation process



Design for Testability
Testability Features (cont.)
     Benefits of Adding Testability Features
           Detecting internal errors before they propagate
           Knowing the source and place of the problem easily
           Ability to reproduce bugs many times
     Notes
           Time stamps may be useful in logging
           Well describe and identifying the logged event
           Agree on a standard format of logging all over the system
            [The use of a stand-alone Logger]
           Use variable levels of logging
           Throwing exceptions upon an assertions violation may be
            useful rather than just logging it as a warning

Design for Testability
Development Techniques
         Defensive Programming
        Assertions everywhere
         Design by Contract
         Test-Driven Development
         Mock Objects
        A generic unit testing framework that
          supports TDD better than test stubs

Design for Testability
Design by Contract
     Preconditions
        what must be true when a method is invoked
     Postconditions
        what must be true after a method completes
         successfully.
     Class invariants
        what must be true about each instance of a class.



Design for Testability
Test-Driven Development
     Write tests first, then write the minimal code
      the makes this test pass
     Tests provide the required specification for
      the developer {A part of the documentation}
     Provides rapid feedback for the developer
     Emphasizes fast, incremental development
     Functionality is added in very small chunks
     Ensures 100% thoroughly unit tested code


Design for Testability
Summary
     Design Better
           Use interfaces
           Don’t violate encapsulation
           Avoid interdependence and cycles
           Class single responsibility
           Class open for extension closed for modification
           Class substitution (parent is more general than its child)
     Add Testability Features
           Logging
           Assertions
           Fault injection hooks
     Enhance the Development Process
           Design by contract
           Test-driven development

Design for Testability
References
  1.      Bret Pettichord, “Design for Testability”
  2.      Jeffery E. Payne, Roger T. Alexander, Charles D. Hutchinson,
          “Design-for-Testability for Object-Oriented Software”
  3.      Robert Martin, “OO Design Quality Metrics An Analysis of
          Dependencies”
  4.      Rahul Tyagi, “Two principles to help create robust, reusable object-
          oriented design apps”
  5.      Robert C. Martin, “Design Principles and Design Patterns”
  6.      Matt Weisfeld, "Object-Oriented Thought Process", Second Edition,
          Sams Publishing
  7.      Wikipedia
  8.      http://www.johndeacon.net/OOAandD/top25GoldenRules.asp
  9.      http://www.artima.com/weblogs/viewpost.jsp?thread=132358
  10.     http://labs.cs.utt.ro/labs/ip2/html
  11.     http://www.mertner.com/confluence/display/MbUnit/Design+Standards


Design for Testability
R&D Dept.
Switching Division
Testing Team




      Thank You Very Much

Software Design for Testability

  • 1.
    R&D Dept. Switching Division TestingTeam Design for Testability Prepared By: - Amr Medhat - 13 - 4 - 2006 -
  • 2.
    Outline  Testability: what, why, how and when?  The Design Dilemma  Testability Features  Techniques for Developing Quality- Oriented Software Design for Testability
  • 3.
    Testability .. What?  Testability = controllability & visibility  Controllability: the ability to apply inputs to s/w under test & place it in specified states  Visibility: the ability to observe states and outputs [what we see is what we test] Design for Testability
  • 4.
    Testability .. Why?  Improve software quality  Ease the test process and more support for test automation  Cost reduction The average software company spends 60-80% of its development costs on supporting [Lidor Wyssocky] Design for Testability
  • 5.
    Testability .. How?  Investing more time in design [A good design is a testable design]  Adding testability features  Using special techniques throughout the development process Design for Testability
  • 6.
    Testability .. When?  From Day 1   Testers has to be engaged early in the product development cycle  The product has to be open for design changes to meet the testing requirements Design for Testability
  • 7.
    The Design Dilemma  The time given for design.... ?!  Using the perfect tools.... But in the wrong way ... !!! ? modularity? Polymorphism scalability? Encapsulation reliability? reusability? Inheritance maintainability? Data Abstraction Design for Testability
  • 8.
    Design Weakness: How& Why  Symptoms of a bad design  Rigidity  Fragility  Immobility  Viscosity  Causes of a bad design  Lack of Abstraction  Violation of Encapsulation  Interdependence {between Objects & Layers} Design for Testability
  • 9.
    Abstraction & Interfaces  Separate interface from its implementation  use overriding to support polymorphism  When deriving a class, inherit interface not implementation  Implementation is either Extended  Or, Overridden  Polymorphism Design for Testability
  • 10.
    Encapsulation  Data are Private, Methods are Public…, & Implementation Details are Hidden  Encapsulating the data and the functions operating on this data. myThing[] things = thingManager.getThingList(); for (int i = 0; i < things.length; i++) { myThing thing = things[i];  if (thing.getName().equals(thingName)) { return thingManager.delete(thing); } } return thingManager.deleteThingNamed(thingName);  Design for Testability
  • 11.
    Interdependence  The Acyclic Dependencies Principle (ADP) Dependencies must not form cycles  3 ways of communication  Invoke Method  Superiority Relation  Raise Trigger  Inferiority Relation  Message Passing  Peer Relation Design for Testability
  • 12.
    Class Design Principles  The Single Responsibility Principle (SRP) class has only one responsibility Each  The Open-Closed Principle extension A module should be open for (OCP) but closed for modification  The Liskov Substitution Principle (LSP) Subclasses should be substitutable for their base classes Design for Testability
  • 13.
    Copy Reader Writer Keyboard Printer Disk Reader Writer Writer Read Write Write Keyboard Printer Disk OCP Example Printer Write Design for Testability Write Copy Disk Keyboard Read
  • 14.
    LSP Example class Bird { class Penguin : public Bird { public: virtual void fly(); public: void fly() { }; error (“Penguins don’t fly!”); } }; class Parrot : public Bird { public: virtual void mimic(); }; void PlayWithBird (Bird& abird) { abird.fly(); // OK if Parrot. // if bird happens to be Penguin...OOOPS!! }  Does not model: “Penguins can’t fly”  It models “Penguins may fly, but if they try it is error”  Run-time error if attempt to fly → not desirable Design for Testability
  • 15.
    Testability Features  Logging events & verbose mode support  Assertions {make assumptions explicit}  Test points (fault injection hooks)  Scriptable installation process Design for Testability
  • 16.
    Testability Features (cont.)  Benefits of Adding Testability Features  Detecting internal errors before they propagate  Knowing the source and place of the problem easily  Ability to reproduce bugs many times  Notes  Time stamps may be useful in logging  Well describe and identifying the logged event  Agree on a standard format of logging all over the system [The use of a stand-alone Logger]  Use variable levels of logging  Throwing exceptions upon an assertions violation may be useful rather than just logging it as a warning Design for Testability
  • 17.
    Development Techniques  Defensive Programming Assertions everywhere  Design by Contract  Test-Driven Development  Mock Objects A generic unit testing framework that supports TDD better than test stubs Design for Testability
  • 18.
    Design by Contract  Preconditions what must be true when a method is invoked  Postconditions what must be true after a method completes successfully.  Class invariants what must be true about each instance of a class. Design for Testability
  • 19.
    Test-Driven Development  Write tests first, then write the minimal code the makes this test pass  Tests provide the required specification for the developer {A part of the documentation}  Provides rapid feedback for the developer  Emphasizes fast, incremental development  Functionality is added in very small chunks  Ensures 100% thoroughly unit tested code Design for Testability
  • 20.
    Summary  Design Better  Use interfaces  Don’t violate encapsulation  Avoid interdependence and cycles  Class single responsibility  Class open for extension closed for modification  Class substitution (parent is more general than its child)  Add Testability Features  Logging  Assertions  Fault injection hooks  Enhance the Development Process  Design by contract  Test-driven development Design for Testability
  • 21.
    References 1. Bret Pettichord, “Design for Testability” 2. Jeffery E. Payne, Roger T. Alexander, Charles D. Hutchinson, “Design-for-Testability for Object-Oriented Software” 3. Robert Martin, “OO Design Quality Metrics An Analysis of Dependencies” 4. Rahul Tyagi, “Two principles to help create robust, reusable object- oriented design apps” 5. Robert C. Martin, “Design Principles and Design Patterns” 6. Matt Weisfeld, "Object-Oriented Thought Process", Second Edition, Sams Publishing 7. Wikipedia 8. http://www.johndeacon.net/OOAandD/top25GoldenRules.asp 9. http://www.artima.com/weblogs/viewpost.jsp?thread=132358 10. http://labs.cs.utt.ro/labs/ip2/html 11. http://www.mertner.com/confluence/display/MbUnit/Design+Standards Design for Testability
  • 22.
    R&D Dept. Switching Division TestingTeam Thank You Very Much

Editor's Notes

  • #8 Know your tool first An OOP language gives you the tools (like overloading, overriding, virtual functions, static functions, friend functions . . . Etc.)… to support the 4 properties of an object-oriented design which are Data Abstraction Encapsulation Inheritance Polymorphism but it is your responsibility to use them the right way to achieve the design goals of modularity, reusability, maintainability, scalability, (expandability, reliability) ..etc
  • #9 Rigidity صلادة (opposite of coherence تماسك ) A design is rigid if it cannot be easily changed. Such rigidity is due to the fact that a single change to heavily interdependent software begins a cascade of changes in dependent modules. Fragility هشاشة (opposite of design reliability) the tendency of a program to break in many places when a single change is made. Simple changes to one part of the application lead to failures in other parts that appear to be completely unrelated. Fixing those problems leads to even more problems, and the maintenance process begins to resemble a dog chasing its tail. Immobility (opposite of reusability) the inability to reuse software from other projects or from parts of the same project. Viscosity لزوجة is when it is much easier to hack than to preserve original design (When faced with a change, engineers usually find more than one way to make the change.)  Viscosity is resistance to fluid motion
  • #10 Tips:  Superclasses should be abstract . Don&apos;t instantiate superclasses even if you could. Only instantiate leaf-node, concrete classes.  Interfaces are more important than implementation Public method (member function) signatures need more thought, care and attention than they are usually given.  Inherit interface first, and implementation later Focus on type sharing (inheritance of interface) first. **Only use inheritance when primarily sharing type relationships and secondarily sharing implementation. If you want implementation alone, composition is a much better contender.  Polymorphism means that similar objects can respond to the same message in different manners.  Implementation is Extended for specialization only not adding new responsibility [Inheritance is Used for Specialization]
  • #11  violation of the single responsibility principle (the class takes over other class responsibility !) This code is tightly coupled to the implementation of myThing in that it gets the name property, knows that it&apos;s a string, etc. This is a classic approach from the old days or procedural programming. It is NOT OO. Why you operate on data that is not yours? All it should know is how to ask a thing manager to delete a thing given its name ! This reduces Cohesion of the code !
  • #13 OCP: - Be open for extension: module&apos;s behavior can be extended - Be closed for modification: source code for the module must not be changes Modules should be written so they can be extended without requiring them to be modified - A class must not depend on a concrete class! It must depend on an abstract class LSP = Inheritance should ensure that any property proved about supertype objects also holds for subtype objects
  • #14 Consider a simple program which is charged with the task of copying characters typed on a keyboard to a printer. void Copy(){ int c; while ((c = ReadKeyboard()) != EOF) WritePrinter(c); } consider a new program that copies keyboard characters to a disk file: while((c = ReadKeyboard())!= EOF) if(dev == printer) WritePrinter(c); else WriteDisk(c); You modified “Copy” to extend it (??? !!!)  it has to be closed for modification !!
  • #15 Solution of this is to make 2 subtypes of birds (flying_birds and non-flying_birds )
  • #16 Back to the testability definition of {visibility and control} and let’s see how can we achieve this by adding some features to the developed code to support both of visibility and control Assertions increase observability Example of a test point: consider the implementation of write_disk class.., you have to make the file_descriptor variable a member data variable in the class not a local variable; so that the tester can change its value to simulate a disk_full case and see how the system will handle it without making the disk full in reality. Test points are very useful for testing environment variables like temperature, I/O, network connections…etc. and other test cases that need simulating cuz making them happen in reality is very hard.
  • #19 The time of the day class example -invariant of the class: its members 0&lt;=(sec, min)&lt;=60 and 0&lt;=(hours)&lt;=23 -precondition of set_hour(h) method: 0&lt;h&lt;23 -postcondition of set_hour(h) method: hour = h, min,sec unchanged
  • #20 Test-driven development is a method of software development where tests specify interfaces of implementation and all code must have passed the tests.