SlideShare a Scribd company logo
1 of 55
presented @




 Factors Relating Field Failures
      and Dependencies
Thomas Zimmermann ● Nachiappan Nagappan ● Kim Herzig
            Rahul Premraj ● Laurie Williams
The Value Of A House
The Value Of A House




 Condition matters!
The Value Of A House




And so does the neighborhood!
What has this to do with
     code quality?
What has this to do with
     code quality?
     Consider software projects as a city
           with classes as houses
What has this to do with
     code quality?
     Consider software projects as a city
           with classes as houses

       The value of a class determined
        by the number of bugs found!
What has this to do with
     code quality?
     Consider software projects as a city
           with classes as houses

       The value of a class determined
        by the number of bugs found!

         How to determine
       the condition of a class?
The Quality Of Source Code

   /**
     * Used by {@link #getThreadInformation()} for a traversal search of
     * {@link Thread}s/{@link ThreadGroup}s
     *
     * @param group
     * @param level
     * @return                                                /**
     */                                                         * Used by {@link #getThreadInformation()} for a traversal search of
   private String visit(final ThreadGroup group,                * {@link Thread}s/{@link ThreadGroup}s
         final int level) {                                     *
       // Get threads in `group' /**                            * @param group
                                                                * @param level
       StringBuilder builder = new StringBuilder(); #getThreadInformation()} for a traversal search of
                                    * Used by {@link
                                                                * @return
       int numThreads = group.activeCount(); Thread}s/{@link ThreadGroup}s
                                    * {@link
       Thread[] threads = new Thread[numThreads * 2];
                                    *                           */
       numThreads = group.enumerate(threads, group
                                    * @param false);          private String visit(final ThreadGroup group,
                                    * @param level                  final int level) {
       StringBuilder indent = new StringBuilder();
                                    * @return                     // Get threads in `group'
       for (int i = 0; i < level; ++i) {
                                    */                            StringBuilder builder = new StringBuilder();
         indent.append(" ");       private String visit(final ThreadGroup group, group.activeCount();
                                                                  int numThreads =
       }                                final int level) {        Thread[] threads = new Thread[numThreads * 2];
                                      // Get threads in `group' numThreads = group.enumerate(threads, false);
       // Enumerate each thread in `group'
                                      StringBuilder builder = new StringBuilder();
       for (int i = 0; i < numThreads; i++) {                     StringBuilder indent = new StringBuilder();
                                      int numThreads = group.activeCount();
         // Get thread                Thread[] threads = new Thread[numThreads * i2]; level; ++i) {
                                                                  for (int i = 0;   <
         Thread thread = threads[i]; numThreads = group.enumerate(threads, false); ");
                                                                    indent.append("
         builder.append(indent);                                  }
         builder.append("|-");        StringBuilder indent = new StringBuilder();
         builder.append(thread.getName()).append(" ["); level; // Enumerate each thread in `group'
                                      for (int i = 0; i <          ++i) {
         builder.append(thread.getClass().getSimpleName()).append("], "); = 0; i < numThreads; i++) {
                                        indent.append(" ");       for (int i
         builder.append(thread.getPriority()).append(", ");
                                      }                             // Get thread
         builder.append(thread.getState().name());                  Thread thread = threads[i];
                                                                    builder.append(indent);
         builder.append(FileUtils.lineSeparator); each thread in `group'
                                      // Enumerate
                                                                    builder.append("|-");
         for (StackTraceElement element : thread.getStackTrace()) { i++) {
                                      for (int i = 0; i < numThreads;
           builder.append(indent);      // Get thread               builder.append(thread.getName()).append(" [");
           builder.append("| ");        Thread thread = threads[i]; builder.append(thread.getClass().getSimpleName()).append("], ");
           builder.append(element.toString());
                                        builder.append(indent);     builder.append(thread.getPriority()).append(", ");
           builder.append(FileUtils.lineSeparator);
                                        builder.append("|-");       builder.append(thread.getState().name());
         }                                                          builder.append(FileUtils.lineSeparator);
                                        builder.append(thread.getName()).append(" [");
         // builder.append(FileUtils.lineSeparator);                for (StackTraceElement element : thread.getStackTrace()) {
                                        builder.append(thread.getClass().getSimpleName()).append("], ");
       }                                                              builder.append(indent);
                                        builder.append(thread.getPriority()).append(", ");
                                                                      builder.append("| ");
                                        builder.append(thread.getState().name());
       // Get thread subgroups of `group'                             builder.append(element.toString());
                                        builder.append(FileUtils.lineSeparator);
       int numGroups = group.activeGroupCount();                      builder.append(FileUtils.lineSeparator);
                                        for (StackTraceElement element : thread.getStackTrace()) {
                                          builder.append(indent); }
       ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       numGroups = group.enumerate(groups, false);
                                          builder.append("| ");     // builder.append(FileUtils.lineSeparator);
                                                                  }
                                          builder.append(element.toString());
       // Recursively visit each subgroup builder.append(FileUtils.lineSeparator);
       for (int i = 0; i < numGroups; i++) {
                                        }                         // Get thread subgroups of `group'
         builder.append(indent);                                  int numGroups = group.activeGroupCount();
                                        // builder.append(FileUtils.lineSeparator);
         builder.append(visit(groups[i], level + 1));
                                      }                           ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       }                                                          numGroups = group.enumerate(groups, false);
                                      // Get thread subgroups of `group'
       return builder.toString();     int numGroups = group.activeGroupCount(); visit each subgroup
                                                                  // Recursively
   }                                  ThreadGroup[] groups = new for (int i = 0; i < numGroups; i++) {
                                                                   ThreadGroup[numGroups * 2];
                                                                    builder.append(indent);
                                      numGroups = group.enumerate(groups, false);
                                                                    builder.append(visit(groups[i], level + 1));
                                                                  }
                                      // Recursively visit each subgroup
                                      for (int i = 0; i < numGroups; i++) {
                                        builder.append(indent); return builder.toString();
                                                              }
                                        builder.append(visit(groups[i], level + 1));
                                      }

                                     return builder.toString();
                                 }




  Code Metrics
The Quality Of Source Code

   /**
     * Used by {@link #getThreadInformation()} for a traversal search of
     * {@link Thread}s/{@link ThreadGroup}s
     *
     * @param group
     * @param level
     * @return                                                /**
     */                                                         * Used by {@link #getThreadInformation()} for a traversal search of
   private String visit(final ThreadGroup group,                * {@link Thread}s/{@link ThreadGroup}s
         final int level) {                                     *
       // Get threads in `group' /**                            * @param group
                                                                * @param level
       StringBuilder builder = new StringBuilder(); #getThreadInformation()} for a traversal search of
                                    * Used by {@link
                                                                * @return
       int numThreads = group.activeCount(); Thread}s/{@link ThreadGroup}s
                                    * {@link
       Thread[] threads = new Thread[numThreads * 2];
                                    *                           */
       numThreads = group.enumerate(threads, group
                                    * @param false);          private String visit(final ThreadGroup group,
                                    * @param level                  final int level) {
       StringBuilder indent = new StringBuilder();
                                    * @return                     // Get threads in `group'
       for (int i = 0; i < level; ++i) {
                                    */                            StringBuilder builder = new StringBuilder();
         indent.append(" ");       private String visit(final ThreadGroup group, group.activeCount();
                                                                  int numThreads =
       }                                final int level) {        Thread[] threads = new Thread[numThreads * 2];
                                      // Get threads in `group' numThreads = group.enumerate(threads, false);
       // Enumerate each thread in `group'
                                      StringBuilder builder = new StringBuilder();
       for (int i = 0; i < numThreads; i++) {                     StringBuilder indent = new StringBuilder();
                                      int numThreads = group.activeCount();
         // Get thread                Thread[] threads = new Thread[numThreads * i2]; level; ++i) {
                                                                  for (int i = 0;   <
         Thread thread = threads[i]; numThreads = group.enumerate(threads, false); ");
                                                                    indent.append("
         builder.append(indent);                                  }
         builder.append("|-");        StringBuilder indent = new StringBuilder();
         builder.append(thread.getName()).append(" ["); level; // Enumerate each thread in `group'
                                      for (int i = 0; i <          ++i) {
         builder.append(thread.getClass().getSimpleName()).append("], "); = 0; i < numThreads; i++) {
                                        indent.append(" ");       for (int i
         builder.append(thread.getPriority()).append(", ");
                                      }                             // Get thread
         builder.append(thread.getState().name());                  Thread thread = threads[i];
                                                                    builder.append(indent);
         builder.append(FileUtils.lineSeparator); each thread in `group'
                                      // Enumerate
                                                                    builder.append("|-");
         for (StackTraceElement element : thread.getStackTrace()) { i++) {
                                      for (int i = 0; i < numThreads;
           builder.append(indent);      // Get thread               builder.append(thread.getName()).append(" [");
           builder.append("| ");        Thread thread = threads[i]; builder.append(thread.getClass().getSimpleName()).append("], ");
           builder.append(element.toString());
                                        builder.append(indent);     builder.append(thread.getPriority()).append(", ");
           builder.append(FileUtils.lineSeparator);
                                        builder.append("|-");       builder.append(thread.getState().name());
         }                                                          builder.append(FileUtils.lineSeparator);
                                        builder.append(thread.getName()).append(" [");
         // builder.append(FileUtils.lineSeparator);                for (StackTraceElement element : thread.getStackTrace()) {
                                        builder.append(thread.getClass().getSimpleName()).append("], ");
       }                                                              builder.append(indent);
                                        builder.append(thread.getPriority()).append(", ");
                                                                      builder.append("| ");
                                        builder.append(thread.getState().name());
       // Get thread subgroups of `group'                             builder.append(element.toString());
                                        builder.append(FileUtils.lineSeparator);
       int numGroups = group.activeGroupCount();                      builder.append(FileUtils.lineSeparator);
                                        for (StackTraceElement element : thread.getStackTrace()) {
                                          builder.append(indent); }
       ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       numGroups = group.enumerate(groups, false);
                                          builder.append("| ");     // builder.append(FileUtils.lineSeparator);
                                                                  }
                                          builder.append(element.toString());
       // Recursively visit each subgroup builder.append(FileUtils.lineSeparator);
       for (int i = 0; i < numGroups; i++) {
                                        }                         // Get thread subgroups of `group'
         builder.append(indent);                                  int numGroups = group.activeGroupCount();
                                        // builder.append(FileUtils.lineSeparator);
         builder.append(visit(groups[i], level + 1));
                                      }                           ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       }                                                          numGroups = group.enumerate(groups, false);
                                      // Get thread subgroups of `group'
       return builder.toString();     int numGroups = group.activeGroupCount(); visit each subgroup
                                                                  // Recursively
   }                                  ThreadGroup[] groups = new for (int i = 0; i < numGroups; i++) {
                                                                   ThreadGroup[numGroups * 2];
                                                                    builder.append(indent);
                                      numGroups = group.enumerate(groups, false);
                                                                    builder.append(visit(groups[i], level + 1));
                                                                  }
                                      // Recursively visit each subgroup
                                      for (int i = 0; i < numGroups; i++) {
                                        builder.append(indent); return builder.toString();
                                                              }
                                        builder.append(visit(groups[i], level + 1));
                                      }

                                     return builder.toString();
                                 }




  Code Metrics                                                                                                                         Neighborhood
Does code neighborhood
 influence code quality?
What We Need

          for each software artifact

•   Determine the value (quality)
•   Determine the neighborhood
•   Determine the condition (metrics)
Quality As Value
We consider failure-proness as a measure of quality.
Quality As Value
     We consider failure-proness as a measure of quality.


                                               12 bugs
•   determine all post-
    release bug                                1 bugs

                                               0 bugs

                                               2 bugs
Quality As Value
     We consider failure-proness as a measure of quality.


                                               12 bugs
•   determine all post-                 FP
    release bug                                1 bugs
                                        FP
•   failure-prone <=> at
                                               0 bugs
    least one post-                    NFP
    release bug
                                               2 bugs
                                        FP
The Neighborhood
Artifacts communicate with each other
      (functions/methods, variables)




                     B
The Neighborhood
Artifacts communicate with each other
      (functions/methods, variables)




                     B


 incoming neighborhood
The Neighborhood
Artifacts communicate with each other
      (functions/methods, variables)




                     B


 incoming neighborhood
 outgoing neighborhood
The Neighborhood
Artifacts communicate with each other
      (functions/methods, variables)




                     B


 incoming neighborhood
 outgoing neighborhood
                            } neighborhood
Code-Metrics As Condition
           Code metrics are useful to predict bugs.
Churn & Size Metrics
   LOC, Churn, Churn Frequency
Code Metrics
                    FanIn, FanOut
         Cyclomatic Complexity
   #methods, inheritance, coupling
Code Coverage
    Block Coverage, Arc Coverage
People Metrics
                 Org. level, #authors
                            and more ...
Code-Metrics As Condition
           Code metrics are useful to predict bugs.
Churn & Size Metrics
   LOC, Churn, Churn Frequency
Code Metrics
                    FanIn, FanOut          B

         Cyclomatic Complexity
   #methods, inheritance, coupling
Code Coverage
    Block Coverage, Arc Coverage
People Metrics
                 Org. level, #authors
                            and more ...
Code-Metrics As Condition
           Code metrics are useful to predict bugs.
Churn & Size Metrics
   LOC, Churn, Churn Frequency                 Compute the
Code Metrics                                    metrics for
                    FanIn, FanOut          B    neighbors
         Cyclomatic Complexity
   #methods, inheritance, coupling
Code Coverage
    Block Coverage, Arc Coverage
People Metrics
                 Org. level, #authors
                            and more ...
Code-Metrics As Condition
           Code metrics are useful to predict bugs.
Churn & Size Metrics
   LOC, Churn, Churn Frequency                  Compute the
Code Metrics                                     metrics for
                    FanIn, FanOut          B     neighbors
         Cyclomatic Complexity
   #methods, inheritance, coupling
Code Coverage                                    Aggregate
    Block Coverage, Arc Coverage                  metrics
People Metrics                                 (med,max,total)
                 Org. level, #authors
                            and more ...
Code-Metrics As Condition
           Code metrics are useful to predict bugs.
Churn & Size Metrics
   LOC, Churn, Churn Frequency                            Compute the
Code Metrics                                               metrics for
                    FanIn, FanOut              B           neighbors
         Cyclomatic Complexity
   #methods, inheritance, coupling
Code Coverage                                              Aggregate
    Block Coverage, Arc Coverage           Assign to B      metrics
People Metrics                                           (med,max,total)
                 Org. level, #authors
                            and more ...
Data Collection

             Quality: FP or NFP



 for each
component
             Neighborhood metrics (aggregated)
Data Collection

               Quality: FP or NFP

                 Is there a relation between
            quality and neighborhood condition?
 for each
component
               Neighborhood metrics (aggregated)
Experimental Setup

  FP
  NFP
  FP
  NFP
  FP
Experimental Setup
        m = churn_median

  FP
  NFP
  FP
  NFP
  FP
Experimental Setup
        m = churn_median
          FP      NFP
  FP
  NFP
  FP
  NFP
  FP
Experimental Setup
        m = churn_median
          FP      NFP
  FP      400
  NFP             330
  FP      450
  NFP             405
  FP      500
Experimental Setup
         m = churn_median
           FP      NFP
   FP      400
   NFP              330
   FP      450
   NFP              405
   FP      500


  Are the values in FP significantly
greater/lower that values in NFP?
Projects
Projects




functional & object oriented         object oriented
  metrics on binary level         metrics on class level
            slightly different set of metrics
Projects




functional & object oriented         object oriented
  metrics on binary level         metrics on class level
            slightly different set of metrics
Projects




functional & object oriented         object oriented
  metrics on binary level         metrics on class level
            slightly different set of metrics
Survey


  We asked 700 Microsoft developers
      to share their opinion on:
How do dependency characteristics
  influence the risk of failures?
Survey

         110 responded (15.7%)
  We asked 700 Microsoft developers
      to share their opinion on:
How do dependency characteristics
  influence the risk of failures?
Survey
              Binary has a dependency with another that ...
     11%
6%




                       83%
     churned a lot

           No Effect           Increases      Decreases   No Opinion
                             risk of failure of binary
Survey
              Binary has a dependency with another that ...
                                           1%
     11%
                                 18%
6%
                              4%


                       83%                         77%

     churned a lot                   has high test
                                      coverage
           No Effect           Increases        Decreases   No Opinion
                             risk of failure of binary
Survey
              Binary has a dependency with another that ...
                                           1%
     11%                                                       2%
                                 18%
6%                                                           6%
                                                            1%
                              4%


                                                   77%                           91%
                       83%
     churned a lot                   has high test          failed many times in
                                      coverage                     the past
           No Effect           Increases        Decreases           No Opinion
                             risk of failure of binary
Results Vista

          indicates medians for
           FP are significantly
         lower than for NFP


         indicates medians for
          FP are significantly
        higher than for NFP
Results Vista
  Survey
Results Vista
  Survey
             Developers were right! High
           degree of churn increases failure-
                       proness.
Results Vista
  Survey




           Code coverage does not matter!
Results Vista
  Survey




           Many users requires better
                    testing!
Results Vista
  Survey




           Depending on bad code does not
                       harm!
Results Eclipse
                  Survey
Results Eclipse
                  Survey



                      as expected!
Results Eclipse
                  Survey




                     depending on
                     components
                      with fewer
                       interfaces
                        more bugs
Results Eclipse
Results between Vista and EclipseSurvey a lot!
                                  differ




                                     depending on
                                     components
                                      with fewer
                                       interfaces
                                        more bugs
Contradictions!
                   Vista        Eclipse       Survey

     churn

  complexity

   coverage                       n/a
  post-release
    failures


Contradiction raises questions regarding the relationship
       between dependencies and code quality!
Factors Relating Field Failures and Dependencies - ICST 2011
Factors Relating Field Failures and Dependencies - ICST 2011
Factors Relating Field Failures and Dependencies - ICST 2011
Factors Relating Field Failures and Dependencies - ICST 2011

More Related Content

More from Kim Herzig

Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
Kim Herzig
 
Code Ownership and Software Quality: A Replication Study @ MSR 2015
Code Ownership and Software Quality: A Replication Study @ MSR 2015Code Ownership and Software Quality: A Replication Study @ MSR 2015
Code Ownership and Software Quality: A Replication Study @ MSR 2015
Kim Herzig
 
The Impact of Test Ownership and Team Structure on the Reliability and Effect...
The Impact of Test Ownership and Team Structure on the Reliability and Effect...The Impact of Test Ownership and Team Structure on the Reliability and Effect...
The Impact of Test Ownership and Team Structure on the Reliability and Effect...
Kim Herzig
 
Predicting Defects Using Change Genealogies (ISSE 2013)
Predicting Defects Using Change Genealogies (ISSE 2013)Predicting Defects Using Change Genealogies (ISSE 2013)
Predicting Defects Using Change Genealogies (ISSE 2013)
Kim Herzig
 
Mining and Untangling Change Genealogies (PhD Defense Talk)
Mining and Untangling Change Genealogies (PhD Defense Talk)Mining and Untangling Change Genealogies (PhD Defense Talk)
Mining and Untangling Change Genealogies (PhD Defense Talk)
Kim Herzig
 
The Impact of Tangled Code Changes
The Impact of Tangled Code ChangesThe Impact of Tangled Code Changes
The Impact of Tangled Code Changes
Kim Herzig
 
Network vs. Code Metrics to Predict Defects: A Replication Study
Network vs. Code Metrics  to Predict Defects: A Replication StudyNetwork vs. Code Metrics  to Predict Defects: A Replication Study
Network vs. Code Metrics to Predict Defects: A Replication Study
Kim Herzig
 
Software Engineering Course 2009 - Mining Software Archives
Software Engineering Course 2009 - Mining Software ArchivesSoftware Engineering Course 2009 - Mining Software Archives
Software Engineering Course 2009 - Mining Software Archives
Kim Herzig
 

More from Kim Herzig (13)

Keynote AST 2016
Keynote AST 2016Keynote AST 2016
Keynote AST 2016
 
Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
Empirically Detecting False Test Alarms Using Association Rules @ ICSE 2015
 
The Art of Testing Less without Sacrificing Quality @ ICSE 2015
The Art of Testing Less without Sacrificing Quality @ ICSE 2015The Art of Testing Less without Sacrificing Quality @ ICSE 2015
The Art of Testing Less without Sacrificing Quality @ ICSE 2015
 
Code Ownership and Software Quality: A Replication Study @ MSR 2015
Code Ownership and Software Quality: A Replication Study @ MSR 2015Code Ownership and Software Quality: A Replication Study @ MSR 2015
Code Ownership and Software Quality: A Replication Study @ MSR 2015
 
Issre2014 test defectprediction
Issre2014 test defectpredictionIssre2014 test defectprediction
Issre2014 test defectprediction
 
The Impact of Test Ownership and Team Structure on the Reliability and Effect...
The Impact of Test Ownership and Team Structure on the Reliability and Effect...The Impact of Test Ownership and Team Structure on the Reliability and Effect...
The Impact of Test Ownership and Team Structure on the Reliability and Effect...
 
Predicting Defects Using Change Genealogies (ISSE 2013)
Predicting Defects Using Change Genealogies (ISSE 2013)Predicting Defects Using Change Genealogies (ISSE 2013)
Predicting Defects Using Change Genealogies (ISSE 2013)
 
Mining and Untangling Change Genealogies (PhD Defense Talk)
Mining and Untangling Change Genealogies (PhD Defense Talk)Mining and Untangling Change Genealogies (PhD Defense Talk)
Mining and Untangling Change Genealogies (PhD Defense Talk)
 
The Impact of Tangled Code Changes
The Impact of Tangled Code ChangesThe Impact of Tangled Code Changes
The Impact of Tangled Code Changes
 
Mining Cause Effect Chains from Version Archives - ISSRE 2011
Mining Cause Effect Chains from Version Archives - ISSRE 2011Mining Cause Effect Chains from Version Archives - ISSRE 2011
Mining Cause Effect Chains from Version Archives - ISSRE 2011
 
Network vs. Code Metrics to Predict Defects: A Replication Study
Network vs. Code Metrics  to Predict Defects: A Replication StudyNetwork vs. Code Metrics  to Predict Defects: A Replication Study
Network vs. Code Metrics to Predict Defects: A Replication Study
 
Capturing the Long Term Impact of Changes
Capturing the Long Term Impact of ChangesCapturing the Long Term Impact of Changes
Capturing the Long Term Impact of Changes
 
Software Engineering Course 2009 - Mining Software Archives
Software Engineering Course 2009 - Mining Software ArchivesSoftware Engineering Course 2009 - Mining Software Archives
Software Engineering Course 2009 - Mining Software Archives
 

Recently uploaded

Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Peter Udo Diehl
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Recently uploaded (20)

UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
THE BEST IPTV in GERMANY for 2024: IPTVreel
THE BEST IPTV in  GERMANY for 2024: IPTVreelTHE BEST IPTV in  GERMANY for 2024: IPTVreel
THE BEST IPTV in GERMANY for 2024: IPTVreel
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, Ocado
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAK
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 

Factors Relating Field Failures and Dependencies - ICST 2011

  • 1. presented @ Factors Relating Field Failures and Dependencies Thomas Zimmermann ● Nachiappan Nagappan ● Kim Herzig Rahul Premraj ● Laurie Williams
  • 2. The Value Of A House
  • 3. The Value Of A House Condition matters!
  • 4. The Value Of A House And so does the neighborhood!
  • 5. What has this to do with code quality?
  • 6. What has this to do with code quality? Consider software projects as a city with classes as houses
  • 7. What has this to do with code quality? Consider software projects as a city with classes as houses The value of a class determined by the number of bugs found!
  • 8. What has this to do with code quality? Consider software projects as a city with classes as houses The value of a class determined by the number of bugs found! How to determine the condition of a class?
  • 9. The Quality Of Source Code /** * Used by {@link #getThreadInformation()} for a traversal search of * {@link Thread}s/{@link ThreadGroup}s * * @param group * @param level * @return /** */ * Used by {@link #getThreadInformation()} for a traversal search of private String visit(final ThreadGroup group, * {@link Thread}s/{@link ThreadGroup}s final int level) { * // Get threads in `group' /** * @param group * @param level StringBuilder builder = new StringBuilder(); #getThreadInformation()} for a traversal search of * Used by {@link * @return int numThreads = group.activeCount(); Thread}s/{@link ThreadGroup}s * {@link Thread[] threads = new Thread[numThreads * 2]; * */ numThreads = group.enumerate(threads, group * @param false); private String visit(final ThreadGroup group, * @param level final int level) { StringBuilder indent = new StringBuilder(); * @return // Get threads in `group' for (int i = 0; i < level; ++i) { */ StringBuilder builder = new StringBuilder(); indent.append(" "); private String visit(final ThreadGroup group, group.activeCount(); int numThreads = } final int level) { Thread[] threads = new Thread[numThreads * 2]; // Get threads in `group' numThreads = group.enumerate(threads, false); // Enumerate each thread in `group' StringBuilder builder = new StringBuilder(); for (int i = 0; i < numThreads; i++) { StringBuilder indent = new StringBuilder(); int numThreads = group.activeCount(); // Get thread Thread[] threads = new Thread[numThreads * i2]; level; ++i) { for (int i = 0; < Thread thread = threads[i]; numThreads = group.enumerate(threads, false); "); indent.append(" builder.append(indent); } builder.append("|-"); StringBuilder indent = new StringBuilder(); builder.append(thread.getName()).append(" ["); level; // Enumerate each thread in `group' for (int i = 0; i < ++i) { builder.append(thread.getClass().getSimpleName()).append("], "); = 0; i < numThreads; i++) { indent.append(" "); for (int i builder.append(thread.getPriority()).append(", "); } // Get thread builder.append(thread.getState().name()); Thread thread = threads[i]; builder.append(indent); builder.append(FileUtils.lineSeparator); each thread in `group' // Enumerate builder.append("|-"); for (StackTraceElement element : thread.getStackTrace()) { i++) { for (int i = 0; i < numThreads; builder.append(indent); // Get thread builder.append(thread.getName()).append(" ["); builder.append("| "); Thread thread = threads[i]; builder.append(thread.getClass().getSimpleName()).append("], "); builder.append(element.toString()); builder.append(indent); builder.append(thread.getPriority()).append(", "); builder.append(FileUtils.lineSeparator); builder.append("|-"); builder.append(thread.getState().name()); } builder.append(FileUtils.lineSeparator); builder.append(thread.getName()).append(" ["); // builder.append(FileUtils.lineSeparator); for (StackTraceElement element : thread.getStackTrace()) { builder.append(thread.getClass().getSimpleName()).append("], "); } builder.append(indent); builder.append(thread.getPriority()).append(", "); builder.append("| "); builder.append(thread.getState().name()); // Get thread subgroups of `group' builder.append(element.toString()); builder.append(FileUtils.lineSeparator); int numGroups = group.activeGroupCount(); builder.append(FileUtils.lineSeparator); for (StackTraceElement element : thread.getStackTrace()) { builder.append(indent); } ThreadGroup[] groups = new ThreadGroup[numGroups * 2]; numGroups = group.enumerate(groups, false); builder.append("| "); // builder.append(FileUtils.lineSeparator); } builder.append(element.toString()); // Recursively visit each subgroup builder.append(FileUtils.lineSeparator); for (int i = 0; i < numGroups; i++) { } // Get thread subgroups of `group' builder.append(indent); int numGroups = group.activeGroupCount(); // builder.append(FileUtils.lineSeparator); builder.append(visit(groups[i], level + 1)); } ThreadGroup[] groups = new ThreadGroup[numGroups * 2]; } numGroups = group.enumerate(groups, false); // Get thread subgroups of `group' return builder.toString(); int numGroups = group.activeGroupCount(); visit each subgroup // Recursively } ThreadGroup[] groups = new for (int i = 0; i < numGroups; i++) { ThreadGroup[numGroups * 2]; builder.append(indent); numGroups = group.enumerate(groups, false); builder.append(visit(groups[i], level + 1)); } // Recursively visit each subgroup for (int i = 0; i < numGroups; i++) { builder.append(indent); return builder.toString(); } builder.append(visit(groups[i], level + 1)); } return builder.toString(); } Code Metrics
  • 10. The Quality Of Source Code /** * Used by {@link #getThreadInformation()} for a traversal search of * {@link Thread}s/{@link ThreadGroup}s * * @param group * @param level * @return /** */ * Used by {@link #getThreadInformation()} for a traversal search of private String visit(final ThreadGroup group, * {@link Thread}s/{@link ThreadGroup}s final int level) { * // Get threads in `group' /** * @param group * @param level StringBuilder builder = new StringBuilder(); #getThreadInformation()} for a traversal search of * Used by {@link * @return int numThreads = group.activeCount(); Thread}s/{@link ThreadGroup}s * {@link Thread[] threads = new Thread[numThreads * 2]; * */ numThreads = group.enumerate(threads, group * @param false); private String visit(final ThreadGroup group, * @param level final int level) { StringBuilder indent = new StringBuilder(); * @return // Get threads in `group' for (int i = 0; i < level; ++i) { */ StringBuilder builder = new StringBuilder(); indent.append(" "); private String visit(final ThreadGroup group, group.activeCount(); int numThreads = } final int level) { Thread[] threads = new Thread[numThreads * 2]; // Get threads in `group' numThreads = group.enumerate(threads, false); // Enumerate each thread in `group' StringBuilder builder = new StringBuilder(); for (int i = 0; i < numThreads; i++) { StringBuilder indent = new StringBuilder(); int numThreads = group.activeCount(); // Get thread Thread[] threads = new Thread[numThreads * i2]; level; ++i) { for (int i = 0; < Thread thread = threads[i]; numThreads = group.enumerate(threads, false); "); indent.append(" builder.append(indent); } builder.append("|-"); StringBuilder indent = new StringBuilder(); builder.append(thread.getName()).append(" ["); level; // Enumerate each thread in `group' for (int i = 0; i < ++i) { builder.append(thread.getClass().getSimpleName()).append("], "); = 0; i < numThreads; i++) { indent.append(" "); for (int i builder.append(thread.getPriority()).append(", "); } // Get thread builder.append(thread.getState().name()); Thread thread = threads[i]; builder.append(indent); builder.append(FileUtils.lineSeparator); each thread in `group' // Enumerate builder.append("|-"); for (StackTraceElement element : thread.getStackTrace()) { i++) { for (int i = 0; i < numThreads; builder.append(indent); // Get thread builder.append(thread.getName()).append(" ["); builder.append("| "); Thread thread = threads[i]; builder.append(thread.getClass().getSimpleName()).append("], "); builder.append(element.toString()); builder.append(indent); builder.append(thread.getPriority()).append(", "); builder.append(FileUtils.lineSeparator); builder.append("|-"); builder.append(thread.getState().name()); } builder.append(FileUtils.lineSeparator); builder.append(thread.getName()).append(" ["); // builder.append(FileUtils.lineSeparator); for (StackTraceElement element : thread.getStackTrace()) { builder.append(thread.getClass().getSimpleName()).append("], "); } builder.append(indent); builder.append(thread.getPriority()).append(", "); builder.append("| "); builder.append(thread.getState().name()); // Get thread subgroups of `group' builder.append(element.toString()); builder.append(FileUtils.lineSeparator); int numGroups = group.activeGroupCount(); builder.append(FileUtils.lineSeparator); for (StackTraceElement element : thread.getStackTrace()) { builder.append(indent); } ThreadGroup[] groups = new ThreadGroup[numGroups * 2]; numGroups = group.enumerate(groups, false); builder.append("| "); // builder.append(FileUtils.lineSeparator); } builder.append(element.toString()); // Recursively visit each subgroup builder.append(FileUtils.lineSeparator); for (int i = 0; i < numGroups; i++) { } // Get thread subgroups of `group' builder.append(indent); int numGroups = group.activeGroupCount(); // builder.append(FileUtils.lineSeparator); builder.append(visit(groups[i], level + 1)); } ThreadGroup[] groups = new ThreadGroup[numGroups * 2]; } numGroups = group.enumerate(groups, false); // Get thread subgroups of `group' return builder.toString(); int numGroups = group.activeGroupCount(); visit each subgroup // Recursively } ThreadGroup[] groups = new for (int i = 0; i < numGroups; i++) { ThreadGroup[numGroups * 2]; builder.append(indent); numGroups = group.enumerate(groups, false); builder.append(visit(groups[i], level + 1)); } // Recursively visit each subgroup for (int i = 0; i < numGroups; i++) { builder.append(indent); return builder.toString(); } builder.append(visit(groups[i], level + 1)); } return builder.toString(); } Code Metrics Neighborhood
  • 11. Does code neighborhood influence code quality?
  • 12. What We Need for each software artifact • Determine the value (quality) • Determine the neighborhood • Determine the condition (metrics)
  • 13. Quality As Value We consider failure-proness as a measure of quality.
  • 14. Quality As Value We consider failure-proness as a measure of quality. 12 bugs • determine all post- release bug 1 bugs 0 bugs 2 bugs
  • 15. Quality As Value We consider failure-proness as a measure of quality. 12 bugs • determine all post- FP release bug 1 bugs FP • failure-prone <=> at 0 bugs least one post- NFP release bug 2 bugs FP
  • 16. The Neighborhood Artifacts communicate with each other (functions/methods, variables) B
  • 17. The Neighborhood Artifacts communicate with each other (functions/methods, variables) B incoming neighborhood
  • 18. The Neighborhood Artifacts communicate with each other (functions/methods, variables) B incoming neighborhood outgoing neighborhood
  • 19. The Neighborhood Artifacts communicate with each other (functions/methods, variables) B incoming neighborhood outgoing neighborhood } neighborhood
  • 20. Code-Metrics As Condition Code metrics are useful to predict bugs. Churn & Size Metrics LOC, Churn, Churn Frequency Code Metrics FanIn, FanOut Cyclomatic Complexity #methods, inheritance, coupling Code Coverage Block Coverage, Arc Coverage People Metrics Org. level, #authors and more ...
  • 21. Code-Metrics As Condition Code metrics are useful to predict bugs. Churn & Size Metrics LOC, Churn, Churn Frequency Code Metrics FanIn, FanOut B Cyclomatic Complexity #methods, inheritance, coupling Code Coverage Block Coverage, Arc Coverage People Metrics Org. level, #authors and more ...
  • 22. Code-Metrics As Condition Code metrics are useful to predict bugs. Churn & Size Metrics LOC, Churn, Churn Frequency Compute the Code Metrics metrics for FanIn, FanOut B neighbors Cyclomatic Complexity #methods, inheritance, coupling Code Coverage Block Coverage, Arc Coverage People Metrics Org. level, #authors and more ...
  • 23. Code-Metrics As Condition Code metrics are useful to predict bugs. Churn & Size Metrics LOC, Churn, Churn Frequency Compute the Code Metrics metrics for FanIn, FanOut B neighbors Cyclomatic Complexity #methods, inheritance, coupling Code Coverage Aggregate Block Coverage, Arc Coverage metrics People Metrics (med,max,total) Org. level, #authors and more ...
  • 24. Code-Metrics As Condition Code metrics are useful to predict bugs. Churn & Size Metrics LOC, Churn, Churn Frequency Compute the Code Metrics metrics for FanIn, FanOut B neighbors Cyclomatic Complexity #methods, inheritance, coupling Code Coverage Aggregate Block Coverage, Arc Coverage Assign to B metrics People Metrics (med,max,total) Org. level, #authors and more ...
  • 25. Data Collection Quality: FP or NFP for each component Neighborhood metrics (aggregated)
  • 26. Data Collection Quality: FP or NFP Is there a relation between quality and neighborhood condition? for each component Neighborhood metrics (aggregated)
  • 27. Experimental Setup FP NFP FP NFP FP
  • 28. Experimental Setup m = churn_median FP NFP FP NFP FP
  • 29. Experimental Setup m = churn_median FP NFP FP NFP FP NFP FP
  • 30. Experimental Setup m = churn_median FP NFP FP 400 NFP 330 FP 450 NFP 405 FP 500
  • 31. Experimental Setup m = churn_median FP NFP FP 400 NFP 330 FP 450 NFP 405 FP 500 Are the values in FP significantly greater/lower that values in NFP?
  • 33. Projects functional & object oriented object oriented metrics on binary level metrics on class level slightly different set of metrics
  • 34. Projects functional & object oriented object oriented metrics on binary level metrics on class level slightly different set of metrics
  • 35. Projects functional & object oriented object oriented metrics on binary level metrics on class level slightly different set of metrics
  • 36. Survey We asked 700 Microsoft developers to share their opinion on: How do dependency characteristics influence the risk of failures?
  • 37. Survey 110 responded (15.7%) We asked 700 Microsoft developers to share their opinion on: How do dependency characteristics influence the risk of failures?
  • 38. Survey Binary has a dependency with another that ... 11% 6% 83% churned a lot No Effect Increases Decreases No Opinion risk of failure of binary
  • 39. Survey Binary has a dependency with another that ... 1% 11% 18% 6% 4% 83% 77% churned a lot has high test coverage No Effect Increases Decreases No Opinion risk of failure of binary
  • 40. Survey Binary has a dependency with another that ... 1% 11% 2% 18% 6% 6% 1% 4% 77% 91% 83% churned a lot has high test failed many times in coverage the past No Effect Increases Decreases No Opinion risk of failure of binary
  • 41. Results Vista indicates medians for FP are significantly lower than for NFP indicates medians for FP are significantly higher than for NFP
  • 42. Results Vista Survey
  • 43. Results Vista Survey Developers were right! High degree of churn increases failure- proness.
  • 44. Results Vista Survey Code coverage does not matter!
  • 45. Results Vista Survey Many users requires better testing!
  • 46. Results Vista Survey Depending on bad code does not harm!
  • 47. Results Eclipse Survey
  • 48. Results Eclipse Survey as expected!
  • 49. Results Eclipse Survey depending on components with fewer interfaces more bugs
  • 50. Results Eclipse Results between Vista and EclipseSurvey a lot! differ depending on components with fewer interfaces more bugs
  • 51. Contradictions! Vista Eclipse Survey churn complexity coverage n/a post-release failures Contradiction raises questions regarding the relationship between dependencies and code quality!

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. [stat] Mann Whitney-U test with the signi&amp;#xFB01;cance level was set to .05\n[stat] the Bonferroni correction is more conservative\n(less likely to reject null hypotheses) and thus less likely to\naccidentally accept incorrect result\n[metrics] 44 on Vista, 252 on Eclipse\n
  110. [stat] Mann Whitney-U test with the signi&amp;#xFB01;cance level was set to .05\n[stat] the Bonferroni correction is more conservative\n(less likely to reject null hypotheses) and thus less likely to\naccidentally accept incorrect result\n[metrics] 44 on Vista, 252 on Eclipse\n
  111. [stat] Mann Whitney-U test with the signi&amp;#xFB01;cance level was set to .05\n[stat] the Bonferroni correction is more conservative\n(less likely to reject null hypotheses) and thus less likely to\naccidentally accept incorrect result\n[metrics] 44 on Vista, 252 on Eclipse\n