Skip to content

Integration Testing

Definition

Integration testing is testing the integration of different part of the system together. Two different parts or modules of the system are first integrated and then integration testing is performed.

The aim of integration testing is to check the functionality, reliability, and performance of the system when integrated.

Integration testing is performed on the modules that are unit tested first and then integration testing defines whether the combination of the modules give the desired output or not.

Integration testing can either be done by independent testers or by developers too.

Spock Testing Framework

Spock (https://spockframework.org/) is the testing framework embedded within Platform 6

It’s primary purpose is to provide a unit testing toolkit for script development. However, it can also be used for integration testing.

  • Integration tests are built using P6 scripts but are not packaged with an application bundle.

  • Integration tests are not run automatically or run via the ‘Run tests’ button within the UI as this is for unit tests only.

  • Integration tests are run manually and often require the system to be in a particular state (database content, external endpoint access etc) before they can run to completion.

  • Integration tests should not be created with the _test extension. However Integration tests do extend the Spock Specification and benefit from its rich DSL.

  • Integration tests, generally, cannot be run from within your IDE as a wider system state is required.

Integration Test Context

Spock has a powerful ‘mocking’ API for unit tests however making wider system capabilities usable from Spock requires the use of a Singleton Context

The Singleton test context can be loaded with system state and bindings and accessed from a Spock test Specification using a simple class as follows:

Module Name: TestContext

package io.platform6.app.core.scripts.integrationtestexample

import io.platform6.core.dsl.TypedP6Dsl

@Singleton
class TestContext {
    TypedP6Dsl p6
    def params = [:]
}
Here we use TestContext to allow access to the Platform 6 DSL, and a Map of general parameters that can be passed in.

Info

Details of the Groovy Singleton annotation here: https://docs.groovy-lang.org/latest/html/api/groovy/lang/Singleton.html

The TestContext is instantiated and loaded via the main script module. The main module also runs the Spock Specification(s) via the EmbeddedSpecRunner:

Module Name: main

package io.platform6.app.core.scripts.integrationtestexample

import spock.util.EmbeddedSpecRunner
import io.platform6.core.dsl.TypedP6Dsl

def esr = new EmbeddedSpecRunner()

def p6 = new TypedP6Dsl(p6)
TestContext.instance.p6 = p6

p6.pipeline.put 'hello', 'world'

esr.runClass(SpockTestSpec.class)

Note

I’m loading the pipeline with ‘hello, world’ as a simple test

Finally, here is the test Specification that tests the content of the P6 pipeline:

Module Name: SpockTestSpec

package io.platform6.app.core.scripts.integrationtestexample

import spock.lang.*
import io.platform6.core.dsl.TypedP6Dsl


class SpockTestSpec extends Specification {

    @Shared TypedP6Dsl p6 = TestContext.instance.p6

    def "hello pipeline must be world"() {
        given:
        def pipelineVal = p6.pipeline.get('hello')

        expect:
        pipelineVal == 'world'
    }

}

Info

Details of the Spock Shared annotation here: https://spockframework.org/spock/docs/2.0/all_in_one.html#_fields