sasjs / cli

Command line interface for creating, compiling, and building SAS® projects
https://cli.sasjs.io
MIT License
37 stars 5 forks source link

sasjs test #607

Closed allanbowe closed 3 years ago

allanbowe commented 3 years ago

A big piece missing from the current framework is the ability to integrate tests. For web apps, this is generally no problem as the tests can be performed using existing javascript based tests (executing requests etc). For SAS Data Engineering / Data Science projects however, these tests must be written in SAS language, as they will relate to backend artefacts.

SAS tests will always have the following form:

filename.test.sas

Config

Currently we have the facility to deploy code as either Jobs or Services. This feature will enable a third type - Tests. This will result in a new object in the sasjsconfig.json:

{
  "testConfig": {
    "testFolders": ["sasjs/tests"],
    "initProgram": "sasjs/tests/testinit.sas",
    "termProgram": "sasjs/tests/testterm.sas",
    "macroVars":  {
      "testVar": "testvalue"
    },
   "testSetUp": "sasjs/tests/testsetup.sas",
   "testTearDown": "sasjs/tests/testteardown.sas"
  }
}

This config can be applied to either (or both) the root level, and target level, similar to Jobs and Services. Note the additional attributes (testSetUp and testTearDown), which would run before / after all the tests (if provided).

The testFolders attribute here would be optional. In most cases we would recommend that SAS users create their test files alongside the regular SAS Jobs / Services. For this reason, when compiling tests (which will compile the same way as Services), we also need to check the jobFolders and serviceFolders arrays.

SAS tests are always identified by the filename - which ends with .test.sas, eg somejob.test.sas.

Tests will be deployed in the same way as Services (with the precode), but in an appLoc/tests/xxx folder - typically appLoc/tests/jobs/xxx or appLoc/tests/services/xxx folder, as explained in the "coverage" section below.

sasjs test command

The test command will have the following form

sasjs test  

This will use the sasjs request command to trigger the tests and collect the results. Results will be presented in the sasjsresults folder. An input data file will be provided with a unique test id, eg:

{
    "sasjs_testmeta": [{
        "sasjs_testid": "$(UNIQUE IDENTIFIER FOR TEST RUN)"
    }]
}

compilation

Tests may exist either in the same folder as the source Job or Service, OR in a different folder (specified in the testFolders array). Either way, the tests themselves will be compiled as services in the following fashion:

Source tests:

common/job1.test.sas  # the common folder being defined in the jobFolders setting
tests/jobs/common/job2.test.sas # defined in testFolders setting
public/appinit.test.sas # defined in serviceFolders setting
tests/services/admin/dostuff.test.sas # defined in testFolders setting

Target folder structure:

sasjsbuild/tests/jobs/common/job1.test.sas
sasjsbuild/tests/jobs/common/job2.test.sas
sasjsbuild/tests/services/public/appinit.test.sas
sasjsbuild/tests/services/admin/dostuff.test.sas

coverage

After running sasjs compile (not for single file) the "sasjsbuild/tests" directory is compared to the "sasjsbuild/services" and "sasjsbuild/jobs" directories to determine coverage.

For instance, if we have the following files:

sasjsbuild/jobs/common/job1.sas
sasjsbuild/jobs/common/job2.sas
sasjsbuild/services/public/appinit.sas
sasjsbuild/services/admin/dostuff.sas

Then, for 100% coverage, we would expect:

sasjsbuild/tests/jobs/common/job1.test.sas
sasjsbuild/tests/jobs/common/job2.test.sas
sasjsbuild/tests/services/public/appinit.test.sas
sasjsbuild/tests/services/admin/dostuff.test.sas

The summary will show:

Whilst it would be easy to get 100% test coverage by simply providing a set of empty files (that match the source jobs / services), this would first have to get past the code review. In any case, the goal here is to make it easy to adopt tests, not to circumvent them (it's nearly always easy to do that).

ghost commented 3 years ago

:tada: This issue has been resolved in version 2.17.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: