/
Reopened Defects

Reopened Defects

Purpose

Reopened Defects by Month shows a percentage of re-opened defects in comparison to all created defects in that month.

How metric helps

Reopened Defects by Month helps to reveal a lack of resources to maintain a required deliverable quality, e.g. insufficient unit testing. The higher this value - the worse a quality of defect fixes is.

The metric is often a leading indicator (as opposed to a lagging indicator). This means it can be used to foresee problems before they become overwhelming and undermine confidence in both the product and project team.

Metric:

  • shows a percentage of re-opened defects in comparison to all created defects in the same period

  • shows how many defects have been re-opened at least once

  • shows how many defects were not accepted by Testers and thus returned back to work to Developers

  • shows quality of development work, i.e. first time right 

  • shows whether engineering quality practices (EngX) are in place (e.g. quality gates in CI/CD, unit testing)

How metric works

Chart overview

Chart displays a percentage of reopened defects (Y axis) over months (Y axis).

Legend within a chart shows the Reopened Defects for the last month as well as a difference with the previous month.   

By hover over a column a hint appears showing a percentage of reopened defects in a particular month.           

By click on a column a pop-up appears with the following information from the defect tracking system:

  • Issue ID

  • Type

  • Priority

  • Summary

Top problems metric identifies 

  1. Technical and Quality Debt is out of control

  2. Team misbalance (skills ratio) 

  3. There is no Test Plan and/or Strategy

  4. Poor requirements provisioning process (not defined or/and agreed upon expected behavior)

Other

  • Issues with build creation, i.e. fixes are not included into the latest version

  • Not reproducible issues on development side (locally), so blind fixes are applied 

  • Limits in physical devices or/and OS configuration in development team, so no way to check on issue resolution locally 

  • Not resolved merge conflicts when pushing to the main branch used for testing, i.e. fixes become overwritten 

  • Bug reports are of poor quality or targeted on the wrong things 

Calculation 

RD = Nrdef/(Ndef + Nrdef)* 100%,

where

Nrdef - number of reopened defects in a considered month. Reopened defect is a defect that leaves the ‘In Progress’/'Done' bucket at least once after it gets into it. Repeatedly reopened defects are always counted as one reopened defect.

Ndef - number of defects in a ‘In Progress’/'Done' status for a considered month. ‘In Progress’/'Done' statuses are the statuses from the ‘In Progress’/'Done' column in Project settings>Task Tracking system>Workflows.

RAG thresholds: no.

Calculation notes

Any backward transition of an issue among buckets is considered as it is reopened: 

  • from Done to In Progress

  • from In Progress to To Do

  • from Done to To Do

2 If an item is completed and then reopened in the same month it is included only into reopened defects.

PerfQL

WITH month_series AS ( SELECT date_trunc('month', generate_series) AS month FROM generate_series( date_trunc('month', current_date) - interval '5 months', date_trunc('month', current_date), '1 month'::interval ) ), tickets_to_process AS ( SELECT key FROM ticket WHERE is_defect(id) ), snapshots_temp AS ( SELECT lag(is_done(s), 1) over (partition by key order by snapshot_created) as prev_is_done, lag(is_in_progress(s), 1) over (partition by key order by snapshot_created) as prev_is_in_progress, lag(status, 1) over (partition by key order by snapshot_created) as prev_status, is_to_do(s) as is_todo, is_in_progress(s) as is_in_progress, is_done(s) as is_done, snapshot_created, status, key FROM ticket_snapshots((SELECT array_agg(key) FROM tickets_to_process )) s ), snapshots AS ( SELECT * FROM snapshots_temp WHERE status != prev_status ), reopened_defects AS ( SELECT distinct s.key, date_trunc('month', snapshot_created) as month FROM snapshots s WHERE (prev_is_done = true and is_todo = true) OR (prev_is_done = true and is_in_progress = true) OR (prev_is_in_progress = true and is_todo = true) ), done_defects AS ( SELECT distinct s.key, date_trunc('month', snapshot_created) as month FROM snapshots s WHERE is_done = true AND not exists ( SELECT 1 FROM reopened_defects d WHERE s.key = d.key and d.month = date_trunc('month', s.snapshot_created) ) ), done_defects_counted AS ( SELECT month, count(distinct key) as done_defects_count FROM done_defects GROUP BY month ORDER BY month ), reopened_defects_counted AS ( SELECT month, count(distinct key) as reopened_defects_count FROM reopened_defects GROUP BY month ) SELECT to_char(ms.month, 'yyyy mon') as month, CASE WHEN dc.done_defects_count + rdc.reopened_defects_count = 0 THEN 0 ELSE round(((rdc.reopened_defects_count::float /( dc.done_defects_count + rdc.reopened_defects_count)::float) * 100)::numeric, 0) END as "reopened defects ratio" FROM month_series ms LEFT JOIN done_defects_counted dc ON ms.month = dc.month LEFT JOIN reopened_defects_counted rdc ON ms.month = rdc.month ORDER BY ms.month;

--------DRILL DOWN---------

select '[' || t.key || '](' || t.url || ')' as "issue id", t.type as "type", t.priority as "priority", t.summary as "summary" from reopened_defects rd inner join ticket t on t.key = rd.key where to_char(month, 'yyyy mon') = clicked_x_value order by (regexp_matches(t.key,'\d+'))[1]::bigint;

Data Source

Data for the metric can be collected from a task tracking system (Jira, TFS, Rally, etc.).

Related content

Bug Growth
Read with this
Total Number of Not Completed Defects (all priorities)
Total Number of Not Completed Defects (all priorities)
More like this
Metrics Catalog
Metrics Catalog
Read with this
Unresolved Bugs Older Than a Month (all priorities)
Unresolved Bugs Older Than a Month (all priorities)
More like this
Defect Containment
Defect Containment
Read with this
Open Bugs Over Time by Priority
Open Bugs Over Time by Priority
More like this