Pular para o conteúdo
murad.guide

As Três Camadas

Capítulo 18

Os testes passam

4 min de leitura 706 palavras 1 gravura

Um teste é um combinado escrito em código: “se eu chamar somar(2, 3), quero 5”. Enquanto o combinado falhar, a função ainda não está pronta. Este capítulo não pede HTML novo. Você implementa funções em funcoes.js até a página ficar verde.

O exemplo está em exemplos/18-testes/. Abra index.html. A pasta já tem uma versão que passa. Para treinar, esvazie o corpo das funções e reescreva uma por vez.

Não use npm, Node nem Jasmine. O corredor dos testes é um arquivo local: testes.js.

Trabalhe na cópia inicio desta etapa. Leia e digite o código indicado; mude apenas uma coisa. Antes de recarregar, escreva o resultado que espera. Depois compare com a referência completa ao lado. Se algo falhar, confira primeiro o arquivo salvo e o caminho aberto.

O que você vai aprender

Não comece mexendo em testes.js

index.html carrega dois scripts, nesta ordem:

<script src="funcoes.js"></script>
<script src="testes.js"></script>

Primeiro as funções existem. Depois os testes as chamam. Se inverter a ordem, o navegador reclama que somar não existe.

testes.js já traz o corredor. Não o altere no começo. Se você mudar o combinado para “passar de qualquer jeito”, o exercício perde o sentido.

function esperar(obtido) {
  return {
    ser(esperado) {
      const ok = Object.is(obtido, esperado) ||
        JSON.stringify(obtido) === JSON.stringify(esperado);
      const linha = document.createElement("li");
      linha.className = ok ? "ok" : "fail";
      linha.textContent = ok
        ? "passou"
        : `falhou: obtido ${JSON.stringify(obtido)} / esperado ${JSON.stringify(esperado)}`;
      document.getElementById("resultado").append(linha);
    }
  };
}

esperar recebe o que a sua função devolveu. ser compara com o valor combinado. Se for igual, a linha fica verde. Se não, a mensagem mostra os dois lados.

Erro comum: apagar uma linha de teste para “ficar verde”. O combinado some, o problema não. Comente no máximo as linhas seguintes para focar num teste. Depois descomente.

Combinado esperar(somar(2, 3)).ser(5) e o hábito de um teste por vez

Um teste por vez

Os seis combinados no fim de testes.js são estes:

esperar(somar(2, 3)).ser(5);
esperar(dobrar(4)).ser(8);
esperar(maior([3, 9, 4])).ser(9);
esperar(contem(["cerâmica", "xilo"], "xilo")).ser(true);
esperar(inverter("farol")).ser("loraf");
esperar(ordenar([3, 1, 2])).ser([1, 2, 3]);

Abra funcoes.js. Deixe só a primeira função funcionando. Recarregue. Leia a primeira falha. Corrija. Só então olhe a segunda.

Pare e experimente. Coloque return 0; em somar. Recarregue. A primeira linha deve falhar com obtido 0 e esperado 5. Volte o return a + b.

somar, dobrar e maior

function somar(a, b) {
  return a + b;
}

function dobrar(n) {
  return n * 2;
}

maior percorre um array e guarda o maior valor visto até agora. Começa no índice 0.

function maior(lista) {
  let atual = lista[0];
  for (let i = 1; i < lista.length; i += 1) {
    if (lista[i] > atual) atual = lista[i];
  }
  return atual;
}

Se a lista for [3, 9, 4], atual começa 3, vira 9 e permanece 9.

contem e inverter

contem responde se o valor está na lista. includes já faz isso.

function contem(lista, valor) {
  return lista.includes(valor);
}

O nome da função está sem acento de propósito: identificador em JavaScript neste volume fica em ASCII.

inverter vira o texto ao contrário. "farol" vira "loraf". Uma forma curta: quebrar em letras, inverter o array, juntar de novo.

function inverter(texto) {
  return texto.split("").reverse().join("");
}

split("") vira ["f", "a", "r", "o", "l"]. reverse troca a ordem. join("") cola sem separador.

ordenar com bolha

O último teste pede [1, 2, 3] a partir de [3, 1, 2]. Bolha compara cada item com o vizinho da direita. Se estiver fora de ordem, troca. Repete até ninguém precisar trocar.

Faça uma cópia com slice(). Assim a lista original não muda.

function ordenar(lista) {
  const copia = lista.slice();
  for (let i = 0; i < copia.length; i += 1) {
    for (let j = 0; j < copia.length - 1; j += 1) {
      if (copia[j] > copia[j + 1]) {
        const temp = copia[j];
        copia[j] = copia[j + 1];
        copia[j + 1] = temp;
      }
    }
  }
  return copia;
}

temp guarda um lado da troca. Sem ele, um valor se perde. Recarregue. As seis linhas devem dizer “passou”.

Erro comum: devolver a lista original sem copiar e ainda assim “passar” neste teste curto. No hábito profissional você copia. Faça isso agora.

Atividades

  1. Por que funcoes.js carrega antes de testes.js?
  2. O que a página mostra se dobrar(4) devolver 4?
  3. Na bolha, para que serve a variável temp?
  4. Esvazie só maior e recarregue. Qual mensagem aparece na terceira linha?

Respostas comentadas

  1. Os testes chamam as funções pelo nome. Se testes.js rodar primeiro, somar ainda não existe e o corredor quebra inteiro.
  2. A segunda linha fica vermelha: obtido 4, esperado 8. As outras dependem de você ter preenchido as funções.
  3. Guarda copia[j] enquanto o vizinho ocupa o lugar. Depois o valor guardado vai para a posição da direita.
  4. Algo como falhou: obtido undefined / esperado 9, se a função não tiver return. Leia a mensagem; ela diz o combinado.

Referências

O arquivo completo

Referência do exemplo 18-testes, reproduzida aqui para que você possa conferir sem sair da página.

index.html

<!DOCTYPE html>

<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Testes</title>
<link href="lab.css" rel="stylesheet"/>
<style>body{overflow-wrap:anywhere}img,input,textarea,select,iframe{max-width:100%}img{height:auto}fieldset,.cartao{min-width:0}pre{max-width:100%;overflow:auto}:focus-visible{outline:3px solid #005fcc;outline-offset:3px}.atalho-conteudo{position:absolute;left:.5rem;top:-6rem;background:white;color:#172f50;padding:.5rem;z-index:999}.atalho-conteudo:focus{top:.5rem}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}</style></head>
<body><a class="atalho-conteudo" href="#conteudo">Pular para o conteúdo</a><main id="conteudo" tabindex="-1">
<h1>Faça os testes passarem</h1>
<p>Edite <code>funcoes.js</code>. Não comece mudando <code>testes.js</code>.</p>
<ol id="resultado"></ol>


</main><script src="funcoes.js"></script><script src="testes.js"></script></body>
</html>

script.js

// este arquivo não é usado; veja funcoes.js