Jenkins interview question
Declarative vs scripted pipeline in Jenkins: which would you use to run tests?
Short answer
Both are pipeline-as-code in a Jenkinsfile. Declarative has a fixed, validated structure (pipeline, agent, stages, steps, post) and is the default choice. Scripted is plain Groovy, more flexible but harder to read and maintain. Use declarative and drop into a script block only when you must.
Answer
Both styles are pipeline as code: the pipeline lives in a Jenkinsfile committed alongside the application or test code, so changes are reviewed, versioned and reproducible. The difference is how much structure Jenkins enforces.
Declarative pipeline
Declarative syntax starts with a pipeline { } block and has a defined shape: agent, environment, options, parameters, stages → stage → steps, and post. Jenkins validates that structure before running, so syntax mistakes fail fast with readable errors. It also gives you useful features for free: post { always { } } for cleanup and report publishing, when conditions, options { timeout(...) }, and stage-level agents. Blue Ocean and the stage view render it cleanly.
pipeline {
agent any
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '20'))
}
parameters {
choice(name: 'ENV', choices: ['qa', 'staging'], description: 'Target environment')
}
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('API tests') {
steps { sh "mvn -B test -Dgroups=api -Denv=${params.ENV}" }
}
stage('UI smoke') {
steps { sh "mvn -B test -Dgroups=smoke -Denv=${params.ENV}" }
}
}
post {
always {
junit testResults: '**/target/surefire-reports/*.xml', allowEmptyResults: true
}
}
}
Scripted pipeline
Scripted pipelines start with node { } and are essentially Groovy programs running on the Jenkins CPS engine. You can write loops, conditionals and helper functions anywhere, which is powerful for unusual flows, but there is no structure validation, error handling is manual (try/catch/finally), and long scripts become hard for the rest of the team to read.
node {
stage('Checkout') { checkout scm }
try {
stage('Tests') { sh 'mvn -B test' }
} finally {
junit '**/target/surefire-reports/*.xml'
}
}
Which one I would choose
Declarative, by default. Most test pipelines are linear: checkout, build, run suites, publish results, notify. Declarative expresses that clearly and makes post handling of results and cleanup hard to get wrong. When I genuinely need imperative logic, such as generating stages from a list, I use a script { } block inside a step, and if the same logic appears in several repos I move it into a shared library rather than growing a scripted pipeline.
Common mistakes
- Putting long Groovy logic inline instead of in a shared library or a shell script that can be run locally.
- Forgetting
post { always { ... } }, so test reports are not published when a stage fails. - Hard-coding credentials instead of using
credentials()orwithCredentials.
What interviewers look for
- You know both are stored as a
Jenkinsfilein source control. - You can sketch a declarative pipeline from memory, including
post. - You prefer declarative and can explain when scripted or
script { }is justified.
A strong answer covers
- Both are pipeline-as-code stored in a Jenkinsfile in the repo
- Declarative has a fixed structure: pipeline, agent, stages, steps, post
- Scripted is full Groovy, flexible but harder to maintain
- Prefer declarative, use a script block or shared library for complex logic