Os Test Runners têm a única responsabilidade de receber uma solução, correr todos os testes e devolver uma saída normalizada. Todas as interações com o site do Exercism são tratadas automaticamente e não fazem parte desta especificação.
two-fer)./tmp para ficheiros temporários (por exemplo, para compilar código-fonte).results.json no diretório de saída.O test runner dispõe de 100% de CPU e 3 GB de memória durante uma janela de 20 segundos por solução. Após 20 segundos, o processo é interrompido e é indicado um tempo limite excedido.
Recomendamos vivamente que sigas o nosso documento de Boas Práticas de Desempenho para reduzir a probabilidade de tempos limite excedidos.
Os seguintes campos são suportados nos ficheiros results.json:
chave:
version, tipo:number, presença: obrigatória
versão: 1, 2, 3
A versão da especificação a que este ficheiro obedece:
1: Para tracks cujo test runner não consegue fornecer informações sobre testes individuais.2: Para tracks cujo test runner consegue apresentar informações sobre testes individuais. Versão mínima obrigatória para tracks com exercícios de conceito.3: Para tracks cujo test runner consegue associar testes individuais a uma tarefa.chave:
status, tipo:string, presença: obrigatória
versão: 1, 2, 3
Os seguintes estados globais são válidos:
pass: Todos os testes passaramfail: Pelo menos um teste tem o estado fail ou error
error: Nenhum teste foi executado (normalmente significa um erro de compilação ou um erro de sintaxe)O estado error só deve ser usado se todos os testes tiverem dado erro.
Em linguagens compiladas, isto resulta geralmente de o código não conseguir compilar.
Em linguagens interpretadas, trata-se de um erro de execução, como um erro de sintaxe que impede o ficheiro de ser analisado.
chave:
message, tipo:string, presença: obrigatória sestatus=error, ou quandostatus=faileversion=1
versão: 1, 2, 3
Quando o estado é error (nenhum teste foi executado corretamente), deve ser fornecida a chave message de nível superior. Deve apresentar ao utilizador o erro que ocorreu. Como é a única informação que o utilizador recebe sobre como depurar o problema, tem de ser o mais clara possível:
<solution-dir>/relative/path em vez de /full/path/to, pois isso incluiria dados específicos do ECR que não ajudamEm Ruby, no caso de um erro de sintaxe, fornecemos o erro de execução e o rastreio da pilha. Em linguagens compiladas, deve ser fornecido o erro de compilação.
O valor message de nível superior está limitado a 65535 carateres.
O comprimento máximo efetivo é menor se o valor contiver carateres multibyte.
Quando o estado não é error, define o valor como null ou omite a chave por completo.
chave:
tests, tipo:array, presença: obrigatória sestatus=failoustatus=pass
versão: 2, 3
Este é um array com os resultados dos testes, especificado na secção «Por teste» abaixo.
Os testes DEVEM ser devolvidos pela ordem em que estão especificados no ficheiro de testes. Para linguagens que executam os testes por ordem aleatória, isto pode implicar reordenar os resultados de acordo com a ordem especificada no ficheiro de testes.
A razão para isto é que só a primeira falha é mostrada aos estudantes e, por isso, é importante que a falha correta seja mostrada. Como os testes estão geralmente ordenados no ficheiro de testes de acordo com o TDD, e como nos exercícios de prática os estudantes veem o ficheiro de testes no editor, é essencial alinhar os resultados com o ficheiro de testes.
chave:
name, tipo:string, presença: obrigatória
versão: 2, 3
É o nome do teste num formato legível por humanos.
chave:
test_code, tipo:string, presença: obrigatória se o exercício for de conceito
versão: 2, 3
Isto DEVE estar presente nos exercícios de conceito e DEVERIA estar presente nos exercícios de prática.
A diferença neste requisito vem do facto de os estudantes não verem os testes nos exercícios de conceito, pelo que resolver o exercício pode ser impossível sem que o test_code seja mostrado, ao passo que nos exercícios de prática os testes são mostrados.
É o corpo do comando que está a ser testado. Por exemplo, o seguinte teste em Ruby:
def test_duplicate_items_uniqs_list
cart = ShoppingCart.new
cart.add(:STARIC)
cart.add(:MEDNEW)
cart.add(:MEDNEW)
assert_equal 'Newspaper, Rice', cart.items_list
end
deve devolver um valor test_code de:
"cart = ShoppingCart.new
cart.add(:STARIC)
cart.add(:MEDNEW)
cart.add(:MEDNEW)
assert_equal 'Newspaper, Rice', cart.items_list"
(com as quebras de linha substituídas por \n para tornar o JSON válido).
chave:
status, tipo:string, presença: obrigatória
versão: 2, 3
Os seguintes estados por teste são válidos:
pass: O teste passoufail: O teste falhouerror: O teste deu erro, ou seja, não devolveu um valorchave:
message, tipo:string, presença: obrigatória sestatusforfailouerror
versão: 2, 3
A chave message por teste é usada para devolver os resultados de um teste com um status de fail ou error. Deve ser o mais legível possível para humanos. Tudo o que for escrito aqui será mostrado ao estudante quando o teste não passar. Se não houver mensagem de falha ou mensagem de erro do teste, define o valor como null ou omite a chave por completo. Também é permitido apresentar aqui a saída do conjunto de testes. O valor message não tem limite de comprimento.
chave:
output, tipo:string, presença: opcional
versão: 2, 3
A chave output por teste deve ser usada para armazenar e apresentar tudo o que o utilizador produza deliberadamente para um teste.
puts em Ruby, print em Python ou Debug.WriteLine em C#), ou podes fornecer um método que o utilizador possa usar (por exemplo, o Test Runner de Ruby disponibiliza ao utilizador um método debug global que ele pode usar, com as mesmas características do método puts padrão).chave:
task_id, tipo:number, presença: opcional
versão: 3
Associa um teste a uma tarefa específica através do ID da tarefa, que é o número usado no início do título da tarefa. Só associa um teste a uma tarefa se for possível associá-lo a precisamente uma tarefa.
De momento, só os exercícios de conceito têm tarefas bem definidas às quais podes associar testes, mas isto pode mudar no futuro.
Por exemplo, considera o seguinte ficheiro instructions.md:
# Instructions
You're going to write some code to help Lucian cook an exquisite lasagna from his favorite cook book.
## 1. Define the expected oven time in minutes
...
## 2. Calculate the remaining oven time in minutes
...
Estas instruções definiam duas tarefas:
O ficheiro results.json pode então ter uma entrada como esta:
{
"name": "Expected oven time in minutes",
"status": "pass",
"task_id": 1,
"test_code": "Assert.Equal(40, Lasagna.ExpectedMinutesInOven());"
}
Este teste está agora associado à primeira tarefa: «Define o tempo esperado no forno, em minutos». Repara que o nome não tem de corresponder à descrição da tarefa.
Há várias formas de os tracks implementarem isto:
.meta/config.json do exercício) e juntar essa informação ao ficheiro results.json gerado.Estes são exemplos do aspeto que um ficheiro results.json válido pode ter nas diferentes versões:
{
"version": 1,
"status": "fail",
"message": "Failed: test_answer\nExpected: 42, actual: 3"
}
{
"version": 2,
"status": "fail",
"message": null,
"tests": [
{
"name": "Test that the thing works",
"status": "fail",
"message": "Expected 42 but got 123123",
"output": "Debugging information output by the user",
"test_code": "assert_equal 42, answerToTheUltimateQuestion()"
}
]
}
{
"version": 3,
"status": "fail",
"message": null,
"tests": [
{
"name": "Test that the thing works",
"status": "fail",
"message": "Expected 42 but got 123123",
"output": "Debugging information output by the user",
"test_code": "assert_equal 42, answerToTheUltimateQuestion()",
"task_id": 1
}
]
}
Quando a solução de um estudante falha um teste, deve mostrar algo como:
Test Code:
<test_code>
Test Result:
<message>
Quando a solução passa um teste, deve mostrar algo como:
Test Code:
<test_code>
Todos os caminhos vão dar a Roma e não há um padrão prescrito para chegar a isto. Até agora, foram adotadas várias abordagens: