This repository contains three separate Java service applications developed to learn: Software Testing, Automation, and Quality Assurance. They demonstrate how to design small, focused applications and verify strict input validation and requirements through unit testing and other testing strategies.
These applications document the importance of testing in building reliable software by validating requirements early and preventing defects. It strengthened my understanding of testing as a fundamental part of software development and long-term maintainability.
The Contact, Task, and Appointment services are responsible for creating, updating, and managing objects while enforcing defined requirements. Each service is fully tested using JUnit, with test cases covering valid, invalid, and edge cases to ensure correct behavior. These applications and tests emphasize test-driven thinking, object-oriented design, and defensive programming. Correctness, reliability, and maintainability are the primary focus rather than the user interface.
A comprehensive write-up for this project can be found at: Project Reflection (PDF)
- Java
- Junit 5
- Unit Testing
- Object-Oriented Programming (OOP)
- Defensive Programming
- Requirements Analysis
- Maintainability and Code Quality
- Open any Java IDE
- Make a new Java project
- Import all or any of the service folders
- Add Junit 5 to classpath
Right Clicktest class -> SelectRun As->Junit Test(or use CLI with Junit)
This project showed me the importance of testing in building software and how unit testing and defensive programming support that. Even small mistakes can have big consequences. The key takeaways are:
- Ensuring Quality and Security
- Converting Requirements to Code
- Better approach to software design
I ensure that my software is secure and functional by using unit testing to verify strict input validation. The Task, Contact, and Appointment service constructors and service methods enforce all defined constraints, such as null checks, length limits, and date validation, to prevent invalid instances. The JUnit tests verify correct behavior for valid inputs and ensure that invalid inputs are rejected appropriately. This approach helps identify defects early and ensures that customer requirements are consistently met. The tests and implemented validation logic also reduce the risk of unexpected behavior and improve overall software reliability.
I interpret user needs by carefully analyzing written requirements and translating them into enforceable rules within the code. Each service included specific constraints, such as date ranges and length limits, which I implemented through validation logic in constructors and service methods. I then used JUnit tests to verify that each requirement was enforced correctly. This ensured the program’s logic aligned with customer needs as defined in the project requirements.
I approach software design by breaking problems into small components with clear rules and responsibilities. Each of the service applications was developed independently, allowing me to focus on improving test quality and coverage as I went onto the next. I later refactored the earlier services based on what I learned. For each service, I separated object logic from service classes to maintain a clear separation of concerns and follow object-oriented design principles. I designed each class to have a single responsibility, which improves readability and maintainability. I also considered customer requirements during the design process to ensure the implemented logic met defined needs. Additionally, I designed the software with testability in mind, which made it easier to verify behavior and validate requirements through unit testing.
I approach software design by breaking problems into small components with clear rules and responsibilities. Each of the service applications was developed independently, allowing me to focus on improving test quality and coverage as I moved on to the next service. I later refactored the earlier services based on what I learned, which reinforced the value of iterative improvement.