Types that used to be 100% covered by tests should still be 100% covered
Runs only in diff mode (baseline defined) and when coverage data is imported. Warns when a type fully covered by tests in the baseline is now only partially covered.
The last ~10% of a class is as hard to cover as the first 90%, but untestable code usually means poorly written, error prone code: most tricky bugs might come from this small portion of hard-to-test code. Most application logic should live in easy-to-test classes 100% covered.
Severity is High: a type that lost 100% coverage is a bug-prone situation to handle carefully.
The last ~10% of a class is as hard to cover as the first 90%, but untestable code usually means poorly written, error prone code: most tricky bugs might come from this small portion of hard-to-test code. Most application logic should live in easy-to-test classes 100% covered.
Severity is High: a type that lost 100% coverage is a bug-prone situation to handle carefully.
How to fix
Write more unit-tests for code no longer covered. Hard-to-test code signals a design needing refactoring. For code impossible to cover (like MessageBox.Show()), define an infrastructure to mock it at test-time.
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Types that used to be 100% covered by tests should still be 100% covered</Name>
// <Id>ND1606:TypesThatUsedToBe100PercentCoveredByTestsShouldStillBe100PercentCovered</Id>
warnif count > 0
from t in JustMyCode.Types where
t.IsPresentInBothBuilds() &&
t.OlderVersion().PercentageCoverage == 100 &&
t.PercentageCoverage < 100
from m in t .MethodsAndConstructors where
m.NbLinesOfCode> 0 &&
m.PercentageCoverage < 100 &&
!m.IsExcludedFromCoverage
select new {
m,
m.PercentageCoverage,
// Simplistic Debt estimation, because the effort to write tests for a method not 100% tested
// is already estimated properly with the rule "Code should be tested".
Debt = t.NbLinesOfCodeNotCovered.Linear(1,2, 10,10).ToMinutes().ToDebt(),
Severity = Severity.High
}
//<Expl>
// The *{0}* was previously 100% covered by tests in the baseline, but now it stands at {1}% coverage.
// It is important to create new tests to potentially detect any regressions in coverage that might introduce bugs.
//</Expl>
//<Desc>
// Runs only in *diff mode* (baseline defined) and when coverage data is
// imported. Warns when a type fully covered by tests in the baseline is now
// only partially covered.
//
// The last ~10% of a class is as hard to cover as the first 90%, but
// *untestable code* usually means *poorly written*, *error prone* code:
// **most tricky bugs might come from this small portion of hard-to-test
// code**. Most application logic should live in *easy-to-test classes* 100%
// covered.
//
// Severity is **High**: a type that lost 100% coverage is a bug-prone
// situation to handle carefully.
//</Desc>
//<HowToFix>
// Write more unit-tests for code no longer covered. *Hard-to-test code*
// signals a design needing refactoring. For code impossible to cover (like
// *MessageBox.Show()*), define an infrastructure to *mock* it at test-time.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Code Coverage: all 15 items
- Code should be tested ND1600
- New Types and Methods should be tested ND1601
- Methods refactored should be tested ND1602
- Assemblies and Namespaces should be tested ND1603
- Types almost 100% tested should be 100% tested ND1604
- Namespaces almost 100% tested should be 100% tested ND1605
- Types that used to be 100% covered by tests should still be 100% covered ND1606
- Types tagged with FullCoveredAttribute should be 100% covered ND1607
- Types 100% covered should be tagged with FullCoveredAttribute ND1608
- Methods should have a low C.R.A.P score ND1609
- Complex Methods should be 100% tested ND1610
- Test methods should assert something ND1611
- Test Methods
- Methods directly called by test Methods
- Methods directly and indirectly called by test Methods