This project demonstrates a simple Java calculator application with comprehensive unit testing using JUnit 5. It showcases best practices for unit testing, Maven project structure, and test-driven development.
The SimpleCalculator project implements basic arithmetic operations (addition and multiplication) with support for variable arguments (varargs). Each operation is thoroughly tested using JUnit 5 framework to ensure reliability and correctness.
SimpleCalculator-unit-Testing-/
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── org/
│ └── example/
│ ├── Main.java
│ └── SimpleCalculator.java
└── test/
└── java/
└── org/
└── example/
└── SimpleCalculatorTest.java
pom.xml: Maven configuration file with JUnit 5 dependenciesSimpleCalculator.java: Main calculator class with arithmetic operationsMain.java: Application entry point (optional)SimpleCalculatorTest.java: Comprehensive unit tests for calculator operations
- Addition: Supports adding multiple numbers using varargs
- Multiplication: Supports multiplying multiple numbers using varargs
- Comprehensive Testing: Full test coverage with edge cases
- Maven Integration: Standard Maven project structure
- JUnit 5: Modern testing framework with advanced assertions
- Java JDK 23 (as configured in pom.xml) or compatible version
- Maven 3.6+ for build management
- IDE (IntelliJ IDEA, Eclipse, or VS Code with Java extensions)
# Check if Java is installed
java -version
# If not installed, download from:
# https://www.oracle.com/java/technologies/downloads/
# or use package manager like Chocolatey:
choco install openjdk# Check if Maven is installed
mvn -version
# If not installed, download from:
# https://maven.apache.org/download.cgi
# or use Chocolatey:
choco install maven# Clone or download the project
cd "c:\Users\mamas\OneDrive\Documents\wipro\SimpleCalculator-unit-Testing-"
# Download dependencies and compile
mvn clean compile# Run all tests
mvn test
# Run tests with detailed output
mvn test -Dtest.verbose=trueExpected Output:
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.example.SimpleCalculatorTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
# Run specific test class
mvn test -Dtest=SimpleCalculatorTest
# Run specific test method
mvn test -Dtest=SimpleCalculatorTest#multipleNumbersShouldSumCorrectlyAdd
# Run multiple specific methods
mvn test -Dtest=SimpleCalculatorTest#multipleNumbersShouldSumCorrectlyAdd,multipleNumbersShouldSumCorrectlyMultiply# Generate detailed test reports
mvn surefire-report:report
# View reports (generated in target/site/surefire-report.html)
start target\site\surefire-report.htmlThe SimpleCalculatorTest.java contains two main test methods:
@Test
void multipleNumbersShouldSumCorrectlyAdd() {
var calculator = new SimpleCalculator();
// Test cases covered:
assertEquals(3, calculator.add(1, 2)); // Basic addition
assertEquals(-2, calculator.add(-1, -1)); // Negative numbers
assertEquals(15, calculator.add(1, 2, 3, 4, 5)); // Multiple numbers
assertEquals(4, calculator.add(-4, 8)); // Mixed positive/negative
}Test Scenarios:
- ✅ Two positive numbers
- ✅ Two negative numbers
- ✅ Multiple numbers (varargs)
- ✅ Mixed positive and negative numbers
@Test
void multipleNumbersShouldSumCorrectlyMultiply() {
var calculator = new SimpleCalculator();
// Test cases covered:
assertEquals(3, calculator.multiply(1, 3)); // Basic multiplication
assertEquals(-3, calculator.multiply(-1, 3)); // Negative numbers
assertEquals(120, calculator.multiply(1, 2, 3, 4, 5)); // Multiple numbers
}Test Scenarios:
- ✅ Two positive numbers
- ✅ Positive and negative numbers
- ✅ Multiple numbers (factorial-like: 1×2×3×4×5 = 120)
- Setup: JUnit creates a new test instance for each test method
- Execution: Each
@Testmethod runs independently - Assertion:
assertEquals()compares expected vs actual results - Reporting: Results are collected and reported by Maven Surefire
# 1. Write a failing test first
# 2. Run tests to see it fail
mvn test
# 3. Implement minimal code to make test pass
# 4. Run tests again
mvn test
# 5. Refactor if needed
# 6. Repeat cycleStep 1: Add test method to SimpleCalculatorTest.java
@Test
void multipleNumbersShouldSubtractCorrectly() {
var calculator = new SimpleCalculator();
assertEquals(1, calculator.subtract(3, 2));
assertEquals(-1, calculator.subtract(2, 3));
assertEquals(0, calculator.subtract(5, 2, 3)); // 5-2-3=0
}Step 2: Run test (should fail)
mvn testStep 3: Implement method in SimpleCalculator.java
public int subtract(int... numbers) {
if (numbers.length == 0) return 0;
int result = numbers[0];
for (int i = 1; i < numbers.length; i++) {
result -= numbers[i];
}
return result;
}Step 4: Run test again (should pass)
mvn testAdd JaCoCo plugin to pom.xml:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>Run with coverage:
mvn clean test jacoco:report
# View coverage report: target/site/jacoco/index.html@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void additionWithSingleNumber(int number) {
assertEquals(number, calculator.add(number));
}class SimpleCalculatorTest {
private SimpleCalculator calculator;
@BeforeEach
void setUp() {
calculator = new SimpleCalculator();
}
@AfterEach
void tearDown() {
// Cleanup if needed
}
}# Problem: Maven can't find tests
# Solution: Ensure proper directory structure
mvn clean compile test-compile test# Problem: Multiple JUnit versions in pom.xml
# Solution: Clean up duplicate dependencies
mvn dependency:tree | findstr junit# Problem: Compiler source/target mismatch
# Solution: Verify Java version matches pom.xml
java -version
mvn -version# Set Maven memory options
set MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=256m
mvn test- Import as Maven project
- Right-click test class → "Run SimpleCalculatorTest"
- View test results in run window
- Generate coverage reports: Run → Run with Coverage
- Install Java Extension Pack
- Open project folder
- Use Test Explorer to run tests
- View results in integrated terminal
- Import → Existing Maven Projects
- Right-click test class → Run As → JUnit Test
- View results in JUnit view
- Clear Test Names: Descriptive method names explaining what is being tested
- Multiple Assertions: Testing various scenarios in each test method
- Edge Cases: Testing with negative numbers, zero, and multiple parameters
- Isolation: Each test method is independent and can run alone
- AAA Pattern: Arrange (setup), Act (execute), Assert (verify)
@Test
void performanceTest() {
var calculator = new SimpleCalculator();
long startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
calculator.add(1, 2, 3, 4, 5);
}
long duration = System.nanoTime() - startTime;
assertTrue(duration < 1000000000); // Should complete in under 1 second
}- Molemo Mamashela
Last updated: July 6, 2025