Tests unitarios: 51 tests para compactor, key_data, fingerprint y costes
- tests/test_compactor.py: 24 tests (estimate_tokens, extract_facts, build_summary, summarize_tool_output, compact_sections) - tests/test_key_data_extraction.py: 11 tests (extracción de tables, records, sections, modules, pages desde tool executions) - tests/test_fingerprint.py: 8 tests (deduplicación MD5, sort_keys, nested args) - tests/test_cost_calculation.py: 8 tests (pricing formula, custom pricing, rounding) - README.md: sección Tests con instrucciones de ejecución Todos offline, sin Docker/Redis/LLM. Ejecutar: python3 -m pytest tests/ -v Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
tests/test_cost_calculation.py
Normal file
71
tests/test_cost_calculation.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Tests para el calculo de costes del orquestador.
|
||||
|
||||
Replica la formula de coste de OrchestratorEngine._run_pipeline():
|
||||
cost_usd = (input_tokens / 1_000_000) * cost_per_1m_input
|
||||
+ (output_tokens / 1_000_000) * cost_per_1m_output
|
||||
|
||||
Defaults: cost_per_1m_input=2.50, cost_per_1m_output=15.00
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def calculate_cost(
|
||||
input_tokens: int,
|
||||
output_tokens: int,
|
||||
cost_per_1m_input: float = 2.50,
|
||||
cost_per_1m_output: float = 15.00,
|
||||
) -> float:
|
||||
"""Replica exacta de la formula de coste en engine.py."""
|
||||
return (
|
||||
(input_tokens / 1_000_000) * cost_per_1m_input
|
||||
+ (output_tokens / 1_000_000) * cost_per_1m_output
|
||||
)
|
||||
|
||||
|
||||
class TestCostCalculation:
|
||||
def test_1m_input_tokens(self):
|
||||
cost = calculate_cost(1_000_000, 0)
|
||||
assert cost == pytest.approx(2.50)
|
||||
|
||||
def test_1m_output_tokens(self):
|
||||
cost = calculate_cost(0, 1_000_000)
|
||||
assert cost == pytest.approx(15.00)
|
||||
|
||||
def test_500k_input_100k_output(self):
|
||||
cost = calculate_cost(500_000, 100_000)
|
||||
# (500_000 / 1_000_000) * 2.50 + (100_000 / 1_000_000) * 15.00
|
||||
# = 1.25 + 1.50 = 2.75
|
||||
assert cost == pytest.approx(2.75)
|
||||
|
||||
def test_zero_tokens(self):
|
||||
cost = calculate_cost(0, 0)
|
||||
assert cost == 0.0
|
||||
|
||||
def test_custom_pricing(self):
|
||||
cost = calculate_cost(
|
||||
1_000_000, 1_000_000,
|
||||
cost_per_1m_input=3.00,
|
||||
cost_per_1m_output=10.00,
|
||||
)
|
||||
assert cost == pytest.approx(13.00)
|
||||
|
||||
def test_small_token_count(self):
|
||||
"""Pocos tokens = coste muy bajo pero no cero."""
|
||||
cost = calculate_cost(100, 50)
|
||||
assert cost > 0
|
||||
assert cost < 0.01
|
||||
|
||||
def test_round_to_6_decimals(self):
|
||||
"""El engine hace round(cost_usd, 6)."""
|
||||
cost = calculate_cost(1, 1)
|
||||
rounded = round(cost, 6)
|
||||
# (1/1M)*2.50 + (1/1M)*15.00 = 1.75e-05
|
||||
# round(1.75e-05, 6) = 1.7e-05 (banker's rounding: 5 rounds to even)
|
||||
assert rounded == pytest.approx(0.000017, abs=1e-7)
|
||||
|
||||
def test_output_more_expensive_than_input(self):
|
||||
"""Con defaults, output es 6x mas caro que input."""
|
||||
input_cost = calculate_cost(1_000_000, 0)
|
||||
output_cost = calculate_cost(0, 1_000_000)
|
||||
assert output_cost == pytest.approx(input_cost * 6.0)
|
||||
Reference in New Issue
Block a user