Cómo probar en la pista de Arturo

Aprende a probar tus ejercicios de Arturo en Exercism


El track de Arturo usa el paquete de pruebas unitarias Unitt 3.0.0 para todas las pruebas de los ejercicios. Este paquete ofrece un framework de pruebas que admite tanto la sintaxis moderna inspirada en RSpec como la sintaxis heredada inspirada en XUnit. Ejecutar arturo tester.art o exercism test desde tu carpeta local del ejercicio debería instalar el paquete desde Internet la primera vez que lo ejecutes. Como alternativa, puedes instalar Unitt ejecutando arturo --package install unitt 3.0.0. Solo se ejecutará la primera prueba y se te mostrará su resultado. Cuando esa prueba pase, deja de omitir la siguiente y vuelve a ejecutar las pruebas hasta que pase cada una. Tanto en la configuración de RSpec como en la de XUnit, basta con quitar .skip de it.skip o de test.skip, respectivamente. Cuando todas las pruebas pasen, envía tu solución, pero ten en cuenta que el ejecutor de pruebas ejecuta todas las pruebas, incluso las omitidas.

Primeros pasos

La carpeta del ejercicio que descargaste tendrá varios archivos, pero estos son los tres esenciales.

leap/
├── src/leap.art         # Your solution file
├── tests/test-leap.art  # Test cases for the exercise
└── tester.art           # Test runner entry point

Ejecutar arturo tester.art configurará Unitt y luego ejecutará las pruebas dentro de tests/test-leap.art. Las pruebas importarán src/leap.art, que contiene tu solución, y luego harán una serie de aserciones sobre lo que debe devolver tu solución para entradas específicas.

Archivo de solución

isLeap?: function [year][
    panic "please implement the isLeap? function"
]

Cuando empiezas un ejercicio, tu archivo de solución incluye una plantilla con la estructura básica de lo que se espera. En este ejemplo de Leap, el archivo contiene una definición mínima de la función isLeap? esperada y, en particular, un panic que detiene la ejecución de las pruebas. Quita la línea del panic y luego empieza a escribir tu implementación de isLeap?.

Estructura de las pruebas de RSpec

import.version:3.0.0 {unitt}!
import {src/leap}!

describe "Leap" [
    it "a year not divisible by 4 is a common year" [
        expects.be:'false? @[isLeap? 2015]
    ]

    it.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        expects.be:'true? @[isLeap? 1996]
    ]
]
  • describe define un bloque de casos de prueba que validan algo en común. Estos bloques se pueden anidar.
  • it e it.skip definen un solo caso de prueba, que se ejecuta o se omite, respectivamente.
  • expects introduce la aserción que está en el centro de un caso de prueba. expects.be recibe una función predicado que se usa para hacer la aserción.

En expects.be:'false? @[isLeap? 2015], el conjunto de pruebas afirma que la función isLeap? debe devolver false para el año 2015. Otra forma de escribirlo es expects.be:'equal? @[false isLeapYear? 2015], donde afirmamos que el valor devuelto por isLeapYear? 2015 es igual a false. Esta forma más larga, que compara dos valores, es el tipo de aserción más común en el track de Arturo. El valor esperado siempre va primero en el bloque, antes del valor resultado.

Estructura de las pruebas de XUnit

suite "Leap" [
    test "a year not divisible by 4 is a common year" [
        result: isLeap? 2015
        assert -> false = result
    ]

    test.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        result: isLeap? 1996
        assert -> true = result
    ]
]

La API similar a XUnit, introducida en la v1 de Unitt, es compatible con versiones anteriores y es en gran medida equivalente a la API moderna similar a RSpec, salvo por sus aserciones menos flexibles.

  • suite define un bloque de casos de prueba que validan algo en común. Estos bloques se pueden anidar.
  • test y test.skip definen un solo caso de prueba, que se ejecuta o se omite, respectivamente.
  • assert introduce la aserción que está en el centro de un caso de prueba. La expresión al lado derecho del -> que sigue debe ser verdadera.

En las pruebas de XUnit, normalmente se crean variables que representan el resultado y, de forma opcional, el valor esperado antes de la línea del assert.

Salida de las pruebas

Ya sea que uses la API de RSpec o la de XUnit, la salida de las pruebas será en gran medida similar. La única diferencia será lo que se imprime debajo del nombre de cada prueba. XUnit reporta la aserción usando los valores evaluados, así que verás false = false. RSpec, en cambio, la reporta como false? false porque usamos la función false? con expects.

Para empezar desde el principio, Arturo reportará un error si no se quitó el panic del archivo inicial, y no evaluará ninguna prueba.

Uncaught error in tests/test-leap.art:
#[
        output: {
                
                ══╡ Program Error ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ <script> ══
                
                  Please implement the isLeap? function
                
                
        }
        code: 1
]

Una vez que reemplaces el panic, Arturo reportará el estado de cada aserción hecha dentro de una prueba. Ahora la primera prueba pasa, pero la segunda se omite.

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ⏩ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         skipped!


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 1 assertion
❌  FAILED: 0 assertion

========== ======= ==========

Después de quitar manualmente la omisión de la segunda prueba, ambas pruebas se ejecutarán. Sin embargo, la implementación actual del código de isLeap? solo devuelve false, así que la segunda prueba falla su aserción.

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ❌ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         ❌: true? false


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 0 assertion
❌  FAILED: 1 assertion

========== ======= ==========

Este proceso continuará a medida que dejes de omitir más pruebas. Cuando todas las pruebas pasen, habrás terminado el ejercicio y podrás enviar la solución. Ten en cuenta que el ejecutor de pruebas ejecutará todas las pruebas localmente, estén omitidas o no.