DesenrolaAi / python-basic-pitch /tests /test_report_audio_accuracy_metrics.py
Azure DevOps Pipeline
deploy: Merged PR 26: melhoria no projeto
77bffac
Raw
History Blame Contribute Delete
4.93 kB
import sys
import types
import unittest
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from report_audio_accuracy import CasoAudio, ResultadoAudio, analisar_caso, resumir_resultados
def resultado_teste(**sobrescritas):
valores = {
"filename": "caso.wav",
"instrument": "violao",
"expected": "C N G",
"predicted": "C N N",
"exact_match": False,
"slash_tolerated_match": False,
"rotated_exact_match": False,
"rotated_simplified_match": False,
"rotated_root_match": False,
"musical_match": False,
"token_accuracy": 2 / 3,
"simplified_token_accuracy": 2 / 3,
"root_accuracy": 2 / 3,
"quality_accuracy": 2 / 3,
"full_quality_accuracy": 0.25,
"edit_distance": 1,
"substitutions": 1,
"insertions": 0,
"deletions": 0,
"token_error_rate": 1 / 3,
"no_chord_true_positives": 1,
"no_chord_false_positives": 1,
"no_chord_false_negatives": 0,
"no_chord_true_negatives": 1,
"best_rotation_shift": 0,
"expected_tokens": 3,
"predicted_tokens": 3,
"matched_tokens": 2,
"elapsed_seconds": 0.1,
"diagnostics": {},
}
valores.update(sobrescritas)
return ResultadoAudio(**valores)
class ReportAudioAccuracyMetricsTests(unittest.TestCase):
def test_analisar_caso_converte_gate_no_chord_em_token_somente_no_benchmark(self):
modulo_harmonico = types.ModuleType("harmonic_pipeline")
modulo_harmonico.analyze_harmonic_audio = lambda *_args, **_kwargs: {
"cifra_palco": "",
"diagnostico_harmonico": {
"no_chord_detected": True,
"no_chord_probability": 0.96,
"no_chord_threshold": 0.88,
"no_chord_reasons": ["digital_silence"],
"score_kind": "heuristic_evidence_v1",
},
}
caso = CasoAudio(
nome_arquivo="silencio.wav",
esperado="N",
instrumento="violao",
caminho=Path("silencio.wav"),
)
with patch.dict(sys.modules, {"harmonic_pipeline": modulo_harmonico}):
resultado = analisar_caso(caso)
self.assertEqual(resultado.predicted, "N")
self.assertEqual(resultado.no_chord_true_positives, 1)
self.assertEqual(resultado.no_chord_false_negatives, 0)
self.assertTrue(resultado.diagnostics["no_chord_detected"])
def test_agrega_ter_e_no_chord_por_contagens_globais(self):
primeiro = resultado_teste()
segundo = resultado_teste(
filename="outro.wav",
expected="N",
predicted="C",
full_quality_accuracy=0.75,
edit_distance=1,
substitutions=1,
token_error_rate=1.0,
no_chord_true_positives=0,
no_chord_false_positives=0,
no_chord_false_negatives=1,
no_chord_true_negatives=0,
expected_tokens=1,
predicted_tokens=1,
matched_tokens=0,
)
resumo = resumir_resultados([primeiro, segundo])
self.assertEqual(resumo["metrics_schema_version"], "music-token-metrics-v2")
self.assertAlmostEqual(resumo["mean_full_quality_accuracy"], 0.5)
self.assertAlmostEqual(resumo["token_error_rate"], 0.5)
self.assertEqual(
resumo["edit_operations"],
{
"distance": 2,
"substitutions": 2,
"insertions": 0,
"deletions": 0,
"expected_tokens": 4,
},
)
self.assertEqual(resumo["no_chord"]["support"], 2)
self.assertEqual(resumo["no_chord"]["true_positives"], 1)
self.assertEqual(resumo["no_chord"]["false_positives"], 1)
self.assertEqual(resumo["no_chord"]["false_negatives"], 1)
self.assertAlmostEqual(resumo["no_chord"]["precision"], 0.5)
self.assertAlmostEqual(resumo["no_chord"]["recall"], 0.5)
self.assertAlmostEqual(resumo["no_chord"]["f1"], 0.5)
por_instrumento = resumo["by_instrument"]["violao"]
self.assertAlmostEqual(por_instrumento["token_error_rate"], 0.5)
self.assertEqual(por_instrumento["no_chord"]["support"], 2)
def test_resumo_vazio_declara_convencao_de_divisao_por_zero(self):
resumo = resumir_resultados([])
self.assertEqual(resumo["token_error_rate"], 0.0)
self.assertEqual(resumo["no_chord"]["accuracy"], 1.0)
self.assertEqual(resumo["no_chord"]["precision"], 0.0)
self.assertEqual(resumo["no_chord"]["recall"], 0.0)
self.assertEqual(resumo["no_chord"]["f1"], 0.0)
self.assertEqual(resumo["no_chord"]["zero_division"], 0)
if __name__ == "__main__":
unittest.main()