All checks were successful
Deploy Development / deploy (push) Successful in 42s
Test Suite / pytest-backend (push) Successful in 38s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m27s
- Enhanced the skill scoring system with category grouping and a universal scale for improved comparability across programs. - Introduced new calculations for artifact share percentage and universal percent, allowing for a more nuanced understanding of skill contributions. - Updated the API to reflect changes in the skill profile structure, including main category and top skill details. - Improved frontend components to display skills by main category, enhancing user experience in skill discovery and profile visualization. - Adjusted tests to validate the new scoring logic and ensure accurate representation of skills and their weights.
118 lines
3.9 KiB
Python
118 lines
3.9 KiB
Python
"""Unit-Tests für gewichtetes Fähigkeiten-Scoring (Phase 3)."""
|
|
from skill_scoring import (
|
|
ExerciseOccurrence,
|
|
compute_skill_profile,
|
|
match_score_for_skill_ids,
|
|
_level_range_multiplier,
|
|
_skill_link_multiplier,
|
|
)
|
|
|
|
|
|
def test_skill_link_multiplier_intensity_and_levels():
|
|
assert _skill_link_multiplier(intensity="hoch") == 1.2
|
|
assert _skill_link_multiplier(intensity="niedrig") == 0.85
|
|
wide = _skill_link_multiplier(
|
|
intensity="mittel",
|
|
required_level="basis",
|
|
target_level="optimierung",
|
|
)
|
|
narrow = _skill_link_multiplier(
|
|
intensity="mittel",
|
|
required_level="grundlagen",
|
|
target_level="grundlagen",
|
|
)
|
|
assert wide > narrow
|
|
|
|
|
|
def test_level_range_multiplier_span():
|
|
assert _level_range_multiplier(None, None) == 1.0
|
|
assert _level_range_multiplier("aufbau", "fortgeschritten") > _level_range_multiplier("basis", "basis")
|
|
|
|
|
|
def test_compute_skill_profile_aggregates_weights():
|
|
occurrences = [
|
|
ExerciseOccurrence(exercise_id=1, planned_duration_min=60),
|
|
ExerciseOccurrence(exercise_id=1, planned_duration_min=30),
|
|
]
|
|
skills_map = {
|
|
1: [
|
|
{
|
|
"skill_id": 10,
|
|
"skill_name": "Distanz",
|
|
"category": "kihon",
|
|
"category_id": 1,
|
|
"category_name": "kihon",
|
|
"main_category_id": 100,
|
|
"main_category_name": "Technik",
|
|
"intensity": "hoch",
|
|
"required_level": "grundlagen",
|
|
"target_level": "aufbau",
|
|
"exercise_title": "Übung A",
|
|
},
|
|
{
|
|
"skill_id": 11,
|
|
"skill_name": "Balance",
|
|
"category": "kihon",
|
|
"category_id": 1,
|
|
"category_name": "kihon",
|
|
"main_category_id": 100,
|
|
"main_category_name": "Technik",
|
|
"intensity": "niedrig",
|
|
"required_level": "basis",
|
|
"target_level": "basis",
|
|
"exercise_title": "Übung A",
|
|
},
|
|
],
|
|
}
|
|
profile = compute_skill_profile(occurrences, skills_map)
|
|
assert profile["scoring_version"] == "1.2"
|
|
assert profile["exercise_occurrence_count"] == 2
|
|
assert profile["distinct_exercise_count"] == 1
|
|
assert len(profile["skills"]) == 2
|
|
assert profile["skills"][0]["skill_id"] == 10
|
|
assert profile["total_weight"] > profile["skills"][1]["weight"]
|
|
assert abs(sum(s["share_percent"] for s in profile["skills"]) - 100.0) < 0.1
|
|
assert len(profile["by_main_category"]) == 1
|
|
assert profile["by_main_category"][0]["categories"][0]["top_skill"]["skill_id"] == 10
|
|
|
|
|
|
def test_universal_percent_against_corpus_max():
|
|
occurrences = [ExerciseOccurrence(exercise_id=1, planned_duration_min=50)]
|
|
skills_map = {
|
|
1: [
|
|
{
|
|
"skill_id": 10,
|
|
"skill_name": "Koordination",
|
|
"category_name": "Koordination",
|
|
"category_id": 2,
|
|
"main_category_id": 200,
|
|
"main_category_name": "Körper",
|
|
},
|
|
],
|
|
}
|
|
profile = compute_skill_profile(
|
|
occurrences,
|
|
skills_map,
|
|
reference_max_by_skill={10: 100.0},
|
|
)
|
|
assert profile["has_reference_scale"] is True
|
|
assert profile["skills"][0]["universal_percent"] == 50.0
|
|
top = profile["by_main_category"][0]["categories"][0]["top_skill"]
|
|
assert top["universal_percent"] == 50.0
|
|
|
|
|
|
def test_match_score_for_skill_ids():
|
|
profile = {
|
|
"total_weight": 100.0,
|
|
"skills": [
|
|
{"skill_id": 1, "skill_name": "A", "weight": 40.0},
|
|
{"skill_id": 2, "skill_name": "B", "weight": 60.0},
|
|
],
|
|
}
|
|
m = match_score_for_skill_ids(profile, [1])
|
|
assert m["match_weight"] == 40.0
|
|
assert m["match_score"] == 40.0
|
|
assert m["match_percent"] == 40.0
|
|
assert m["artifact_focus_percent"] == 40.0
|
|
assert m["matched_skill_ids"] == [1]
|