Published on

  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide


  1. 1. Testing—Part 1 Lecture #13 Software Engineering and Project Management Instructed by Steven Choy on Jan 29, 2007
  2. 2. Software Testing Overview
  3. 3. What’s your view on Testing? <ul><li>Testing is dirty work </li></ul><ul><li>Testing is boring (so, boring tutorial too?) </li></ul><ul><li>Testing is non-technical </li></ul><ul><li>Testing is tedious </li></ul><ul><li>Testing is for those less-talented developers </li></ul>
  4. 4. But the fact is … <ul><li>Testing is a creative, systematic kind of work </li></ul><ul><li>Highly talented people are required to work on testing </li></ul><ul><li>Highly skilled programmers develop innovative test tools and strategies (e.g. JUnit and Test-Driven Development) </li></ul>
  5. 5. What’s our target for Testing? Expected System = Actual System Are the expected behaviour (specified in requirement specification and system models) the same as the observed behaviour of the actual system? ?
  6. 6. So … what qualities do we measure? <ul><li>Correctness </li></ul><ul><li>Reliability </li></ul><ul><li>Robustness </li></ul><ul><li>Security </li></ul><ul><li>Performance </li></ul><ul><li>Usability </li></ul>Non-functional Requirements Functional Requirements
  7. 7. Strategies for Improving Software Qualities <ul><li>Detective Approach (Our Focus) </li></ul><ul><ul><li>Find out the potential bugs and fix it </li></ul></ul><ul><ul><li>Testing & Debugging </li></ul></ul><ul><li>Preventive Approach </li></ul><ul><ul><li>Avoid the bug to come out </li></ul></ul><ul><ul><ul><li>An well-established development methodologies such as design & code review, configuration management </li></ul></ul></ul><ul><ul><ul><li>Use well-practiced design such as design pattern </li></ul></ul></ul><ul><li>Recovery Approach </li></ul><ul><ul><li>Admit it’s impossible to test the system completely that there may be faults in the system </li></ul></ul><ul><ul><li>But even the system fails, it can recover itself at runtime without affecting the user </li></ul></ul>
  8. 8. Test Development Lifecycle
  9. 9. How do you do the Testing?
  10. 10. Test Development Lifecycle Test Planning Unit Test Integration Test Performance Test Acceptance Test Functional Test Alpha Test Installation Test Beta Test Developer Client End User Usability Test
  11. 11. Testing Activities <ul><li>Component Inspection </li></ul><ul><ul><li>Discover fault by code review </li></ul></ul><ul><ul><li>Carried out during design/coding stage </li></ul></ul><ul><li>Test Planning (Plan what to test) </li></ul><ul><ul><li>What features to be tested </li></ul></ul><ul><ul><li>What features not to be tested </li></ul></ul><ul><ul><li>The Test Approach </li></ul></ul><ul><ul><li>The Test Deliverable </li></ul></ul><ul><ul><li>The Test Schedule and Resource Allocation </li></ul></ul><ul><li>Usability Testing </li></ul><ul><ul><li>Test users’ understanding of the system </li></ul></ul><ul><ul><li>Usually performed during product prototype stage by client/end-user </li></ul></ul>
  12. 12. Testing Activities… <ul><li>Unit Testing </li></ul><ul><ul><li>Focus testing on unit level (e.g. object & subsystem) </li></ul></ul><ul><li>Integration Testing </li></ul><ul><ul><li>Perform tests on a group of components/subsystems </li></ul></ul><ul><li>System Testing </li></ul><ul><ul><li>Functional Testing </li></ul></ul><ul><ul><li>Performance Testing </li></ul></ul><ul><ul><li>Pilot Testing </li></ul></ul><ul><ul><li>Acceptance Testing </li></ul></ul>
  13. 13. Tested Subsystem Subsystem Code Functional Integration Unit Tested Subsystem Requirements Analysis Document System Design Document Tested Subsystem Test Test T est Unit T est Unit T est User Manual Requirements Analysis Document Subsystem Code Subsystem Code All tests by developer Functioning System Integrated Subsystems
  14. 14. Global Requirements User’s understanding Tests by developer Performance Acceptance Client’s Understanding of Requirements Test Functioning System Test Installation User Environment Test System in Use Usable System Validated System Accepted System Tests (?) by user Tests by client
  15. 15. Fault Handling Techniques Testing Fault Handling Fault Avoidance Fault Tolerance Fault Detection Debugging Unit Testing Integration Testing System Testing Verification Configuration Management Atomic Transactions Modular Redundancy Correctness Debugging Performance Debugging Reviews Design Methodology
  16. 16. Quality Assurance encompasses Testing Usability Testing Quality Assurance Testing Prototype Testing Scenario Testing Product Testing Fault Avoidance Fault Tolerance Fault Detection Debugging Unit Testing Integration Testing System Testing Verification Configuration Management Atomic Transactions Modular Redundancy Correctness Debugging Performance Debugging Reviews Walkthrough Inspection
  17. 17. Testing Vocabulary <ul><li>Component </li></ul><ul><ul><li>An object, groups of objects or subsystem that can be isolated for testing </li></ul></ul><ul><li>Fault / Bug / Defect </li></ul><ul><ul><li>A design or coding mistake that contributes to the failure of a component </li></ul></ul><ul><li>Failure </li></ul><ul><ul><li>Deviation of the observed behaviour from the specified/expected behaviour </li></ul></ul><ul><li>Test Case </li></ul><ul><ul><li>Detailed instructions (with a set of input data & expected results) on exercising a component with the purpose to detecting faults </li></ul></ul>
  18. 18. Developing Test Case <ul><li>We develop test case to exercise a component with the purpose of causing failures and detecting faults </li></ul><ul><li>A test case normally includes: </li></ul><ul><ul><li>Name </li></ul></ul><ul><ul><li>Component/Feature to be tested </li></ul></ul><ul><ul><li>Detailed test procedures </li></ul></ul><ul><ul><li>Input Data </li></ul></ul><ul><ul><li>Pass/Fail Criteria, Expected Result </li></ul></ul>
  19. 19. Unit Testing
  20. 20. Unit Testing <ul><li>Focus on components (i.e. objects/subsystem) testing, rather than the whole system </li></ul><ul><li>Responsible by developer (usually by the developer who actually write the component) </li></ul><ul><li>Why Unit Testing? </li></ul><ul><ul><li>Reduce complexity of testing </li></ul></ul><ul><ul><li>Ease to locate faults/bugs in a specific component </li></ul></ul><ul><li>Current Development Trend </li></ul><ul><ul><li>Automated Unit Testing e.g. JUnit Framework </li></ul></ul><ul><ul><ul><li>Encourage developers to write test </li></ul></ul></ul><ul><ul><ul><li>Make testing fun! </li></ul></ul></ul>
  21. 21. Test Stubs & Driver <ul><li>Test Stub </li></ul><ul><ul><li>A partial implementation of components on which the tested component depends </li></ul></ul><ul><ul><li>A stub consists of interfaces that are identical to the actual component but with simpler implementation (It can be as simple as a return statement) </li></ul></ul><ul><li>Test Driver </li></ul><ul><ul><li>Simulates the part of the system that controls (drives) the component under test </li></ul></ul><ul><ul><li>Passes in the test inputs to the component under test and displays the result </li></ul></ul>
  22. 22. Test Stub & Driver in Action <ul><li>If you are the developer of the Login component, how do you unit-test it? </li></ul>UI Component Login Component Data Access Component UI Layer Business Layer Database Layer call login() call getPassword()
  23. 23. Example of Login Component <ul><li>class LoginComponent { </li></ul><ul><li>public boolean login(String userId, String password) { </li></ul><ul><li>DataAccessComponent dac = new DataAccessComponent(); </li></ul><ul><li>String originPassword = dac.getPassword(userId); </li></ul><ul><li>if (password.equals(originPassword)) { </li></ul><ul><li>return true; </li></ul><ul><li>} else { </li></ul><ul><li>return false; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  24. 24. Test Driver & Stub Samples <ul><li>class TestDriver { </li></ul><ul><li>public static void main(String[] args) { </li></ul><ul><li>LoginComponent lc = new LoginComponent(); </li></ul><ul><li>boolean result = lc.login(&quot;tester&quot;, &quot;1234&quot;); </li></ul><ul><li>System.out.println(&quot;Login result: &quot; + result); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>class DataAccessComponent { </li></ul><ul><li>public String getPassword(String userId) { </li></ul><ul><li>return &quot;1234&quot;; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  25. 25. Test Stub & Driver in Action <ul><li>We develop a Test Driver to invoke the Login component </li></ul><ul><li>As the Data Access Component is not in place, we develop a Test Stub to emulate the function it provides (Only those functions that Login Component needs during testing) </li></ul>Test Driver Login Component Test Stub UI Layer Business Layer Database Layer call login() call getPassword()
  26. 26. Black-box Testing <ul><li>Test how well the code meets the requirement </li></ul><ul><li>Know nothing about the internal logic of the component/module (Treat it as a Blackbox ) </li></ul><ul><li>Focus on the input/output behaviour </li></ul>Module Feed in input Observe output We focus on: Is the output the same as what we expected?
  27. 27. White-box Testing <ul><li>Performed to reveal the internal structure of a program </li></ul><ul><li>Covers every statement of the component (Each statement is executed once) </li></ul><ul><li>Derive test cases from the code </li></ul><ul><li>Types of white-box testing: </li></ul><ul><ul><li>Statement Testing </li></ul></ul><ul><ul><li>Loop Testing </li></ul></ul><ul><ul><li>Path Testing </li></ul></ul><ul><ul><li>Branch Testing </li></ul></ul>
  28. 28. /*Read in and sum the scores*/ FindMean(float Mean, FILE ScoreFile) { SumOfScores = 0.0; NumberOfScores = 0; Mean = 0; Read(Scor eFile, Score); while (! EOF(ScoreFile) { if ( Score > 0.0 ) { SumOfScores = SumOfScores + Score; NumberOfScores++; } Read(ScoreFile, Score); } /* Compute the mean and print the result */ if (NumberOfScores > 0 ) { Mean = SumOfScores/NumberOfScores; printf(&quot;The mean score is %f &quot;, Mean); } else printf(&quot;No scores found in file &quot;); }
  29. 29. <ul><li>FindMean (FILE ScoreFile) </li></ul><ul><li>{ float SumOfScores = 0.0; </li></ul><ul><ul><li>int NumberOfScores = 0; </li></ul></ul><ul><ul><li>float Mean=0.0; float Score; </li></ul></ul><ul><ul><li>Read(ScoreFile, Score); </li></ul></ul><ul><ul><li>while (! EOF(ScoreFile) { </li></ul></ul><ul><ul><ul><li>if (Score > 0.0 ) { </li></ul></ul></ul><ul><ul><ul><ul><ul><li>SumOfScores = SumOfScores + Score; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>NumberOfScores++; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>} </li></ul></ul></ul></ul></ul><ul><ul><ul><li>Read(ScoreFile, Score); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>/* Compute the mean and print the result */ </li></ul></ul><ul><ul><li>if (NumberOfScores > 0) { </li></ul></ul><ul><ul><ul><ul><li>Mean = SumOfScores / NumberOfScores; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>printf(“ The mean score is %f ”, Mean); </li></ul></ul></ul></ul><ul><ul><li>} else </li></ul></ul><ul><ul><ul><ul><li>printf (“No scores found in file ”); </li></ul></ul></ul></ul><ul><li>} </li></ul>1 2 3 4 5 7 6 8 9
  30. 30. Constructing the Logic Flow Diagram
  31. 31. Finding the Test Cases Start 2 3 4 5 6 7 8 9 Exit 1 b d e g f i j h c k l a (Covered by any data) (Data set must (Data set must contain at least one value) be empty) (Total score > 0.0) (Total score < 0.0) (Positive score) (Negative score) (Reached if either f or e is reached)
  32. 32. Comparison of White & Black-box Testing <ul><li>White-box Testing: </li></ul><ul><ul><li>Potentially infinite number of paths have to be tested </li></ul></ul><ul><ul><li>White-box testing often tests what is done, instead of what should be done </li></ul></ul><ul><ul><li>Cannot detect missing use cases </li></ul></ul><ul><li>Black-box Testing: </li></ul><ul><ul><li>Potential combinatorical explosion of test cases (valid & invalid data) </li></ul></ul><ul><ul><li>Often not clear whether the selected test cases uncover a particular error </li></ul></ul><ul><ul><li>Does not discover extraneous use cases (&quot;features&quot;) </li></ul></ul><ul><li>Both types of testing are needed </li></ul><ul><li>White-box testing and black box testing are the extreme ends of a testing continuum. </li></ul><ul><li>Any choice of test case lies in between and depends on the following: </li></ul><ul><ul><li>Number of possible logical paths </li></ul></ul><ul><ul><li>Nature of input data </li></ul></ul><ul><ul><li>Amount of computation </li></ul></ul><ul><ul><li>Complexity of algorithms and data structures </li></ul></ul>
  33. 33. Integration Testing
  34. 34. Integration Testing <ul><li>Focus on testing groups of components </li></ul><ul><li>Two or more components are integrated for testing. When they are tested okay, more components are added for testing </li></ul><ul><li>Test Strategies: </li></ul><ul><ul><li>Big Bang Testing </li></ul></ul><ul><ul><li>Bottom-up Testing </li></ul></ul><ul><ul><li>Top-down Testing </li></ul></ul>
  35. 35. Integration Test Strategies <ul><li>Big-bang Testing </li></ul><ul><ul><li>After each component are tested individually, all components are then tested together as a single system </li></ul></ul>
  36. 36. Integration Test Strategies <ul><li>Bottom-up Testing </li></ul><ul><ul><li>Designed for layered system </li></ul></ul><ul><ul><li>The bottom layer is tested first, and then integrates with components of the next layer up </li></ul></ul><ul><ul><li>Repeat until all layers are combined and tested </li></ul></ul><ul><ul><li>Test Drivers are needed to do the testing </li></ul></ul><ul><ul><ul><li>A routine that calls a subsystem and passes a test case to it </li></ul></ul></ul>
  37. 37. Integration Test Strategies <ul><li>Top-down Testing </li></ul><ul><ul><li>A reversed of Bottom-up Testing </li></ul></ul><ul><ul><li>The components of top layer is tested first, then integrates with components of the next layer down </li></ul></ul><ul><ul><li>Repeat until all layers are tested </li></ul></ul><ul><ul><li>Test stub is needed to do the testing </li></ul></ul><ul><ul><ul><li>A program or a method that simulates the activity of a missing subsystem by answering to the calling sequence of the calling subsystem and returning back fake data. </li></ul></ul></ul>
  38. 38. Example: Three Layer Call Hierarchy A B C D G F E Layer I Layer II Layer III
  39. 39. Big-Bang Approach Unit Test F Unit Test E Unit Test D Unit Test C Unit Test B Unit Test A System Test
  40. 40. Bottom-up Integration Test F Test E Test G Test C A B C D G F E Layer I Layer II Layer III Test D,G Test B, E, F Test A, B, C, D, E, F, G
  41. 41. Pros and Cons of bottom up integration testing <ul><li>Bad for functionally decomposed systems: </li></ul><ul><ul><li>Tests the most important subsystem (UI) last </li></ul></ul><ul><li>Useful for integrating the following systems </li></ul><ul><ul><li>Object-oriented systems </li></ul></ul><ul><ul><li>real-time systems </li></ul></ul><ul><ul><li>systems with strict performance requirements </li></ul></ul>
  42. 42. Top-down Integration Testing Test A Layer I A B C D G F E Layer I Layer II Layer III Test A, B, C, D Layer I + II Test A, B, C, D, E, F, G All Layers
  43. 43. Pros and Cons of top-down integration testing <ul><li>Test cases can be defined in terms of the functionality of the system (functional requirements) </li></ul><ul><li>Writing stubs can be difficult: Stubs must allow all possible conditions to be tested. </li></ul><ul><li>Possibly a very large number of stubs may be required, especially if the lowest level of the system contains many methods. </li></ul><ul><li>One solution to avoid too many stubs: Modified top-down testing strategy </li></ul><ul><ul><li>Test each layer of the system decomposition individually before merging the layers </li></ul></ul><ul><ul><li>Disadvantage of modified top-down testing: Both, stubs and drivers are needed </li></ul></ul>
  44. 44. Sandwich Testing Strategy <ul><li>Combines top-down strategy with bottom-up strategy </li></ul><ul><li>The system is view as having three layers </li></ul><ul><ul><li>A target layer in the middle </li></ul></ul><ul><ul><li>A layer above the target </li></ul></ul><ul><ul><li>A layer below the target </li></ul></ul><ul><ul><li>Testing converges at the target layer </li></ul></ul><ul><li>How do you select the target layer if there are more than 3 layers? </li></ul><ul><ul><li>Heuristic: Try to minimize the number of stubs and drivers </li></ul></ul>
  45. 45. Sandwich Testing Strategy <ul><li>Test in parallel: </li></ul><ul><ul><li>Middle layer with drivers and stubs </li></ul></ul><ul><ul><li>Top layer with stubs </li></ul></ul><ul><ul><li>Bottom layer with drivers </li></ul></ul><ul><li>Test in parallel: </li></ul><ul><ul><li>Top layer accessing middle layer (top layer replaces drivers) </li></ul></ul><ul><ul><li>Bottom accessed by middle layer (bottom layer replaces stubs) </li></ul></ul>
  46. 46. Modified Sandwich Testing Strategy A B C D G F E Layer I Layer II Layer III Test F Test E Test B Test G Test D Test A Test C Test B, E, F Triple Test I Triple Test I Test D,G Double Test II Double Test II Double Test I Double Test I Test A,C Test A, B, C, D, E, F, G
  47. 47. To be continue… <ul><li>System Testing </li></ul><ul><li>Regression Testing </li></ul><ul><li>Automate Unit Testing </li></ul><ul><li>Document Your Testing </li></ul>
  48. 48. <ul><li>Acknowledgement </li></ul><ul><li>Part of the slides </li></ul><ul><li>were originally authored </li></ul><ul><li>by Simon Ng . </li></ul>