Aprenda sobre geradores de testes

Saiba como a trilha de Clojure usa geradores de testes para gerar testes para os exercícios


A trilha de Clojure usa um gerador de testes para gerar automaticamente os testes dos exercícios de prática. Ele aproveita o fato de que a maioria dos exercícios definidos no repositório problem-specifications também tem um arquivo canonical-data.json, que contém entradas e saídas de teste padronizadas que podem ser usadas para implementar o exercício.

Etapas

Para gerar os testes de um exercício de prática, o gerador de testes:

  1. Lê os casos de teste do exercício no arquivo canonical-data.json
  2. Usa o arquivo tests.toml para omitir os casos de teste excluídos
  3. Transforma os casos de teste (opcional)
  4. Renderiza os casos de teste usando o template de gerador do exercício
  5. Formata o template renderizado usando o cljfmt
  6. Escreve o template formatado no arquivo de teste do exercício

Etapa 1: ler o arquivo canonical-data.json

O gerador de testes analisa os casos de teste do canonical-data.json do exercício usando a biblioteca clojure/data.json.

Como alguns dados canônicos usam aninhamento, o caso de teste analisado inclui um campo path adicional que contém as propriedades description de quaisquer elementos pais, além da própria propriedade description do caso de teste.

Observação: as chaves são analisadas como keywords.

Etapa 2: omitir os testes excluídos do arquivo tests.toml

Cada exercício tem um arquivo tests.toml, no qual testes individuais podem ser excluídos/desativados. O gerador de testes remove qualquer caso de teste marcado como excluído (include = false).

Etapa 3: transformar os casos de teste (opcional)

Alguns exercícios podem precisar de alguns ajustes antes de renderizar os dados. Por exemplo, talvez você queira deixar a descrição menos prolixa.

Para ajustar casos de teste, defina um arquivo .meta/generator.clj com um namespace <slug>-generator. Há duas formas de transformar casos de teste:

  • Atualizar caso(s) de teste
  • Adicionar/remover caso(s) de teste

Atualizar caso(s) de teste

Para atualizar casos de teste individuais, defina a seguinte função:

(defn update-test-case
  "Update a test case"
  [test-case]
  ;; function body
)
Exemplo

Este exemplo remove todos os elementos, menos o último, do valor :path (encurtando a descrição):

(ns difference-of-squares-generator)

(defn update-test-case [test-case]
  (update test-case :path #(take-last 1 %)))

Adicionar ou remover caso(s) de teste

Para adicionar ou remover casos de teste, defina a seguinte função:

(defn add-remove-test-cases
  "Add/remove test case(s)"
  [test-cases]
  ;; function body
)
Note

Se você definir as duas funções, add-remove-test-cases é chamada primeiro e update-test-case depois.

Etapa 4: renderizar os casos de teste

Os casos de teste (potencialmente transformados) são então passados para o arquivo .meta/generator.tpl, que define como os testes devem ser renderizados com base nesses casos de teste.

Etapa 5: formatar o template renderizado usando o cljfmt

O template renderizado é então formatado usando o cljfmt. Isso traz os seguintes benefícios:

  • Os exercícios são formatados de forma consistente
  • Você não precisa se preocupar muito com espaços em branco e alinhamento ao escrever templates

Etapa 6: escrever o template renderizado no arquivo de teste do exercício

Por fim, a saída do template renderizado é escrita no arquivo de teste do exercício.

Templates

Os templates são renderizados usando a biblioteca hbs, que dá suporte à sintaxe handlebars (usando o handlebars.java).

Interface de linha de comando

Há duas formas de rodar o gerador de testes:

  1. bin/generate-tests: gera os testes de todos os exercícios que têm um template de gerador
  2. bin/generate-tests <slug>: gera os testes do exercício especificado, se ele tiver um template de gerador