3

I have two 2GMP packages: Baseline package and package Extension which depends on Baseline package.

I have released Major version for the Baseline package and now I am trying to release Major version for the package Extension.

When I run all the apex test, I see coverage is 96%. When I try to release the package extension, I receive an error

ERROR running force:package:version:promote:  The code coverage required to promote this version has not been met.  Please add additional test coverage and ensure the code coverage check passes during version creation.

Looks like some tests from baseline package cover the extension package classes, but this isn't accounted on package promotion.

This brings an issue, how can I find the uncovered lines if 96% is covered?

3

The code coverage is calculated on test classes belonging to package extension. Baseline test classes execution is not considered while releasing package extension.

To find the real test coverage on package extension, the following actions should be performed.

  1. Prepare manually a list of test classes that belong to package extension.

  2. Prepare manually a list of classes (and triggers) that belong to package extension.

  3. Execute the test classes from the list of test classes belonging to package extension.

  4. Execute Tooling API query SELECT Id, ApexClassorTriggerId, ApexClassorTrigger.Name, NumLinesCovered, NumLinesUncovered, Coverage FROM ApexCodeCoverageAggregate

  5. Prepare the table from the query results and filter classes to include only classes belonging to package extension.

  6. Sum up all the covered lines and uncovered lines from classes belonging to package extension.

  7. Divide the sum of all package extension classes covered lines to sum of covered and uncovered lines for package extension. This is the actual coverage for the package extension.

Assuming you are using bash and the path where package extension is extension, you could use the following bash script to automate this:

x=()
for class in $(ls extension/classes/*.cls)
do
    tmp=${class#*classes/}
    b=${tmp%.*}
    x+=($b)
done
s="','"
b=$(printf "${s}%s" "${x[@]}")
b="'${b:${#s}}'"

t=$(IFS=, ; echo "${x[*]}")


echo "Running apex tests"

echo $(sfdx force:apex:test:run -n "$t" --loglevel=trace -c -r json -d ./tests/apex -w 20) > tests.json

echo $(sfdx force:data:soql:query -t -q "SELECT Id, ApexClassorTriggerId, ApexClassorTrigger.Name, NumLinesCovered, NumLinesUncovered, Coverage FROM ApexCodeCoverageAggregate WHERE ApexClassOrTrigger.Name IN ($b)" --json) > query.json

cover=$(echo $(cat query.json) | jq '.result.records[] .NumLinesCovered' | awk '{s+=$1} END {print s}')

uncov=$(echo $(cat query.json) | jq '.result.records[] .NumLinesUncovered' | awk '{s+=$1} END {print s}')

echo "scale=9 ; 100 * $cover / ($cover + $uncov)" | bc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.