Skip to content

6. Importing Tests

Rob Scanlon edited this page Jun 9, 2022 · 6 revisions

Goal

Some Implementation Guides refer to other Implementation Guides when they would like to reuse guidance or rules. In these cases, it is useful to be able to import tests from associated Test Kits to provide a single integrated testing experience. This is how the Inferno-based (g)(10) Standardized API Test Kit is constructed -- it imports multi-purpose tests from the SMART App Launch Test Kit and the US Core Test Kit.

In this step, we will add an optional SMART App Launch test to this test suite, which will automatically provide other tests with an OAuth bearer token, as well as a patient_id if provided in context.

For those using the Inferno Reference Server, note that you may use the SAMPLE_PUBLIC_CLIENT_ID client id with no secret as registration information to provide into the tests.

Resources

Solution

In the .env file add the host of your environment (if launching from GitHub Codespaces or any non-localhost environment, you can just copy the host that the Inferno interface is served from):

INFERNO_HOST=http://localhost

Update the inferno_template.gemspec to include the smart_app_launch_test_kit gem:

spec.add_runtime_dependency 'smart_app_launch_test_kit', '~> 0.1.3'

And update the tests to import the library, and include a new optional Auth section with groups described in the SMART App Launch documentation. Grouping all existing tests under an API section will help keep things clean:

require_relative 'inferno_template/patient_group'
require 'smart_app_launch_test_kit'

module InfernoTemplate
  class Suite < Inferno::TestSuite
    id :test_suite_template
    title 'Inferno Test Suite Template'
    description 'A basic test suite template for Inferno'

    # This input will be available to all tests in this suite
    input :url

    group do
      title 'Auth'
      optional
      run_as_group

      output :access_token, :patient_id
      
      group from: :smart_discovery
      group from: :smart_standalone_launch
    end

    group do
      title 'API'
      input :access_token

      # All FHIR requests in this suite will use this FHIR client
      fhir_client do
        url :url
        bearer_token :access_token
      end

      # Tests and TestGroups can be defined inline
      group do
        id :capability_statement
        title 'Capability Statement'
        description 'Verify that the server has a CapabilityStatement'

        test do
          id :capability_statement_read
          title 'Read CapabilityStatement'
          description 'Read CapabilityStatement from /metadata endpoint'

          run do
            fhir_get_capability_statement

            assert_response_status(200)
            assert_resource_type(:capability_statement)
          end
        end
      end

      # Tests and TestGroups can be written in separate files and then included
      # using their id
      group from: :patient_group

      group do
        id :search_tests
        title 'Search Tests'
      
        input :patient_id
      
        ['AllergyIntolerance',
        'CarePlan',
        'CareTeam',
        'Condition',
        'Device',
        'DiagnosticReport',
        'DocumentReference',
        'Encounter',
        'Goal',
        'Immunization',
        'MedicationRequest',
        'Observation',
        'Procedure'].each do |tested_resource|

          test do
            title "#{tested_resource} Search by Patient"
        
            run do
              fhir_search(tested_resource, params: { patient: patient_id })
        
              assert_response_status(200)
              assert_resource_type('Bundle')

              # skip_if is a shortcut to wrapping `skip` statement in an `if` block
              # it is a good idea to use the safe navigation operator `&.` to avoid runtime errors on nil
              skip_if resource.entry&.empty?, 'No entries in bundle response.'

              info "Bundle contains #{resource.entry&.count} resources."

              # There are not profiles for Observation, DocumentReference, or Device
              # in US Core v3.1.1
              pass_if ['Observation', 'DiagnosticReport', 'Device'].include?(tested_resource),
                "Note: no US Core Profile for #{tested_resource} resource type"

              assert_valid_bundle_entries(
                resource_types: {
                  "#{tested_resource}": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-#{tested_resource.downcase}"
                }
              )
            end
          end
        end
      end
    end
  end
end