Jenkins Spock
We test pipeline libraries using Jenkins-Spock, a variation of the Spock testing framework that has been designed around testing Jenkins pipelines.
Writing a Specification File
A "specification" is a list of features derived from business requirements. A specification file contains that list of features as unit tests, and those tests validate that the features work as expected. There should be a separate file for each pipeline step in your library.
Below is an outline of a specification file. It shows what you need to include in order to run tests, as well as some conventions for what to name methods and variables. Create a groovy file with the same name as the class (such as MyPipelineStepSpec.groovy
`) and use this outline to get you started, making sure to swap names with ones for your library.
Sample Specification
-
Import the framework
-
Create a class extending
JenkinsPipelineSpecification
-
Create a field to house the loaded step
-
Define a setup method where you will load the step
-
Write a test
// Start by importing the Jenkins-Spock framework Code
import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
// Create a new class for the Spec
// The naming convention is the pipeline step's name, followed by Spec,
// all camel-cased starting w/ a capital.
public class MyPipelineStepSpec extends JenkinsPipelineSpecification {
// Define the variable that will store the step's groovy code. This variable
// follows the same naming variable as the class name, with Spec omitted.
def MyPipelineStep = null
// setup() is a fixture method that gets run before every test.
// http://spockframework.org/spock/docs/1.2/spock_primer.html#_fixture_methods
def setup() {
// It's required to load the pipeline script as part of setup()
// With the library monorepo, pipeline step groovy files can be found in "sdp/libraries"
MyPipelineStep = loadPipelineScriptForTest("sdp/libraries/my_library/my_pipeline_step.groovy")
}
// Write a test (i.e. Feature Method) for each feature you wish to validate
// http://spockframework.org/spock/docs/1.2/spock_primer.html#_feature_methods
def "Successful Build Sends Success Result" () {
setup:
// unlike in the pipeline, the config object is not loaded during
// unit tests. Use this to set it manually
MyPipelineStep.getBinding().setVariable("config", [ field: "String" ])
when:
// This is the "stimulus". It does things so we can test what happens
// Typically, you execute the step's groovy code like this
MyPipelineStep()
then:
// Here's where you describe the expected response
// If everything in here is valid, the test passes
1 * getPipelineMock("sh")("echo \"field = String\"")
}
}