Author Archives: RickDjouwe1

Connecting Object-Oriented Principles to UML Class Diagrams

Hello everyone, and welcome to my first blog entry of the semester!

For this week’s self-directed professional development, I listened to the podcast

SOLID Principles with Uncle Bob (Robert C. Martin) on Hanselminutes. (hanselminutes.com) Even though the focus of the episode was on SOLID design principles, I found that many of the ideas connected back to the object-oriented design principles we covered in CS-343 last week. The principles were inheritance, polymorphism, encapsulation, and abstraction, and also tied naturally into our current topic of UML class diagrams.

Summary of the Podcast

Here I am just going to give you guys a tiny summary of the podcast. It’s about 45 mins.

In this episode, Scott Hanselman interviews Robert C. Martin, known as “Uncle Bob,” about how object-oriented design principles shape the flexibility and maintainability of software. He explains why well-structured code allows systems to grow and adapt, while poor design leads to fragile, hard-to-maintain projects. Uncle Bob also emphasizes the importance of thinking carefully about class responsibilities and relationships early in the design phase, which is exactly what UML class diagrams are meant to capture.

Why I Selected This Resource

I chose this podcast because it offered a professional perspective on how design principles go beyond theory and impact real-world software. Since we just studied the four pillars of OOP and are now practicing UML diagrams, I wanted a resource that would help me bridge those two areas. The episode did exactly that: it showed how principles like abstraction or encapsulation are not just coding rules but also influence how we design and visualize systems.

Personal Reflections: What I Learned and Connections to Class

Listening to Uncle Bob made me reflect on how the four OOP principles are deeply connected to UML diagrams:

  • Encapsulation: In diagrams, private attributes and public methods show how data is protected yet accessible through controlled interfaces.
  • Inheritance: The “is-a” relationships in UML are not just arrows; they communicate how subclasses extend parent classes without duplicating logic.
  • Polymorphism: Method overriding and dynamic behavior become clearer when you see how subclasses can stand in for parents in a diagram.
  • Abstraction: Interfaces and abstract classes in UML help highlight shared behaviors without tying designs to specific implementations.

What stood out to me was how Uncle Bob framed design decisions as long-term investments. A UML diagram isn’t just a class picture, it’s the foundation for whether the software remains adaptable or becomes rigid.

Application to Future Practice

Going forward in CS-343, I’ll use these insights to strengthen my UML class diagrams. I plan to treat encapsulation, inheritance, polymorphism, and abstraction as a checklist when building diagrams. For example, when defining relationships, I’ll ask whether inheritance truly makes sense or if abstraction through an interface is better. These habits will not only help me in this course but also in future projects where design clarity and flexibility are essential.

Citation / Link

  • Hanselman, Scott. SOLID Principles with Uncle Bob – Robert C. Martin. Hanselminutes Podcast, Episode #145, January 5, 2009. Available online. (hanselminutes.com)

This resource helped me connect the four pillars of object-oriented programming we studied last week with the UML class diagrams we are now practicing. It reinforced that principles and diagrams go hand in hand, shaping how professional software is designed and maintained.

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Starting My Journey in Software Process Management

Hello everyone, my name is Rick Djouwe, and this semester I am also taking Software Process Management. While some of my other computer science courses focus on the technical side of software development, like design, coding, and architecture, this class emphasizes the processes, management strategies, and professional practices that ensure software projects succeed.

What This Course is About

Software Process Management is designed to explore the methods and tools used to manage software projects from start to finish. Topics include:

  • Version control and collaboration tools for effective teamwork.
  • Software process models (from agile to large-scale iterative methodologies).
  • Project management skills such as planning, measuring progress, estimating costs, and managing risks.
  • Software licensing and contracts, and an introduction to intellectual property.
  • Coding standards, documentation standards, and code reviews to ensure consistency and quality.
  • Software maintenance and testing as ongoing parts of the development lifecycle.

In short, this course highlights the practices that make the difference between a project that simply “works” and one that is well-managed, scalable, and sustainable.

Skills and Outcomes

By the end of this course, I will be able to:

  • Gather and prioritize requirements through communication and negotiation with stakeholders.
  • Develop project plans and track progress to ensure goals are met on time and within budget.
  • Apply management techniques in both agile and larger-scale development contexts.
  • Analyze needs and goals to make informed decisions about software solutions.
  • Understand contracts, licensing, and professional ethics within the software industry.

These skills go hand-in-hand with the Computer Science program outcomes, such as analyzing problems, applying ethical reasoning, and demonstrating leadership and effective teamwork.

Why This Matters to Me

As I prepare for a career as a software engineer, this course will strengthen my ability not only to contribute technically, but also to lead and manage software projects effectively. Understanding process management is critical in real-world environments, where collaboration, deadlines, and accountability are just as important as writing clean code.

I also see a strong connection to my current role at The Hanover Insurance Group, where teamwork, version control, documentation, and project management practices are essential to delivering quality solutions. What I learn in this class will help me bring even more value to my work, both now and in the future.

I look forward to exploring how different methodologies shape the software development lifecycle, and how project management skills complement technical expertise. My goal is to come out of this course not only as a better developer, but also as someone prepared to guide teams, manage projects, and ensure successful outcomes.

I’m also excited to meet everyone in this class and learn from each other’s perspectives and experiences as we grow together throughout the semester.

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Welcome to My Journey in CS 343: Software Construction, Design & Architecture

Hello everyone, my name is Rick Djouwe, and this semester I am beginning CS 343: Software Construction, Design & Architecture. I am truly excited for this class because it represents the next step in strengthening my ability to think beyond coding and focus on building well-structured, scalable, and maintainable software systems.

What This Course is About

CS 343 covers a wide range of essential topics in modern software development, including:

  • Design principles such as abstraction, encapsulation, inheritance, and polymorphism.
  • Best practices like SOLID, DRY (“Don’t Repeat Yourself”), and YAGNI (“You Ain’t Gonna Need It”).
  • Design patterns that provide reusable solutions to common problems.
  • Software architectures and frameworks, including REST API design.
  • Refactoring, code smells, and concurrency, which improve software quality and longevity.
  • Modeling and documentation tools like UML, which ensure clear communication of design decisions.

In short, this course is not just about writing code, it’s about learning to think like a software engineer who can approach problems critically, design solutions thoughtfully, and work effectively with others.

Skills and Outcomes

Through CS 343, I will gain valuable experience in:

  • Collaborating with stakeholders to design, test, and deliver software systems.
  • Applying professional judgment and staying current with evolving tools and practices.
  • Organizing projects using proven methodologies and team processes.
  • Communicating complex technical concepts clearly, both in writing and orally.

These outcomes connect directly to the broader goals of my Computer Science major: analyzing problems, building solutions, and developing the professional skills needed to succeed in the field.

Why This Matters to Me

As someone pursuing a career as a software engineer specializing in artificial intelligence, this course will help me strengthen the foundations of software design and architecture that are critical in building intelligent, scalable systems. Beyond my academic goals, I also see a strong connection to my current role as an Automation Developer at The Hanover Insurance Group, where I contribute to projects that rely on thoughtful design, testing, and collaboration. The principles and practices I learn here will make me more effective in my work today while preparing me for even greater responsibilities in the future.

I am eager to reflect on my progress throughout the semester, connect this material with experiences across my other courses, and apply these lessons directly to both my professional role and long-term career.

For me, CS 343 is more than a class, it’s a bridge between where I am now and the kind of innovative, responsible, and skilled software engineer I strive to become. I am also excited to meet everyone in this course and learn from each other as we move forward together. Feel free to reach out if you’d like to connect, collaborate, or study together this semester!

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Understanding Pairwise and Combinatorial Testing

Hello everyone, and welcome back to my weekly blog post! This week, we’re diving into an essential software testing technique: Pairwise and Combinatorial Testing. These methods help testers create effective test cases without needing to check every single possible combination of inputs. Similar to most of the test cases selection methods we’ve learned.

To make things more relatable, let’s start with a real-life example from the insurance industry.

A Real-Life Problem: Insurance Policy Testing

Imagine you are working for an insurance company that sells car insurance. Customers can choose different policy options based on:

  1. Car Type: Sedan, SUV, Truck
  2. Driver’s Age: Under 25, 25–50, Over 50
  3. Coverage Type: Basic, Standard, Premium

If we tested every possible combination, we would have:

3 × 3 × 3 = 27 test cases!

This is just for three factors. If we add more, such as driving history, location, or accident records, the number of test cases grows exponentially, making full testing impossible.

So how can we test efficiently while ensuring that all critical scenarios are covered?
That’s where Pairwise and Combinatorial Testing come in!

What is Combinatorial Testing?

Combinatorial Testing is a technique that selects test cases based on different input combinations. Instead of testing all possible inputs, it chooses a smaller set that still covers key interactions between variables.

Example: Combinatorial Testing for Insurance Policies

Instead of testing all 27 cases, we can use combinatorial testing to reduce the number of test cases while still covering important interactions.

A possible set of test cases could be:

Test Case Car Type Driver’s Age Coverage Type
1 Sedan Under 25 Basic
2 SUV 25–50 Standard
3 Truck Over 50 Premium
4 Sedan 25–50 Premium
5 SUV Over 50 Basic
6 Truck Under 25 Standard

This method reduces the number of test cases while ensuring that each factor appears in multiple meaningful combinations.

What is Pairwise Testing?

Pairwise Testing is a type of combinatorial testing where all possible pairs of input values are tested at least once. Research has shown that most defects in software are caused by the interaction of just two variables, so testing all pairs ensures good coverage with fewer test cases.

Example: Pairwise Testing for Insurance Policies

Instead of testing all combinations, we can create a smaller set where every pair of values appears at least once:

Test Case Car Type Driver’s Age Coverage Type
1 Sedan Under 25 Basic
2 Sedan 25–50 Standard
3 SUV Under 25 Premium
4 SUV Over 50 Basic
5 Truck 25–50 Premium
6 Truck Over 50 Standard

Here, every pair (Car Type, Driver’s Age), (Car Type, Coverage Type), and (Driver’s Age, Coverage Type) appears at least once. This means we cover all important interactions with just 6 test cases instead of 27!

Permutations and Combinations in Testing

To understand combinatorial testing better, we need to understand permutations and combinations. These are ways of arranging or selecting elements from a set.

What is a Combination?

A combination is a selection of elements where order does not matter. The formula for combinations is: C(n, r) = n! / [r! * (n – r)!]

where:

  • n is the total number of items
  • r is the number of selected items
  • ! (factorial) means multiplying all numbers down to 1

Example of Combination in Insurance

If an insurance company wants to offer 3 different discounts from a list of 5 available discounts, the number of ways to choose these discounts is: C(5,3)=5!3!(5−3)!

So, there are 10 different ways to choose 3 discounts.


What is a Permutation?

A permutation is an arrangement of elements where order matters. The formula for permutations is: P(n, r) = n! / (n – r)!

where:

  • n is the total number of items
  • r is the number of selected items

Example of Permutation in Insurance

If an insurance company wants to assign 3 priority levels (High, Medium, Low) to 5 claims, the number of ways to arrange these claims is: P(5,3)=5!(5−3)!

So, there are 60 different ways to assign priority levels to 3 claims.


Why Use Pairwise and Combinatorial Testing?

  1. Saves Time and Effort – Testing fewer cases while maintaining coverage.
  2. Covers Critical Scenarios – Ensures every important combination is tested.
  3. Finds Defects Faster – Most bugs are caused by two interacting factors, so pairwise testing helps detect them efficiently.
  4. Reduces Costs – Fewer test cases mean lower testing costs and faster releases.

When Should You Use These Techniques?

  • When a system has many input variables
  • When full exhaustive testing is impractical
  • When you need to find bugs quickly with limited resources
  • When testing insurance, finance, healthcare, and other complex systems

Tools for Pairwise and Combinatorial Testing

To make the process easier, you can use tools like:

  • PICT (Pairwise Independent Combinatorial Testing Tool) – Free from Microsoft
  • Hexawise – A combinatorial test design tool
  • ACTS (Automated Combinatorial Testing for Software) – Developed by NIST

These tools help generate optimized test cases automatically based on pairwise and combinatorial principles.

Conclusion

Pairwise and Combinatorial Testing are powerful techniques that allow testers to find defects efficiently without having to test every possible combination. They save time, reduce costs, and improve software quality.

Next time you’re dealing with multiple input variables, try using Pairwise or Combinatorial Testing to make your testing smarter and more effective!

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Mastering Software Quality: Path Testing and Decision-Based Testing in Real-World Applications

Introduction (GREAT NEWS!!!!)

Hello everyone, I apologize for the delay in posting this week’s blog. I’ve been balancing a lot lately, but I’m excited to share some great news with you. I recently secured a summer internship at Hanover Insurance Group as an automation developer, and I couldn’t be more thrilled! As I dive into this amazing opportunity, I want most of my projects to focus on solving, exploring, or even just addressing challenges within the insurance industry. That’s why this week’s post on Path Testing and Decision-Based Testing will highlight real-world applications in insurance software. Let’s jump in!

How Proven Testing Techniques Ensure Reliability in Insurance Software Systems

In the insurance industry, software systems play a critical role in managing claims, processing policies, and ensuring compliance. Given the complexity of insurance workflows, robust testing is essential to avoid costly errors and enhance customer satisfaction. Two effective testing methods: Path Testing and Decision-Based Testing, are invaluable in achieving high-quality software. Let’s explore these techniques with simple examples and see how they apply to real-world insurance applications.


What is Path Testing?

Ensuring Every Route in the Code is Tested

Path Testing involves checking all possible execution paths within a program to ensure each one functions as expected. This technique is particularly useful in complex systems where different inputs and scenarios lead to various execution routes.

Example:
Consider an insurance claims processing system where a claim can go through multiple steps:

  1. Eligibility Check: Is the policy active?
  2. Coverage Validation: Does the claim fall under covered incidents?
  3. Fraud Check: Are there any red flags?
  4. Approval Process: Does the claim meet all criteria for approval?

Path Testing would generate test cases to ensure every possible scenario is covered, such as:

  • Active policy, valid coverage, no fraud, claim approved (Success)
  • Inactive policy (Failure)
  • Valid policy but uncovered incident (Failure)
  • Fraud detected (Failure)

What is Decision-Based Testing?

Validating Every Decision Made by the Software

Decision-Based Testing (also known as Branch Testing) focuses on testing each decision point in the code, such as conditional statements and logic branches.

Example:
In the same insurance claims system, the decision to approve or deny a claim might depend on multiple conditions:

 ClaimCheck(isPolicyActive) {
if (isCoveredIncident) {
if (!isFraudulent) {
System.out.println("Claim Approved");
} else {
System.out.println("Claim Denied: Fraud Detected");
}
} else {
System.out.println("Claim Denied: Uncovered Incident");
}
} else {
System.out.println("Claim Denied: Inactive Policy");
}

Decision-Based Testing would create test cases to cover all possible outcomes:

  • Active policy, covered incident, no fraud (Approved)
  • Active policy, covered incident, fraud detected (Denied)
  • Active policy, uncovered incident (Denied)
  • Inactive policy (Denied)

Real-World Application: Insurance Claims Processing Systems

Why Insurance Software?
Insurance software involves complex business rules and multiple decision points. Errors in these systems can lead to mismanagement of claims, financial losses, or regulatory issues.

How Are These Testing Techniques Used?

  1. Path Testing: Ensures that all possible claim processing scenarios are thoroughly tested, including edge cases like expired policies or unusual claim amounts.
  2. Decision-Based Testing: Validates that all critical decisions, such as fraud detection or policy eligibility, are handled accurately by the system.

Example Scenario:
An insurance company uses a claims management system that automatically processes thousands of claims daily. Path Testing would ensure that every possible claim scenario is tested, while Decision-Based Testing would verify that all decision points, such as flagging a claim for manual review, function correctly.


Key Differences Between Path Testing and Decision-Based Testing

Aspect Path Testing Decision-Based Testing
Focus All possible execution paths Each decision point (branches)
Best For Complex insurance workflows Policy validation and claim decisions
Example Application Claims processing systems Fraud detection and approvals

Conclusion: Delivering Reliable Insurance Software with Strategic Testing

For software engineers working in the insurance industry, combining Path Testing and Decision-Based Testing is crucial. These techniques ensure the software is well-equipped to handle every possible scenario and make accurate decisions in policy and claims management. By implementing these robust testing strategies, insurance companies can boost efficiency, reduce errors, and maintain compliance with regulatory standards.

For further exploration, consider:

Software-testing-laboon-ebook

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

The Intersection of Manual Testing, Automated Testing, Equivalence Class Testing, and Security Testing

Hello guys, welcome to my second blog. In my previous blog, I explored JUnit testing, focusing on boundary value analysis and how to use assert Throws for exception handling in Java. Those concepts helped us understand how to write robust test cases and ensure that our software behaves correctly at its limits.

Building on that foundation, this post expands into a broader discussion of manual vs. automated testing, equivalence class testing, and security testing. These methodologies work together to create a comprehensive testing strategy that ensures software is functional, efficient, and secure.

Introduction

Software testing is a critical part of the software development lifecycle (SDLC). Among the various testing methodologies, manual testing, automated testing, equivalence class testing, and security testing play vital roles in ensuring software reliability, performance, and security. This article explores these techniques, their strengths, and how they work together.

Manual vs. Automated Testing

Testing software can be broadly categorized into manual testing and automated testing. Each approach serves specific purposes and has its advantages.

Manual Testing

Manual testing involves human testers executing test cases without automation tools. It is useful for exploratory testing, usability testing, and cases requiring human judgment.

Pros:

  • Suitable for UI/UX testing and exploratory testing
  • Requires no programming skills
  • Provides a human perspective on software quality

Cons:

  • Time-consuming and repetitive
  • Prone to human errors
  • Inefficient for large-scale projects

Automated Testing

Automated testing uses scripts and testing frameworks to execute test cases automatically. It is ideal for regression testing and performance testing.

Pros:

  • Faster execution and scalable for large projects
  • Reduces human errors
  • Works well with continuous integration/continuous deployment (CI/CD)

Cons:

  • High initial setup cost
  • Requires programming expertise
  • Not suitable for exploratory testing

Example: Java Automated Test Using Selenium

Here is a basic example of using Java to automate a test: I have a simple Calculator class and an Add method. There is a test that runs without human intervention once executed

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class CalculatorTest {
    @Test
    public void testAddition() {
        Calculator calculator = new Calculator();
        int result = calculator.add(2, 3);
        assertEquals(5, result); 
    }
}

Equivalence Class Testing

Equivalence Class Testing (ECT) is a black-box testing technique that reduces the number of test cases while ensuring comprehensive test coverage. It divides input data into equivalence classes, where each class represents similar expected outcomes.

How It Works:

  • Identify input conditions
  • Categorize inputs into equivalence classes (valid and invalid)
  • Select one representative input from each class for testing

Example: Equivalence Class Testing in Java

Consider a function that validates age input:

public class AgeValidator {
    public static String validateAge(int age) {
        if (age >= 18 && age <= 60) {
            return "Valid Age";
        } else {
            return "Invalid Age";
        }
    }

    public static void main(String[] args) {
        System.out.println(validateAge(25)); // Valid input class
        System.out.println(validateAge(17)); // Invalid input class
        System.out.println(validateAge(61)); // Invalid input class
    }
}

Security Testing: A Critical Component

Security testing ensures that applications are protected against cyber threats. This is increasingly crucial with rising cyberattacks and data breaches.

Key Security Testing Techniques:

  • Penetration Testing: Simulating cyberattacks to identify vulnerabilities.
  • Static Code Analysis: Reviewing source code for potential security flaws.
  • Dynamic Analysis: Testing a running application for security weaknesses.
  • Fuzz Testing: Inputting random data to identify unexpected behavior.

Example: Basic SQL Injection Test

A common security vulnerability is SQL Injection. Here’s an example of a vulnerable and a secure implementation:

Vulnerable Code:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class SQLInjectionVulnerable {
    public static void getUserData(String userId) {
        try {
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
            Statement stmt = conn.createStatement();
            String query = "SELECT * FROM users WHERE id = " + userId; // Vulnerable to SQL Injection
            ResultSet rs = stmt.executeQuery(query);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Secure Code:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class SQLInjectionSecure {
    public static void getUserData(String userId) {
        try {
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
            String query = "SELECT * FROM users WHERE id = ?";
            PreparedStatement pstmt = conn.prepareStatement(query);
            pstmt.setString(1, userId);
            ResultSet rs = pstmt.executeQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

How These Testing Methods Work Together

Each testing approach contributes uniquely to software quality:

  • Manual and automated testing ensure functional correctness and usability.
  • Equivalence class testing optimizes test case selection.
  • Security testing safeguards applications from threats.

By integrating these methods, development teams can achieve efficiency, reliability, and security in their software products.

Conclusion

A strong testing strategy incorporates manual testing, automated testing, equivalence class testing, and security testing. Leveraging these approaches ensures robust software quality while improving development efficiency.

For further exploration, consider:

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Effective Exception Testing in JUnit 5: Boundary Value Testing and AssertThrows

Introduction

In modern software development, ensuring that a program handles exceptions correctly is crucial for building robust applications. Exception testing in JUnit 5 allows developers to verify that their code properly handles error scenarios, improving reliability and maintainability. This blog post explores key techniques such as Testing for Exceptions in JUnit 5, Boundary Value Testing, and using AssertThrows to create effective test cases.

Testing for Exceptions in JUnit 5

JUnit 5 provides a streamlined way to test exceptions in Java applications. Unlike JUnit 4, which required using the expected attribute or @Rule, JUnit 5 introduces Assertions.assertThrows(), offering a more flexible and readable approach.

Example of Exception Testing in JUnit 5

Consider a method that calculates the square root of a number. If a negative number is provided, it should throw an IllegalArgumentException.

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class MathUtilsTest {

    double calculateSquareRoot(double number) {
        if (number < 0) {
            throw new IllegalArgumentException("Number must be non-negative");
        }
        return Math.sqrt(number);
    }

    @Test
    void testCalculateSquareRootException() {
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            calculateSquareRoot(-5);
        });
        assertEquals("Number must be non-negative", exception.getMessage());
    }
}

This test verifies that the method correctly throws an exception when given invalid input, ensuring robustness.

Boundary Value Testing

Boundary Value Testing (BVT) is a technique used to test the limits of input values. It focuses on edge cases, such as minimum and maximum values, where software is most likely to fail.

Example: Boundary Testing for Age Validation

Consider a function that validates a user’s age for registration, allowing only ages between 18 and 65.

boolean isValidAge(int age) {
    return age >= 18 && age <= 65;
}

Boundary tests should check values just inside and just outside the valid range:

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class AgeValidatorTest {
    
    @Test
    void testAgeBoundaries() {
        assertTrue(isValidAge(18)); 
        assertTrue(isValidAge(65));  
        assertFalse(isValidAge(17)); 
        assertFalse(isValidAge(66)); 
    }
}

BVT ensures the system correctly distinguishes between valid and invalid inputs.

Testing for Exceptions with AssertThrows

The assertThrows method in JUnit 5 simplifies exception testing, making tests more readable and maintainable. It helps validate that methods correctly handle invalid inputs by throwing the expected exceptions.

Example: Division by Zero Handling

Consider a simple method that performs division:

int divide(int dividend, int divisor) {
    if (divisor == 0) {
        throw new ArithmeticException("Cannot divide by zero");
    }
    return dividend / divisor;
}

We can use assertThrows to verify proper exception handling:

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class DivisionTest {

    @Test
    void testDivideByZero() {
        ArithmeticException exception = assertThrows(ArithmeticException.class, () -> {
            divide(10, 0);
        });
        assertEquals("Cannot divide by zero", exception.getMessage());
    }
}

This ensures that the division method correctly throws an exception when dividing by zero.

Conclusion

Testing exceptions effectively is a vital part of software quality assurance. JUnit 5’s assertThrows method, combined with Boundary Value Testing, enables developers to create thorough test cases that improve the reliability and robustness of applications. By writing well-structured exception tests, developers can prevent unexpected failures and ensure their applications behave as expected under various conditions.

For further reading, check out:

#JUnit5 #ExceptionTesting #AssertThrows #BoundaryValueTesting

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.

Rick Djouwe’s Blog

Hello, and welcome to my blog!

My name is Woubinwou Djouwe Rick Manuel, but most people call me Rick. I am an undergraduate Computer Science student at Worcester State University, and this blog is dedicated to documenting my journey in CS-443: Software Quality Assurance and Testing.

About Me

I have a strong passion for software engineering and artificial intelligence, and I enjoy working on projects that solve real-world problems. Throughout my academic journey, I have gained experience in web development, Python, Java, C++, and database management. I also have a background in tutoring and mentoring students in math and computer science.

From the blog Rick’s Software Journal by RickDjouwe1 and used with permission of the author. All other rights reserved by the author.