6

Is it possible to get 100% code coverage all the time by considering all cases such as positive/negative, bulk/single etc. Are there any cases which can't be covered by test classes? I often hear that callouts can't be tested but we can use "HttpCalloutMock" to mock the target service. Just wondering what is not possible to test using test classes. would appreciate your thoughts.

Thanks.

3
  • 5
    In my experience much beyond 90% isn't value for money.
    – Keith C
    Aug 28, 2014 at 17:06
  • I agree with Keith -- some people hold 100% out there as a badge of honor but it sometimes leads to a false sense of security since every permutation of code path can't reasonably be covered
    – daveespo
    Aug 28, 2014 at 17:24
  • Not all exceptions you can test. Like if you have try ... catch. Aug 28, 2014 at 18:13

3 Answers 3

9

For all but the most trivial code, 100% coverage isn't achievable. Generally speaking, code coverage generally follows the Pareto principle: Covering 80% of your code only requires about 20% of the code it would take to get to 100% coverage. In most cases, the very first test method I write usually gets about 80% of the coverage (but can vary between 40% and 100%), and an additional 4-6 methods are necessary to approach 100%. Very simple code with no (or very few) branches can be covered with a single test method, but for most practical code, you'll need multiple methods to reach high coverage.

You'll generally have four categories of code:

  • The main execution branch. This is covered in 1 test method, and should reach about 80% of your coverage (if not, your code probably needs refactoring).
  • The side execution branches. These cover normal situations, such as showing warnings on a page, different paths of execution depending on input, etc.
  • The exception branches. These cover unusual situations that have to be handled in a special way. You should not normally code to try and cover these branches, just know that they work. This code should be no more than 20% of your total code, and is usually closer to 10%.
  • The impossible branches. Some code simply can't be run, because of the various limitations of test methods, including some sharing, branches that can't be reached normally but could be reached in unusual situations, and methods that can't be called without causing a "skip" message. This should be no more than 5% of your code, and is usually far less (<1%).

I personally strive for 90% coverage in all classes; this gives a safety margin of 15%. I usually write my code in ways that seem unusual, but result in better coverage through fewer lines of code.

On average, I usually get to about 95%, with the other 5% being exception code and/or impossible-to-cover code. Also, it's worth noting that the percent covered is inversely proportional to the size of the class, on average. At less than 50 lines, I'm almost certain to reach 100%, but at 5000 lines, I'll be lucky to reach 90% in any reasonable amount of time. It usually takes more time to write proper test methods than it does the code you're testing.

5

These are 2 off the top of my head for starters...

PageReference.getContent() and PageReference.getContentAsPDF() can't be called by code running under test.

0

If you need to test more obscure corner cases of code that deals with limits that you can't setup enough test data for in a single transaction. For example, issuing a delete on a record with more than 100k detail records raises a DmlException -- you can rescue and deal with this condition, but you can only insert 10k records in a single transaction so you could never test this (without having setup the data in advance in the org and using the IsTest(SeeAllData=true) annotation)

try{
    delete result;
}
catch(System.DmlException dmle){
    if(dmle.getDmlType(0) != StatusCode.DELETE_OPERATION_TOO_LARGE){
        throw dmle; //reraise
    }
    // enqueue a job to clean up this record asynchronously
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .