189 lines
6.2 KiB
Python
189 lines
6.2 KiB
Python
|
|
"""卡路里计算测试"""
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from src.vitals.core.calories import (
|
||
|
|
parse_food_description,
|
||
|
|
estimate_meal_calories,
|
||
|
|
estimate_exercise_calories,
|
||
|
|
FOOD_DATABASE,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class TestFoodDatabase:
|
||
|
|
"""食物数据库测试"""
|
||
|
|
|
||
|
|
def test_database_not_empty(self):
|
||
|
|
"""测试数据库不为空"""
|
||
|
|
assert len(FOOD_DATABASE) > 0
|
||
|
|
|
||
|
|
def test_common_foods_exist(self):
|
||
|
|
"""测试常见食物存在"""
|
||
|
|
common_foods = ["米饭", "鸡蛋", "牛奶", "苹果", "鸡胸肉"]
|
||
|
|
for food in common_foods:
|
||
|
|
assert food in FOOD_DATABASE
|
||
|
|
|
||
|
|
def test_food_has_required_fields(self):
|
||
|
|
"""测试食物有必需字段"""
|
||
|
|
for name, data in FOOD_DATABASE.items():
|
||
|
|
assert "calories" in data
|
||
|
|
assert "protein" in data
|
||
|
|
assert "carbs" in data
|
||
|
|
assert "fat" in data
|
||
|
|
assert "serving" in data
|
||
|
|
|
||
|
|
|
||
|
|
class TestParseFoodDescription:
|
||
|
|
"""食物描述解析测试"""
|
||
|
|
|
||
|
|
def test_parse_plus_separated(self):
|
||
|
|
"""测试加号分隔"""
|
||
|
|
items = parse_food_description("燕麦+鸡蛋+牛奶")
|
||
|
|
assert len(items) == 3
|
||
|
|
|
||
|
|
def test_parse_comma_separated(self):
|
||
|
|
"""测试逗号分隔"""
|
||
|
|
items = parse_food_description("米饭,红烧肉,青菜")
|
||
|
|
assert len(items) == 3
|
||
|
|
|
||
|
|
def test_parse_chinese_comma(self):
|
||
|
|
"""测试中文逗号分隔"""
|
||
|
|
items = parse_food_description("米饭,红烧肉,青菜")
|
||
|
|
assert len(items) == 3
|
||
|
|
|
||
|
|
def test_parse_with_quantity(self):
|
||
|
|
"""测试带数量"""
|
||
|
|
items = parse_food_description("2个鸡蛋")
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0]["quantity"] == 2
|
||
|
|
|
||
|
|
def test_parse_chinese_quantity(self):
|
||
|
|
"""测试中文数量"""
|
||
|
|
items = parse_food_description("一碗米饭")
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0]["quantity"] == 1
|
||
|
|
|
||
|
|
def test_parse_half_quantity(self):
|
||
|
|
"""测试半份"""
|
||
|
|
items = parse_food_description("半碗米饭")
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0]["quantity"] == 0.5
|
||
|
|
|
||
|
|
def test_parse_unknown_food(self):
|
||
|
|
"""测试未知食物"""
|
||
|
|
items = parse_food_description("神秘食物")
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0]["calories"] == 0
|
||
|
|
assert items[0]["estimated"] == False
|
||
|
|
|
||
|
|
def test_parse_fuzzy_match(self):
|
||
|
|
"""测试模糊匹配"""
|
||
|
|
items = parse_food_description("炒青菜")
|
||
|
|
assert len(items) == 1
|
||
|
|
assert items[0]["calories"] > 0
|
||
|
|
|
||
|
|
|
||
|
|
class TestEstimateMealCalories:
|
||
|
|
"""餐食卡路里估算测试"""
|
||
|
|
|
||
|
|
def test_single_food(self):
|
||
|
|
"""测试单个食物"""
|
||
|
|
result = estimate_meal_calories("米饭")
|
||
|
|
assert result["total_calories"] > 0
|
||
|
|
assert len(result["items"]) == 1
|
||
|
|
|
||
|
|
def test_multiple_foods(self):
|
||
|
|
"""测试多个食物"""
|
||
|
|
result = estimate_meal_calories("米饭+红烧肉+青菜")
|
||
|
|
assert result["total_calories"] > 0
|
||
|
|
assert len(result["items"]) == 3
|
||
|
|
|
||
|
|
def test_total_is_sum_of_items(self):
|
||
|
|
"""测试总量等于各项之和"""
|
||
|
|
result = estimate_meal_calories("鸡蛋+牛奶")
|
||
|
|
items_sum = sum(item["calories"] for item in result["items"])
|
||
|
|
assert result["total_calories"] == items_sum
|
||
|
|
|
||
|
|
def test_macros_calculated(self):
|
||
|
|
"""测试营养素计算"""
|
||
|
|
result = estimate_meal_calories("鸡胸肉")
|
||
|
|
assert result["total_protein"] > 0
|
||
|
|
assert result["total_carbs"] >= 0
|
||
|
|
assert result["total_fat"] >= 0
|
||
|
|
|
||
|
|
def test_empty_description(self):
|
||
|
|
"""测试空描述"""
|
||
|
|
result = estimate_meal_calories("")
|
||
|
|
assert result["total_calories"] == 0
|
||
|
|
assert len(result["items"]) == 0
|
||
|
|
|
||
|
|
|
||
|
|
class TestEstimateExerciseCalories:
|
||
|
|
"""运动卡路里估算测试"""
|
||
|
|
|
||
|
|
def test_running(self):
|
||
|
|
"""测试跑步"""
|
||
|
|
calories = estimate_exercise_calories("跑步", 30, 70)
|
||
|
|
assert calories > 0
|
||
|
|
|
||
|
|
def test_swimming(self):
|
||
|
|
"""测试游泳"""
|
||
|
|
calories = estimate_exercise_calories("游泳", 30, 70)
|
||
|
|
assert calories > 0
|
||
|
|
|
||
|
|
def test_longer_duration_more_calories(self):
|
||
|
|
"""测试时长越长卡路里越多"""
|
||
|
|
cal_30 = estimate_exercise_calories("跑步", 30, 70)
|
||
|
|
cal_60 = estimate_exercise_calories("跑步", 60, 70)
|
||
|
|
assert cal_60 > cal_30
|
||
|
|
|
||
|
|
def test_heavier_person_more_calories(self):
|
||
|
|
"""测试体重越大卡路里越多"""
|
||
|
|
cal_60kg = estimate_exercise_calories("跑步", 30, 60)
|
||
|
|
cal_80kg = estimate_exercise_calories("跑步", 30, 80)
|
||
|
|
assert cal_80kg > cal_60kg
|
||
|
|
|
||
|
|
def test_unknown_exercise_uses_default(self):
|
||
|
|
"""测试未知运动使用默认值"""
|
||
|
|
calories = estimate_exercise_calories("未知运动", 30, 70)
|
||
|
|
assert calories > 0
|
||
|
|
|
||
|
|
def test_zero_duration(self):
|
||
|
|
"""测试零时长"""
|
||
|
|
calories = estimate_exercise_calories("跑步", 0, 70)
|
||
|
|
assert calories == 0
|
||
|
|
|
||
|
|
def test_different_exercises_different_calories(self):
|
||
|
|
"""测试不同运动不同卡路里"""
|
||
|
|
running = estimate_exercise_calories("跑步", 30, 70)
|
||
|
|
yoga = estimate_exercise_calories("瑜伽", 30, 70)
|
||
|
|
assert running > yoga # 跑步消耗更多
|
||
|
|
|
||
|
|
|
||
|
|
class TestCalorieAccuracy:
|
||
|
|
"""卡路里准确性测试"""
|
||
|
|
|
||
|
|
def test_rice_calories_reasonable(self):
|
||
|
|
"""测试米饭卡路里合理"""
|
||
|
|
result = estimate_meal_calories("一碗米饭")
|
||
|
|
# 一碗米饭约 200-250 卡
|
||
|
|
assert 150 < result["total_calories"] < 300
|
||
|
|
|
||
|
|
def test_egg_calories_reasonable(self):
|
||
|
|
"""测试鸡蛋卡路里合理"""
|
||
|
|
result = estimate_meal_calories("一个鸡蛋")
|
||
|
|
# 一个鸡蛋约 70-90 卡
|
||
|
|
assert 50 < result["total_calories"] < 120
|
||
|
|
|
||
|
|
def test_milk_calories_reasonable(self):
|
||
|
|
"""测试牛奶卡路里合理"""
|
||
|
|
result = estimate_meal_calories("一杯牛奶")
|
||
|
|
# 一杯牛奶 250ml 约 130-150 卡
|
||
|
|
assert 100 < result["total_calories"] < 200
|
||
|
|
|
||
|
|
def test_running_calories_reasonable(self):
|
||
|
|
"""测试跑步卡路里合理"""
|
||
|
|
# 70kg 的人跑步 30 分钟约消耗 300-400 卡
|
||
|
|
calories = estimate_exercise_calories("跑步", 30, 70)
|
||
|
|
assert 200 < calories < 500
|