Ideas en bits

Los errores sirven

En mi anterior post hice un refactor a un código, verifique los tests que tenia, y además le agregue más tests usando based property tests.

Que aplicado no?

not

Así es, cuando hice el refactor metí un hermoso bugcito, que no fue lo peor de todo, ya que lo "mucho" peor fue que los tests seguían pasando, y me hizo acordar a una gran frase

Tener tests malos, es mucho peor que tener codigo fallando

El Bug

El código refactorizado ayer termino así:

def is_first_weekday_of_month(weekday: int) -> bool:
    """Determine if today is the first weekday of the month.

    :param weekday: weekday we want to identify (starting as monday -> 0)
    """
    weekday = datetime.today().weekday()
    day = datetime.today().day

    return weekday == weekday and day <= 7

Vieron el error? (yo la primera vez no lo ví y estaba super claro)

look

Última línea:

return weekday == weekday and day <= 7

Estoy sobre-escribiendo weekday, por lo tanto la primera condición siempre es verdadera, y lo único que hace el metodo es decirme si el dia esta en la primer semana 🤦🏻‍♂️.

Y ahora, por que los tests pasaban? vamos a analizarlos

Tests incompletos

El test con hypothesis verificaba si el mismo dia a testear era el primero de la semana, por lo tanto la primer condición no se verificaba nunca.

El test con pytest + parametrize, estaba casi bien hecho, pero el set de datos elegidos no probaba nunca con un dia diferente al lunes que sea de la primer semana.

Vamos a actualizar el primer test, agregando un caso más:

@pytest.mark.parametrize(
    "date,expected",
    [
        ("2021-10-04 03:21:34", True),
        ("2021-10-11 03:21:34", False),
        ("2021-07-15 03:21:34", False),
        ("2021-07-26 03:21:34", False),
        ("2021-02-01 03:21:34", True),
        ("2021-12-06 03:21:34", True),
        ("2021-06-07 03:21:34", True),
        ("2021-06-03 03:21:34", False),  # Caso faltante
    ],
)
def test_is_first_monday_of_month(date, expected):

    with freeze_time(date):
        assert dates_utils.is_first_weekday_of_month(PyDay.MONDAY.value) == expected

Corremos de nuevo los tests...

$ pytest -k test_is_first_monday_of_month

FAILED test_is_first_monday_of_month[2021-06-03 03:21:34-False] - assert True == False

1 failed, 7 passed

Genial! ahora los tests atinan un poco mas, y podemos volver a creer en la humanidad (?).

Vamos a corregir el código para resolver el error:

def is_first_weekday_of_month(weekday: int) -> bool:
    """Determine if today is the first weekday of the month.

    :param weekday: weekday we want to identify (starting as monday -> 0)
    """
    today = datetime.today()
    current_weekday = today.weekday()
    day = today.day

    return current_weekday == weekday and day <= 7

Largamos los tests nuevamente...

$ pytest -k test_is_first_monday_of_month

8 passed

pff

Conclusiones

Lo mejor de esto fue reforzar la idea de los "tests malos que hacen mal", pero tambien agradezco mucho recibir feedback en los posts!

Para la próxima, estoy viendo como utilizar hypothesis pero de una mejor manera, y este caso es un buen candidato!

Un saludo de He-Man para todos:

alt


over 2 years ago

Ariel Parra