Testing and Quality Assurance

Testing and Quality Assurance

Introduction to Testing in Jenkins

Testing Strategy

A comprehensive testing strategy in Jenkins includes:

  • Unit Testing
  • Integration Testing
  • Performance Testing
  • Security Testing
  • Code Quality Analysis

Test Automation Framework

// Test Automation Pipeline
pipeline {
    agent any
    tools {
        maven 'Maven 3.8.4'
        jdk 'JDK 11'
    }
    stages {
        stage('Unit Tests') {
            steps {
                sh 'mvn test'
                junit '**/target/surefire-reports/*.xml'
            }
        }
        stage('Integration Tests') {
            steps {
                sh 'mvn verify'
                junit '**/target/failsafe-reports/*.xml'
            }
        }
    }
    post {
        always {
            archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
            publishHTML([
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: 'target/site/jacoco',
                reportFiles: 'index.html',
                reportName: 'Code Coverage Report'
            ])
        }
    }
}

Unit Testing

JUnit Integration

// JUnit Test Configuration
class CalculatorTest {
    @Test
    void testAddition() {
        Calculator calc = new Calculator()
        assertEquals(4, calc.add(2, 2))
    }
    
    @Test
    void testDivision() {
        Calculator calc = new Calculator()
        assertThrows(ArithmeticException.class, () -> {
            calc.divide(1, 0)
        })
    }
}

TestNG Implementation

// TestNG Configuration
@Test(groups = {"unit"})
public class UserServiceTest {
    @BeforeClass
    public void setUp() {
        // Setup test environment
    }
    
    @Test(dataProvider = "userData")
    public void testUserCreation(String username, String email) {
        User user = userService.createUser(username, email)
        assertNotNull(user)
        assertEquals(username, user.getUsername())
    }
    
    @DataProvider(name = "userData")
    public Object[][] userData() {
        return new Object[][] {
            {"user1", "user1@example.com"},
            {"user2", "user2@example.com"}
        }
    }
}

Integration Testing

API Testing

// REST Assured Test Configuration
public class APITest {
    @Test
    public void testUserAPI() {
        given()
            .contentType(ContentType.JSON)
            .body(new User("testuser", "test@example.com"))
        .when()
            .post("/api/users")
        .then()
            .statusCode(201)
            .body("username", equalTo("testuser"))
            .body("email", equalTo("test@example.com"))
    }
}

Database Integration Tests

// Database Test Configuration
@SpringBootTest
class UserRepositoryTest {
    @Autowired
    private UserRepository userRepository
    
    @Test
    @Sql("/test-data.sql")
    void testFindByUsername() {
        User user = userRepository.findByUsername("testuser")
        assertNotNull(user)
        assertEquals("test@example.com", user.getEmail())
    }
}

Performance Testing

JMeter Integration

// JMeter Pipeline Stage
stage('Performance Tests') {
    steps {
        sh '''
            jmeter -n -t performance-test.jmx \
                -l results.jtl \
                -e -o report
        '''
        
        perfReport sourceDataFiles: 'results.jtl',
                   errorFailedThreshold: 5,
                   errorUnstableThreshold: 3,
                   errorUnstableResponseTimeThreshold: '5000'
    }
}

Gatling Performance Tests

// Gatling Test Scenario
class UserSimulation extends Simulation {
    val httpProtocol = http
        .baseUrl("http://test-api.example.com")
        .acceptHeader("application/json")
    
    val scn = scenario("User API Test")
        .exec(http("Get Users")
            .get("/api/users")
            .check(status.is(200)))
        .pause(1)
        .exec(http("Create User")
            .post("/api/users")
            .body(StringBody("""{"username":"test","email":"test@example.com"}"""))
            .check(status.is(201)))
    
    setUp(
        scn.inject(
            rampUsers(100).during(10.seconds)
        )
    ).protocols(httpProtocol)
}

Code Quality

SonarQube Integration

// SonarQube Analysis Pipeline
stage('Code Quality') {
    steps {
        withSonarQubeEnv('SonarQube') {
            sh '''
                mvn sonar:sonar \
                    -Dsonar.projectKey=my-project \
                    -Dsonar.sources=src/main \
                    -Dsonar.tests=src/test \
                    -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
            '''
        }
        timeout(time: 1, unit: 'HOURS') {
            waitForQualityGate abortPipeline: true
        }
    }
}

Code Coverage

// JaCoCo Configuration
jacoco {
    toolVersion = "0.8.7"
    reportsDirectory = layout.buildDirectory.dir('reports/jacoco')
    
    coverage {
        rules {
            rule {
                limit {
                    minimum = 0.8
                }
            }
        }
    }
}

Security Testing

OWASP Dependency Check

// OWASP Dependency Check Stage
stage('Security Scan') {
    steps {
        dependencyCheck additionalArguments: '''
            --scan ./ \
            --format HTML \
            --format XML \
            --suppression suppression.xml
            ''',
            odcInstallation: 'OWASP-Dependency-Check'
        
        dependencyCheckPublisher pattern: '**/dependency-check-report.xml'
    }
}

ZAP Security Scan

// ZAP Security Scan Configuration
stage('Security Testing') {
    steps {
        sh '''
            zap-cli quick-scan \
                --self-contained \
                --start-options "-config api.disablekey=true" \
                --spider \
                --ajax-spider \
                --scan \
                https://test.example.com
        '''
    }
    post {
        always {
            publishHTML([
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: 'zap-report',
                reportFiles: 'report.html',
                reportName: 'ZAP Security Report'
            ])
        }
    }
}

Test Reporting

Test Result Visualization

// Test Report Configuration
post {
    always {
        junit '**/target/surefire-reports/*.xml'
        jacoco(
            execPattern: '**/target/jacoco.exec',
            classPattern: '**/target/classes',
            sourcePattern: '**/src/main/java',
            exclusionPattern: '**/test/**'
        )
        publishHTML([
            allowMissing: false,
            alwaysLinkToLastBuild: true,
            keepAll: true,
            reportDir: 'target/site/serenity',
            reportFiles: 'index.html',
            reportName: 'Serenity Test Report'
        ])
    }
}

Custom Report Generation

// Custom Test Report Generator
class TestReportGenerator {
    static void generateReport(results) {
        def report = new StringBuilder()
        report.append("Test Execution Summary\n")
        report.append("=====================\n\n")
        
        results.each { suite ->
            report.append("Suite: ${suite.name}\n")
            report.append("Tests: ${suite.tests}\n")
            report.append("Passed: ${suite.passed}\n")
            report.append("Failed: ${suite.failed}\n\n")
        }
        
        new File('test-report.txt').text = report.toString()
    }
}

Hands-on Exercises

Exercise 1: Test Implementation

  1. Set up Unit Tests
  2. Configure Integration Tests
  3. Implement Performance Tests
  4. Add Security Scans
  5. Generate Reports

Exercise 2: Quality Gates

  1. Configure SonarQube
  2. Set up Code Coverage
  3. Implement Quality Gates
  4. Monitor Results
  5. Optimize Tests

Assessment

Knowledge Check

  1. What are the key components of a testing strategy?
  2. How do you implement different types of tests?
  3. What are the best practices for test reporting?
  4. How do you configure quality gates?

Practice Tasks

  1. Implement comprehensive tests
  2. Set up quality analysis
  3. Configure security scanning
  4. Create custom reports

Additional Resources

Documentation

Best Practices

  • Automate all tests
  • Implement quality gates
  • Regular security scans
  • Comprehensive reporting

Next Steps

  • Review testing concepts
  • Practice test implementation
  • Explore advanced features
  • Study real-world scenarios