openTARS / app /tests /test_autoteste.py
ProjectOpenTARS4's picture
Mirror of openTARS 5.2 Ranger (revision 2026110101)
2695555 verified
Raw History Blame Contribute Delete
5.06 kB
"""opentars --diagnostico / --autoteste: o relatório que o usuário roda no
PC dele. Aqui o Ollama, a IA e a calculadora são simulados; o que se testa
é que o relatório não quebra em nenhuma situação e que o teste da
calculadora confere o VISOR (não só o que a IA diz)."""
import contextlib
import io
import os
import tempfile
os.environ["TARS_ARQUIVO_AUTOTESTE"] = os.path.join(tempfile.mkdtemp(), "relatorio.txt")
from _util import carregar_tars # noqa: E402
tars = carregar_tars()
import tars_autoteste # noqa: E402
def rodar(completo):
saida = io.StringIO()
with contextlib.redirect_stdout(saida):
codigo = tars_autoteste.executar(tars, completo=completo)
return codigo, saida.getvalue()
# 1. Nada funcionando (sem Ollama, sem tela): relata, não quebra
tars._SESSION.get = lambda *a, **k: (_ for _ in ()).throw(ConnectionError("recusado"))
tars.ollama_online = lambda: False
codigo, texto = rodar(completo=True)
assert codigo == 1 and "Ollama" in texto and "não está respondendo" in texto, texto
assert "sem Ollama ou sem modelo de conversa" in texto
print("OK: sem Ollama, o relatório aponta o problema (e não quebra)")
# 2. Ollama e modelos no ar; a IA "abre a calculadora e clica"
class Resp:
status_code = 200
def json(self):
return {"version": "0.12.3"}
CATALOGO = {
"qwen3:8b": {"tag": "qwen3:8b", "familia": "qwen3", "parametros_b": 8.2, "categoria": "geral",
"vram_estimado_gb": 5.5, "capacidades": {"tools", "thinking"}, "capacidades_conhecidas": True},
"qwen2.5:0.5b": {"tag": "qwen2.5:0.5b", "familia": "qwen2", "parametros_b": 0.5, "categoria": "simples",
"vram_estimado_gb": 0.9, "capacidades": {"tools"}, "capacidades_conhecidas": True},
}
tars._SESSION.get = lambda *a, **k: Resp()
tars.catalogar_modelos = lambda forcar=False: CATALOGO
tars.listar_modelos_instalados = lambda forcar=False: set(CATALOGO)
tars.detectar_gpu = lambda forcar=False: {"vram_total_gb": 6.0, "vram_livre_gb": 5.0, "fabricante": "NVIDIA"}
tars.medir_classificador = lambda frases: {"n": 34, "acertos_local": 31, "acertos_total": 32, "ms_medio": 0.4,
"por_categoria": {}, "erros_total": [("frase x", "busca", "geral")],
"erros_local": []}
tars.SESSAO_GRAFICA = "x11"
tars._buscar_app_no_sistema = lambda nome: {"tipo": "desktop", "nome": "Calculadora", "comando": ["gnome-calculator"]}
tars._capturar_tela = lambda: __import__("PIL.Image", fromlist=["Image"]).new("RGB", (1920, 1080), (40, 90, 160))
tars.listar_janelas_x = lambda: [{"id": 1, "titulo": "Calculadora", "classe": "gnome-calculator", "pid": 9}]
tars._termos_para_janela = lambda nome: [nome]
tars._pids_protegidos = lambda: set()
fechados = []
tars.fechar_aplicativo = lambda nome: fechados.append(nome) or {"sucesso": True}
visor = {"textos": ["9"]}
tars.acess.indisponivel = lambda: None
tars.acess.janelas = lambda: [{"app": "gnome-calculator", "titulo": "Calculadora", "pid": 9, "ativa": True, "no": None}]
tars.acess.achar_janela = lambda **k: {"titulo": "Calculadora", "no": None}
tars.acess.listar = lambda janela, filtro=None: {"elementos": {}, "textos": visor["textos"], "total": 0}
conversa_antes = list(tars.conversa)
arquivo_antes = tars.ARQUIVO_SESSOES
def ia_que_acerta(texto):
assert "calculadora" in texto.lower() and tars.ARQUIVO_SESSOES != arquivo_antes, "o teste não usa o histórico real"
for nome in ("7", "+", "2", "="):
tars.executar_ferramenta("click_element", {"name": nome, "window": "calculadora"})
return "O resultado é 9."
tars._DISPATCH_FERRAMENTAS["click_element"] = lambda a: {"sucesso": True, "mensagem": "SUCCESS"}
tars.processar_mensagem = ia_que_acerta
codigo, texto = rodar(completo=True)
assert codigo == 0, texto
assert "passou (o visor mostra 9)" in texto and "click_element×4" in texto, texto
assert "32/34 (94%)" in texto and "0.12.3" in texto and "NVIDIA 6.0 GB" in texto, texto
assert fechados == ["calculadora"] and tars.conversa == conversa_antes and tars.ARQUIVO_SESSOES == arquivo_antes
relatorio = open(os.environ["TARS_ARQUIVO_AUTOTESTE"], encoding="utf-8").read()
assert "passou" in relatorio and "\033[" not in relatorio and "frase x | busca | geral" in relatorio
print("OK: IA clicou 7 + 2 =, o visor mostra 9: passou (relatório em texto puro, histórico intacto)")
# 3. A IA diz "9", mas o visor não mostra: não passa
visor["textos"] = ["7+"]
codigo, texto = rodar(completo=True)
assert codigo == 1 and "não chegou no 9 (visor: 7+)" in texto, texto
print("OK: a IA dizer '9' não basta: o teste confere o visor")
# 4. Diagnóstico rápido não abre nada
tars.processar_mensagem = lambda texto: (_ for _ in ()).throw(AssertionError("o diagnóstico não pode chamar a IA"))
codigo, texto = rodar(completo=False)
assert "Calculadora 7 + 2" not in texto and "Clique pelo nome" in texto and "gnome-calculator" in texto, texto
print("OK: --diagnostico só confere o ambiente (não abre a calculadora)")
print("\nTUDO OK.")