typestar

test_suite.py en Python

Un archivo de pytest como en un proyecto real: fixtures, parametrize, marcas.

"""Córreme con: pytest test_suite.py -v"""

import pytest

# ---- el código bajo prueba -------------------------------------------


class Puntuador:
    def __init__(self, tpm_objetivo: int = 90):
        if tpm_objetivo <= 0:
            raise ValueError("el objetivo debe ser positivo")
        self.target_tpm = tpm_objetivo
        self.history: list[int] = []

    def stars(self, tpm: float, precision: float) -> int:
        if precision < 0 or precision > 100:
            raise ValueError(f"precisión fuera de rango: {precision}")
        ganadas = 1
        if precision >= 95:
            ganadas = 2
        if precision >= 98 and tpm >= self.target_tpm:
            ganadas = 3
        self.history.append(ganadas)
        return ganadas

    @property
    def best(self) -> int:
        return max(self.history, default=0)


# ---- las pruebas -----------------------------------------------------


@pytest.fixture
def puntuador():
    return Puntuador(tpm_objetivo=90)


@pytest.mark.parametrize("tpm,precision,esperado", [
    (60.0, 90.0, 1),
    (60.0, 96.0, 2),
    (95.0, 99.0, 3),
    (80.0, 99.0, 2),
])
def test_estrellas_por_nivel(puntuador, tpm, precision, esperado):
    assert puntuador.stars(tpm, precision) == esperado


def test_historial_y_mejor(puntuador):
    puntuador.stars(95.0, 99.0)
    puntuador.stars(50.0, 80.0)
    assert puntuador.history == [3, 1]
    assert puntuador.best == 3


def test_historial_vacio_sin_mejor(puntuador):
    assert puntuador.best == 0


@pytest.mark.parametrize("precision", [-1.0, 101.0])
def test_rechaza_precision_imposible(puntuador, precision):
    with pytest.raises(ValueError, match="fuera de rango"):
        puntuador.stars(90.0, precision)


def test_rechaza_objetivo_cero():
    with pytest.raises(ValueError, match="positivo"):
        Puntuador(tpm_objetivo=0)


def test_respeta_el_objetivo(monkeypatch):
    estricto = Puntuador(tpm_objetivo=200)
    assert estricto.stars(150.0, 99.0) == 2


@pytest.mark.parametrize("objetivo", [1, 90, 500])
def test_cualquier_objetivo_positivo_construye(objetivo):
    assert Puntuador(objetivo).target_tpm == objetivo

Cómo funciona

  1. El módulo bajo prueba va arriba, así el archivo es autocontenido.
  2. Los fixtures arman los objetos; parametrize cubre los casos.
  3. Correr pytest sobre este archivo ejercita cada camino de abajo.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
78
Caracteres a escribir
1918
Tokens
408
Ritmo de tres estrellas
110 tpm

Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 223 segundos.

Escribe este fragmento

Paso 1 de 1 en Bis; paso 9 de 9 en Testing con pytest.

← Anterior