Friday, September 30, 2016

Starting related test cases for a given Apex test class

Way back in the day (v27.0 and earlier) it was possible to inline the test cases directly with the apex class. This wasn't always ideal, but it did have one big advantage. Finding the test cases for a class was super easy - they were right there in the class!

This functionality was torn away from us in Summer '13 (v28.0) with the Apex Test Code Segregation act. Maybe that phrasing was a bit melodramatic. The change was actually for the better and heralded in improvements to Apex performance. It did leave a gap with finding the applicable test classes for a given class. This was partially acknowledged with the following planned improvement:

"Test-to-Parent class linking – You will be able to have a test class explicitly related to regular class or trigger. Currently, many of you have implicit connections by adding a suffix or prefix to a class name, but this doesn’t make managing or interacting with your codebase all that much easier. The explicit linkage will allow us to do better UI treatments for related classes. A direct mapping will also make the upcoming Fast Deploy feature much easier to utilize."

Unfortunately for us developers I think the safe harbour this one pulled up in is a bit too comfortable. Since 2013 it's been sitting on a golden beach sipping a cold drink without a care in the world. Maybe we will see it one day.

Back to the now, I've been tinkering with the APIs to try and find an interim solution. There are a couple of challenges with this.

  1. How do you find the Apex classes that directly call a given class?
  2. How do you identify which of those classes is a test class?

The SymbolTable that is exposed by the Tooling API can be useful for the first problem. The ExternalReferences can be used to find all the Apex Classes (and Triggers) that have a direct reference to the given class. It isn't ideal as we really want to find the inbound rather than outbound references. I.e. what calls me, not what do I call. Also, the ExternalReferences returns the class name and namespace, but not the Id. Ugh, so I need to do an extra query to resolve the Id for each class.

There are also less savory ways of finding the reference information if you are willing to pull apart the developer console. Do so at your own risk. One of these is to borrow an unofficial API from the developer console. The short version is that you POST to /_ui/common/apex/debug/ApexCSIAPI and pull out the JSON response. That will give you the list of Apex classes that depend on a given class.

This brings us back to the second problem. How to determine if an Apex class contains Test cases?
My current approach is to do a SOSL query looking for Apex classes that contain @IsTest or testMethod. It can get a few false positives, but at least narrows down the referenced Apex class Ids to those that are likely to contain test methods.

I've put the accumulation of these ideas into the latest release of the FuseIT SFDC Explorer. If you are viewing an individual Apex class you can used the double green arrow to start all the associated test classes.

See also: