Adding a Step¶
1. Create the step file¶
Add vars/<stepName>.groovy. The file must define a call(...) method — that's what Jenkins invokes when pipeline code calls stepName().
// Accept an optional config map so callers can pass named parameters without breaking existing usage
def call(Map config = [:]) {
// Pipeline DSL globals are available here: sh, echo, error, fileExists, env, etc.
echo "running ${config.get('target', 'default')}"
}
2. Write the test¶
Add test/<StepName>Test.groovy extending BasePipelineTest. Mock every DSL method the step calls via helper.registerAllowedMethod.
// Test class extends BasePipelineTest so JPU can intercept pipeline DSL calls
import com.lesfurets.jenkins.unit.BasePipelineTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.*
class MyStepTest extends BasePipelineTest {
@BeforeEach
void setUp() {
// Initialise the JPU helper and set a default empty environment for each test
super.setUp()
binding.setVariable('env', [:])
}
@Test
void 'does the thing'() {
// Load the step script and invoke it, then assert on return values or call stack
def script = loadScript('vars/myStep.groovy')
script.call()
}
}
Dots in test method names
Java 25 rejects method names containing .. Never include filenames or extensions
in a test method name — use underscores instead (package_json not package.json).
3. Run the tests¶
# Run the full test suite or narrow to a single class for faster feedback
./gradlew test # all tests
./gradlew test --tests MyStepTest # single class
4. Document the step¶
Add docs/steps/<step-name>.md and register it in mkdocs.yml under the Steps nav entry.