Menambahkan Unit Testing Pada app/java/src/test[unitest/java/com.example.tiptime/BMICalculatorTest.kt
This commit is contained in:
parent
e1fa621f14
commit
2cbe128a08
@ -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
|
||||
|
||||
---
|
||||
411
app/src/test/java/com.example.tiptime/BMICalculatorTest.kt
Normal file
411
app/src/test/java/com.example.tiptime/BMICalculatorTest.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user