Aprenda a testar seus exercícios de Arturo no Exercism
A trilha de Arturo usa o pacote de testes unitários Unitt 3.0.0 para todos os testes dos exercícios.
Esse pacote fornece um framework de testes que suporta tanto a sintaxe moderna inspirada no RSpec quanto a sintaxe legada inspirada no XUnit.
Rodar arturo tester.art ou exercism test de dentro da pasta local do seu exercício deve instalar o pacote pela Internet na primeira execução.
Como alternativa, você pode instalar o Unitt rodando arturo --package install unitt 3.0.0.
Só o primeiro teste será rodado e reportado para você.
Quando esse teste passar, reative o próximo e rode os testes de novo até que cada teste passe.
Tanto na configuração do RSpec quanto na do XUnit, isso é tão simples quanto remover .skip de it.skip ou de test.skip, respectivamente.
Quando todos os testes passarem, envie sua solução, mas fique atento: o test runner roda todos os testes, até os ignorados.
A pasta do exercício que você baixou vai ter alguns arquivos, mas estes três são os essenciais.
leap/
├── src/leap.art # Your solution file
├── tests/test-leap.art # Test cases for the exercise
└── tester.art # Test runner entry point
Rodar arturo tester.art vai configurar o Unitt e depois rodar os testes dentro de tests/test-leap.art.
Os testes vão importar src/leap.art, que contém sua solução, e então fazer uma série de asserções sobre o que sua solução deve retornar para entradas específicas.
isLeap?: function [year][
panic "please implement the isLeap? function"
]
Ao começar um exercício, o arquivo da sua solução vem com um template contendo a estrutura básica do que se espera.
Neste exemplo do Leap, o arquivo contém uma definição básica da função isLeap? esperada e, em especial, um panic que interrompe a execução dos testes.
Remova a linha do panic e então comece a programar sua implementação de isLeap?.
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 um bloco de casos de teste que validam algo em comum. Esses blocos podem ser aninhados.it e it.skip definem cada um um único caso de teste, que é rodado ou ignorado, respectivamente.expects introduz a asserção que está no coração de um caso de teste. expects.be recebe uma função de predicado, que é usada para fazer a asserção.Em expects.be:'false? @[isLeap? 2015], a suíte de testes está afirmando que a função isLeap? deve retornar false para o ano 2015.
Outra forma de escrever isso é expects.be:'equal? @[false isLeapYear? 2015], em que afirmamos que o valor retornado por isLeapYear? 2015 é igual a false.
Essa forma mais longa, que compara dois valores, é o tipo de asserção mais comum na trilha de Arturo.
O valor esperado sempre vem primeiro no bloco, antes do valor do resultado.
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
]
]
A API no estilo XUnit, introduzida na v1 do Unitt, é suportada por compatibilidade retroativa e é basicamente equivalente à API moderna no estilo RSpec, exceto pelas asserções menos flexíveis.
suite define um bloco de casos de teste que validam algo em comum. Esses blocos podem ser aninhados.test e test.skip definem cada um um único caso de teste, que é rodado ou ignorado, respectivamente.assert introduz a asserção que está no coração de um caso de teste. A expressão do lado direito do -> a seguir precisa ser verdadeira.Com os testes XUnit, normalmente criamos variáveis que representam o resultado e, opcionalmente, o valor esperado antes da linha do assert.
Esteja você usando a API do RSpec ou a do XUnit, a saída dos testes será basicamente parecida.
A única diferença vai ser o que é impresso abaixo de cada nome de teste.
O XUnit reporta a asserção usando os valores avaliados, então você veria false = false.
O RSpec, por sua vez, reporta como false? false, porque usamos a função false? com expects.
Começando do início, o Arturo vai reportar um erro se o panic do arquivo inicial não tiver sido removido e não vai avaliar nenhum teste.
Uncaught error in tests/test-leap.art:
#[
output: {
══╡ Program Error ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ <script> ══
Please implement the isLeap? function
}
code: 1
]
Depois que o panic for substituído, o Arturo vai reportar o status de cada asserção feita dentro de um teste.
Agora o primeiro teste passa, mas o segundo teste é ignorado.
======== .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
========== ======= ==========
Depois que o segundo teste for reativado manualmente, os dois testes serão rodados.
No entanto, a implementação atual de isLeap? só retorna false, então o segundo teste falha na sua asserção.
======== .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
========== ======= ==========
Esse processo continua conforme você reativa mais testes. Quando todos os testes passarem, você terminou o exercício e pode enviar a solução. Vale notar que o test runner vai rodar todos os testes, estejam eles ignorados ou não localmente.