Code Coverage

In order to obtain the code coverage of your unit tests, you should use the Unit Test Framework we provide, or modify your own framework to generate the information required for the analys. We will help to modify your custom Unit Test Framework under license basis.

Check also the InterSystems TestCoverage project on Github, which is also compatible with objectscriptQuality. In that case, use the Cobertura option to generate the data output.

1. Setup your environment

1.1 Download the Unit Test Framework from here

1.2 Import the XML into your namespace

2. Writer your unit tests

You can view a package named lite.test.coverage.linebyline, which contains all you need to create your unit test at the time it takes information about the code coverage.

Let's go ahead with a simple example; imagine we have such simple class:

Class lite.samples.co.Component [ Abstract ]
{

ClassMethod Add(pintP1 As %Integer, pintP2 As %Integer) As %Integer
  {
      Write !,"Add: 1"
      Write !,"Add: 2"
      Write !,"Add: 3"
    
      If (pintP1 '= 1)
      {
          Write !,"This line won't be covered when pintP1 is 1"
      }
    
      Return pintP1+pintP2
  }

}

And we write a simple unit test:


Class lite.samples.test.co.ComponentTest Extends %UnitTest.TestCase
{

Method TestAdd()
  {
      Do $$$AssertEquals(##class(lite.samples.co.Component).Add(1, 2), 3, "Test Add(1,2)=3")
  }
}

You can run the unit test from the terminal with the following sentence:

Do  ##Class(lite.test.coverage.linebyline.Runner).RunOneTestCase("lite.samples.co", "lite.samples.test.co.ComponentTest", "TestAdd", "C:\Temp\Coverage.xml")

Parameters of RunOneTestCase are:

  • ptheLogicSuite: String with the package involved on test
  • ptheTestClass: String with the class name which contains the test
  • ptheTestMethod: Method name on ptheTestClass to invoke
  • pstrOutputLogFile: String with the full filename where the code coverage information is bulked

3. Run from command line

3.1 To execute your unit tests from command line, you will need to create a file with the execution information, with the following format:

cache_username
cache_password
Do ##Class(lite.test.coverage.linebyline.Runner).RunOneTestCase("lite.samples.co", "lite.samples.test.co.ComponentTest", "TestAdd", "C:\sonarqube\jenkins-home\myproject\test\output\codecoverage.xml")

3.2 Run your test using your Caché installation:

{cache_root}\bin\cache.exe -s {cache_root}\mgr < C:\sonarqube\jenkins-home\myproject\test\runTests.cmd
Paths must be adapted to your context

4. Add Code Coverage on Jenkins task

4.1 Add a step before running sonar-scanner to run your tests

{cache_root}\bin\cache.exe -s {cache_root}\mgr < C:\sonarqube\jenkins-home\myproject\test\runTests.cmd

4.2 On the sonar-scanner execution, add the parameter -Dsonar.coverageReportPaths:

cd "C:\sonarqube\cachedb-import\output\%JOB_NAME%"
sonar-scanner -Dsonar.projectKey="%JOB_NAME%" -Dsonar.projectName="%JOB_NAME%" -Dsonar.sources=. -Dsonar.projectVersion=1.0 -Dsonar.coverageReportPaths="$WORKSPACE\test\output\codecoverage.xml"
Paths must be adapted to your context

1. Setup your environment

1.1 Download the Unit Test Framework from here

1.2 Import the XML into your namespace

2. Writer your unit tests

You can view a package named lite.test.coverage.linebyline, which contains all you need to create your unit test at the time it takes information about the code coverage.

Let's go ahead with a simple example; imagine we have such simple class:

Class lite.samples.co.Component [ Abstract ]
{

ClassMethod Add(pintP1 As %Integer, pintP2 As %Integer) As %Integer
  {
      Write !,"Add: 1"
      Write !,"Add: 2"
      Write !,"Add: 3"
    
      If (pintP1 '= 1)
      {
          Write !,"This line won't be covered when pintP1 is 1"
      }
    
      Return pintP1+pintP2
  }

}

And we write a simple unit test:


Class lite.samples.test.co.ComponentTest Extends %UnitTest.TestCase
{

Method TestAdd()
  {
      Do $$$AssertEquals(##class(lite.samples.co.Component).Add(1, 2), 3, "Test Add(1,2)=3")
  }
}

You can run the unit test from the terminal with the following sentence:

Do  ##Class(lite.test.coverage.linebyline.Runner).RunOneTestCase("lite.samples.co", "lite.samples.test.co.ComponentTest", "TestAdd", "/tmp/codecoverage.xml")

Parameters of RunOneTestCase are:

  • ptheLogicSuite: String with the package involved on test
  • ptheTestClass: String with the class name which contains the test
  • ptheTestMethod: Method name on ptheTestClass to invoke
  • pstrOutputLogFile: String with the full filename where the code coverage information is bulked

3. Run from command line

3.1 To execute your unit tests from command line, you will need to create a file with the execution information, with the following format:

cache_username
cache_password
Do ##Class(lite.test.coverage.linebyline.Runner).RunOneTestCase("lite.samples.co", "lite.samples.test.co.ComponentTest", "TestAdd", "/opt/jenkins/home/workspace/myproject/test/output/codecoverage.xml")

3.2 Run your test invoking your Caché installation:

{cache_root}/bin/cache.exe -s {cache_root}/mgr < /opt/jenkins/home/workspace/myproject/test/runTests.cmd

4. Add Code Coverage on Jenkins task

4.1 Add a step before running sonar-scanner to run your tests, as you would do from command line

{cache_root}/bin/cache.exe -s {cache_root}/mgr < /opt/jenkins/home/workspace/myproject/test/runTests.cmd

4.2 On the sonar-scanner execution, add the parameter -Dsonar.coverageReportPaths:

cd "/opt/sonarqube/cachedb-import/output/$JOB_NAME"
/opt/sonarqube/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey="$JOB_NAME" -Dsonar.projectName="$JOB_NAME" -Dsonar.sources=. -Dsonar.projectVersion=1.0 -Dsonar.coverageReportPaths="$WORKSPACE/codecoverage/codecoverage.xml"