Menambahkan Unit Testing Pada app/java/src/test[unitest/java/com.example.tiptime/BMICalculatorTest.kt

This commit is contained in:
dend 2025-11-06 22:41:12 +07:00
parent e1fa621f14
commit 2cbe128a08
2 changed files with 414 additions and 2 deletions

View File

@ -19,6 +19,9 @@ Starter dimodifikasi dan terinspirasi dari:
https://developer.android.com/codelabs/basic-android-compose-calculate-tip#0
---
Dibantu oleh [Claude AI](https://claude.ai):
-Untuk Mengatasi Nan
-Modifikasi Tampilan UI Dan UX
## 🔄 Changelog - Perubahan dari Awal sampai Akhir
@ -199,7 +202,5 @@ data class BMIResult(
- [ ] Rekomendasi diet dan olahraga
- [ ] Export hasil ke PDF
- [ ] Multi-language support
- [ ] Dark mode toggle
- [ ] BMI ideal calculator berdasarkan usia dan gender
---

View File

@ -0,0 +1,411 @@
package com.example.tiptime
import org.junit.Test
import org.junit.Assert.*
import org.junit.Before
/**
* Unit Testing untuk BMI Calculator
*
* NPM: [202310715051]
* Nama: [Dendi Yogia Pratama]
*/
class BMICalculatorTest {
// Test Data Class BMIResult
@Test
fun `BMIResult should store values correctly`() {
val result = BMIResult(
bmiValue = 22.5,
category = "Normal weight",
isValid = true,
errorMessage = ""
)
assertEquals(22.5, result.bmiValue, 0.01)
assertEquals("Normal weight", result.category)
assertTrue(result.isValid)
assertEquals("", result.errorMessage)
}
@Test
fun `BMIResult should handle invalid state`() {
val result = BMIResult(
bmiValue = 0.0,
category = "",
isValid = false,
errorMessage = "Invalid input"
)
assertFalse(result.isValid)
assertEquals("Invalid input", result.errorMessage)
}
// Test BMI Category Function
@Test
fun `getBMICategory should return Underweight for BMI less than 18-5`() {
assertEquals("Underweight", getBMICategory(15.0))
assertEquals("Underweight", getBMICategory(18.0))
assertEquals("Underweight", getBMICategory(18.4))
}
@Test
fun `getBMICategory should return Normal weight for BMI 18-5 to 24-9`() {
assertEquals("Normal weight", getBMICategory(18.5))
assertEquals("Normal weight", getBMICategory(20.0))
assertEquals("Normal weight", getBMICategory(24.9))
}
@Test
fun `getBMICategory should return Overweight for BMI 25 to 29-9`() {
assertEquals("Overweight", getBMICategory(25.0))
assertEquals("Overweight", getBMICategory(27.5))
assertEquals("Overweight", getBMICategory(29.9))
}
@Test
fun `getBMICategory should return Obese for BMI 30 and above`() {
assertEquals("Obese", getBMICategory(30.0))
assertEquals("Obese", getBMICategory(35.0))
assertEquals("Obese", getBMICategory(40.0))
}
// Test SI Units BMI Calculation
@Test
fun `calculateBMI should calculate correctly for SI units - Normal weight`() {
val result = calculateBMI(170.0, 65.0, false)
assertTrue(result.isValid)
assertEquals(22.49, result.bmiValue, 0.01)
assertEquals("Normal weight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for SI units - Underweight`() {
val result = calculateBMI(175.0, 55.0, false)
assertTrue(result.isValid)
assertEquals(17.96, result.bmiValue, 0.01)
assertEquals("Underweight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for SI units - Overweight`() {
val result = calculateBMI(160.0, 70.0, false)
assertTrue(result.isValid)
assertEquals(27.34, result.bmiValue, 0.01)
assertEquals("Overweight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for SI units - Obese`() {
val result = calculateBMI(165.0, 85.0, false)
assertTrue(result.isValid)
assertEquals(31.22, result.bmiValue, 0.01)
assertEquals("Obese", result.category)
}
// Test USC Units BMI Calculation
@Test
fun `calculateBMI should calculate correctly for USC units - Normal weight`() {
val result = calculateBMI(67.0, 143.0, true)
assertTrue(result.isValid)
assertEquals(22.39, result.bmiValue, 0.01)
assertEquals("Normal weight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for USC units - Underweight`() {
val result = calculateBMI(69.0, 120.0, true)
assertTrue(result.isValid)
assertEquals(17.72, result.bmiValue, 0.01)
assertEquals("Underweight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for USC units - Overweight`() {
val result = calculateBMI(63.0, 154.0, true)
assertTrue(result.isValid)
assertEquals(27.31, result.bmiValue, 0.01)
assertEquals("Overweight", result.category)
}
@Test
fun `calculateBMI should calculate correctly for USC units - Obese`() {
val result = calculateBMI(65.0, 200.0, true)
assertTrue(result.isValid)
assertEquals(33.29, result.bmiValue, 0.01)
assertEquals("Obese", result.category)
}
// Test Input Validation - SI Units
@Test
fun `validateBMIInput should reject zero height for SI units`() {
val (isValid, message) = validateBMIInput(0.0, 70.0, false)
assertFalse(isValid)
assertEquals("Tinggi harus lebih dari 0", message)
}
@Test
fun `validateBMIInput should reject negative height for SI units`() {
val (isValid, message) = validateBMIInput(-10.0, 70.0, false)
assertFalse(isValid)
assertEquals("Tinggi harus lebih dari 0", message)
}
@Test
fun `validateBMIInput should reject height below 50cm for SI units`() {
val (isValid, message) = validateBMIInput(45.0, 70.0, false)
assertFalse(isValid)
assertEquals("Tinggi terlalu rendah (minimum 50cm)", message)
}
@Test
fun `validateBMIInput should reject height above 300cm for SI units`() {
val (isValid, message) = validateBMIInput(350.0, 70.0, false)
assertFalse(isValid)
assertEquals("Tinggi tidak wajar (maksimum 300cm)", message)
}
@Test
fun `validateBMIInput should reject zero weight for SI units`() {
val (isValid, message) = validateBMIInput(170.0, 0.0, false)
assertFalse(isValid)
assertEquals("Berat harus lebih dari 0", message)
}
@Test
fun `validateBMIInput should reject weight below 20kg for SI units`() {
val (isValid, message) = validateBMIInput(170.0, 15.0, false)
assertFalse(isValid)
assertEquals("Berat terlalu rendah (minimum 20kg)", message)
}
@Test
fun `validateBMIInput should reject weight above 500kg for SI units`() {
val (isValid, message) = validateBMIInput(170.0, 550.0, false)
assertFalse(isValid)
assertEquals("Berat tidak wajar (maksimum 500kg)", message)
}
@Test
fun `validateBMIInput should accept valid SI units`() {
val (isValid, message) = validateBMIInput(170.0, 70.0, false)
assertTrue(isValid)
assertEquals("", message)
}
// Test Input Validation - USC Units
@Test
fun `validateBMIInput should reject zero height for USC units`() {
val (isValid, message) = validateBMIInput(0.0, 150.0, true)
assertFalse(isValid)
assertEquals("Height must be greater than 0", message)
}
@Test
fun `validateBMIInput should reject height below 20 inches for USC units`() {
val (isValid, message) = validateBMIInput(15.0, 150.0, true)
assertFalse(isValid)
assertEquals("Height too low (minimum 20 inches)", message)
}
@Test
fun `validateBMIInput should reject height above 120 inches for USC units`() {
val (isValid, message) = validateBMIInput(130.0, 150.0, true)
assertFalse(isValid)
assertEquals("Height unrealistic (maximum 120 inches)", message)
}
@Test
fun `validateBMIInput should reject weight below 44 lbs for USC units`() {
val (isValid, message) = validateBMIInput(65.0, 40.0, true)
assertFalse(isValid)
assertEquals("Weight too low (minimum 44 lbs)", message)
}
@Test
fun `validateBMIInput should reject weight above 1100 lbs for USC units`() {
val (isValid, message) = validateBMIInput(65.0, 1200.0, true)
assertFalse(isValid)
assertEquals("Weight unrealistic (maximum 1100 lbs)", message)
}
@Test
fun `validateBMIInput should accept valid USC units`() {
val (isValid, message) = validateBMIInput(67.0, 150.0, true)
assertTrue(isValid)
assertEquals("", message)
}
// Test BMI Category Info
@Test
fun `getBMICategoryInfo should return correct info for Underweight`() {
val info = getBMICategoryInfo("Underweight")
assertTrue(info.contains("kurang dari ideal"))
}
@Test
fun `getBMICategoryInfo should return correct info for Normal weight`() {
val info = getBMICategoryInfo("Normal weight")
assertTrue(info.contains("Selamat"))
assertTrue(info.contains("ideal"))
}
@Test
fun `getBMICategoryInfo should return correct info for Overweight`() {
val info = getBMICategoryInfo("Overweight")
assertTrue(info.contains("berlebih"))
}
@Test
fun `getBMICategoryInfo should return correct info for Obese`() {
val info = getBMICategoryInfo("Obese")
assertTrue(info.contains("berlebih"))
assertTrue(info.contains("dokter"))
}
// Test BMI Category Color
@Test
fun `getBMICategoryColor should return correct colors`() {
assertNotNull(getBMICategoryColor("Underweight"))
assertNotNull(getBMICategoryColor("Normal weight"))
assertNotNull(getBMICategoryColor("Overweight"))
assertNotNull(getBMICategoryColor("Obese"))
}
// Test Category Emoji
@Test
fun `getCategoryEmoji should return correct emojis`() {
assertEquals("⚠️", getCategoryEmoji("Underweight"))
assertEquals("", getCategoryEmoji("Normal weight"))
assertEquals("", getCategoryEmoji("Overweight"))
assertEquals("🔴", getCategoryEmoji("Obese"))
assertEquals("", getCategoryEmoji("Unknown"))
}
// Test Format BMI Result
@Test
fun `formatBMIResult should format valid result correctly`() {
val result = BMIResult(22.486, "Normal weight", true, "")
val formatted = formatBMIResult(result)
assertTrue(formatted.contains("22") || formatted.contains("22,5"))
}
@Test
fun `formatBMIResult should return error message for invalid result`() {
val result = BMIResult(0.0, "", false, "Error message")
val formatted = formatBMIResult(result)
assertEquals("Error message", formatted)
}
// Edge Cases
@Test
fun `calculateBMI should handle boundary value BMI 18-5 exactly`() {
// Height and weight that should give BMI exactly 18.5
val result = calculateBMI(175.0, 56.66, false)
assertTrue(result.bmiValue >= 18.4 && result.bmiValue <= 18.6)
}
@Test
fun `calculateBMI should handle boundary value BMI 25-0 exactly`() {
// Height and weight that should give BMI exactly 25.0
val result = calculateBMI(170.0, 72.25, false)
assertTrue(result.bmiValue >= 24.9 && result.bmiValue <= 25.1)
}
@Test
fun `calculateBMI should handle boundary value BMI 30-0 exactly`() {
// Height and weight that should give BMI exactly 30.0
val result = calculateBMI(170.0, 86.7, false)
assertTrue(result.bmiValue >= 29.9 && result.bmiValue <= 30.1)
}
// Integration Tests
@Test
fun `full flow SI units should work correctly`() {
val height = 175.0
val weight = 70.0
// Validate
val (isValid, _) = validateBMIInput(height, weight, false)
assertTrue(isValid)
// Calculate
val result = calculateBMI(height, weight, false)
assertTrue(result.isValid)
assertEquals("Normal weight", result.category)
// Format
val formatted = formatBMIResult(result)
assertTrue(formatted.isNotEmpty())
// Get info
val info = getBMICategoryInfo(result.category)
assertTrue(info.isNotEmpty())
}
@Test
fun `full flow USC units should work correctly`() {
val height = 69.0
val weight = 154.0
// Validate
val (isValid, _) = validateBMIInput(height, weight, true)
assertTrue(isValid)
// Calculate
val result = calculateBMI(height, weight, true)
assertTrue(result.isValid)
assertTrue(result.category.isNotEmpty())
// Format
val formatted = formatBMIResult(result)
assertTrue(formatted.isNotEmpty())
}
@Test
fun `calculateBMI should return invalid result for invalid input`() {
val result = calculateBMI(-10.0, 70.0, false)
assertFalse(result.isValid)
assertTrue(result.errorMessage.isNotEmpty())
assertEquals(0.0, result.bmiValue, 0.01)
}
// Accuracy Tests
@Test
fun `BMI calculation should be accurate for SI units`() {
// Manual calculation: 75 / (1.80 * 1.80) = 23.148
val result = calculateBMI(180.0, 75.0, false)
assertEquals(23.15, result.bmiValue, 0.01)
}
@Test
fun `BMI calculation should be accurate for USC units`() {
// Manual calculation: 703 * (170 / (70 * 70)) = 24.39
val result = calculateBMI(70.0, 170.0, true)
assertEquals(24.39, result.bmiValue, 0.01)
}
}