Software Testing Illustration

Advanced Software Testing

Explore risk-based testing, structure-based testing, analytical techniques, and dynamic analysis for software quality improvement.

Advanced Software Testing Book

Risk-Based Testing

Risk-based testing is a test strategy that prioritizes test cases based on the likelihood and impact of potential failures.

  • More focus should be given to areas with high risk.
  • Resources should be appropriately allocated.

Where Does Risk Come From?

  • Complex features
  • Frequently used features
  • Past defect history

How to Assess Risk?

  • Based on likelihood and impact
  • Create a Likelihood-Impact Matrix
  • Risk Matrix:
Likelihood →Low ImpactMedium ImpactHigh Impact
LowLowLowMedium
MediumLowMediumHigh
HighMediumHighCritical

Testing Strategy Based on Risk Level

  • High Risk → Extensive testing (functional, edge cases, performance, security).
  • Medium Risk → Moderate testing (positive and negative test cases).
  • Low Risk → Minimal testing (smoke and sanity checks).

Pragmatic Risk-Based Testing

  • Use scoring:
    • Low = 1
    • Medium = 2
    • High = 3
  • Risk Score = Impact Score × Likelihood Score

How to Determine Likelihood Score?

  • Recent code changes
  • History of defects
  • Code complexity (Git changes)
  • Usage frequency
  • Integration with third-party tools
  • Security vulnerabilities

Tools for Risk Assessment

  • SonarQube, Pylint

Structure-Based Testing

Structure-based testing is a white-box testing strategy where test cases are defined based on the internal structure of the code rather than just relying on external behavior.

Why Structure-Based Testing?

  • Helps uncover defects not found in black-box testing.
  • Identifies dead code (unused or unreachable code).
  • Detects missing conditions and logical errors.
  • Ensures better test coverage.

Types of Structure-Based Testing

  1. Statement Coverage – Ensures all statements in the code are executed.
  2. Branch Coverage – Ensures all decision branches are executed.
  3. Path Coverage – Ensures all execution paths are tested.
    • Use flow graphs to determine possible paths.
    • Design test cases for each path.
    • Cyclomatic Complexity – Measures the number of independent paths in a program.
  4. Loop Coverage – Ensures loops are tested with:
    • 0 iterations (loop not executed)
    • 1 iteration (loop executed once)
    • Multiple iterations

Tools for Code Coverage Measurement

  • SonarQube, Pylint

Automation Strategy

  • Automate all unit test cases.

Selecting the Right Structure-Based Coverage

System ComplexityRecommended Coverage
Simple SystemStatement Coverage is sufficient
Complex SystemPath Coverage is required

Analytical Techniques

Analytical techniques involve analyzing code to improve quality and detect defects early.

Static Analysis

In static analysis, code is examined without executing it. It helps identify issues related to structure, control flow, and data flow.

1. Control Flow Analysis

  • Uses control flow graphs to identify:
    • Unreachable code
    • Infinite loops
    • Paths that are not tested

2. Data Flow Analysis

  • Tracks variable value changes throughout the program.
  • Helps detect:
    • Uninitialized variables
    • Unused variables
    • Incorrect assignments

3. Call Graph Analysis

  • Constructs a graph of function calls within the program.
  • Helps detect:
    • Excessive dependencies
    • Low modularity
    • Used in integration testing

Dynamic Analysis

Dynamic analysis involves executing the program to detect runtime issues such as crashes, memory leaks, and pointer-related errors.

1. Memory Leaks

  • Occurs when memory is allocated but not freed.
  • Leads to:
    • Performance degradation
    • Crashes due to high memory consumption

2. Wild Pointers

  • A wild pointer is an uninitialized pointer.
  • Can cause segmentation faults and crashes.