Mapa da aula
Aula 08 publicada. Mapa, exemplo, EX022.
flowchart TD
N0["8.1 Funções puras são revisáveis"]
N1["8.2 Falhar fechado"]
N2["8.3 Testes como documentação"]
N3["8.4 Registrar decisões para revisão"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX022"]
Desenho lógico
flowchart LR
N0["8.1 Funções puras são revisáveis"]
N1["8.2 Falhar fechado"]
N2["8.3 Testes como documentação"]
N3["8.4 Registrar decisões para revisão"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX022"]
[8.1 Funções puras são revisáveis]
|
v
[8.2 Falhar fechado]
|
v
[8.3 Testes como documentação]
|
v
[8.4 Registrar decisões para revisão]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX022]
Objetivos de aprendizagem
Você vai (1) estruturar uma ferramenta de análise como funções puras com testes; (2) usar o unittest da biblioteca padrão; (3) fazer as funções falharem fechadas; e (4) versionar um script para que um resultado possa ser reproduzido meses depois.
8.1 Funções puras são revisáveis
Uma função que recebe entradas e devolve uma decisão, sem ler a rede nem o relógio, pode ser testada exaustivamente. Para ferramentas de TO isso importa, porque o revisor muitas vezes é um engenheiro de controle que só aceitará uma ferramenta se o seu comportamento nos casos-limite for demonstrado. Mantenha a entrada e a saída (arquivos, impressão) nas bordas e a lógica de decisão no meio. O classificador de Maya foi escrito assim: classify(code) recebe um código de função e devolve uma palavra, de modo que um engenheiro de controle consegue ler a lista de testes e ver todas as decisões sem rodar uma captura.
8.2 Falhar fechado
Quando uma função de lista de permissão recebe uma origem desconhecida, um código de função desconhecido ou um endereço malformado, ela deve devolver "bloquear" em vez de levantar uma exceção que um chamador poderia capturar e ignorar. Falhar fechado numa ferramenta de monitoramento significa "sinalizar para revisão"; num dispositivo de imposição, significa "negar". Nenhum dos dois significa "supor que está tudo bem". O primeiro classificador de Maya falhava aberto: tudo o que estava fora do conjunto de escritas devolvia "read". Um revisor perguntou sobre o código 8, diagnósticos, cujas subfunções podem reiniciar as comunicações, e a resposta expôs o defeito. A correção dela devolve "unknown", o que, num monitor offline, significa sinalizar para revisão.
8.3 Testes como documentação
Uma pequena lista de casos de unittest se lê como uma especificação:
import unittest
def classify(fc):
return "write" if fc in (5, 6, 15, 16) else ("read" if fc in (1, 2, 3, 4) else "unknown")
class T(unittest.TestCase):
def test_codes(self):
self.assertEqual(classify(3), "read"); self.assertEqual(classify(16), "write")
self.assertEqual(classify(8), "unknown"); self.assertEqual(classify(43), "unknown")
unittest.main(argv=["x"], exit=False)
Executá-lo imprime Ran 1 test e OK. O código 43 (encapsulated interface transport, usado para identificação de dispositivos) é deliberadamente "unknown" em vez de "read", porque o autor da ferramenta não raciocinou sobre ele.
A lista de testes é também a especificação que um revisor assina: classify(3) é leitura, classify(16) é escrita, classify(8) e classify(43) são desconhecidos. O defeito original de Maya teria sido pego pela única asserção de que o código 8 devolve "unknown"; essa asserção agora está na lista. Quando um novo código de função aparece numa captura da LDHP, a primeira mudança é uma nova asserção com a resposta esperada, escrita antes de o classificador ser editado.
Exemplo resolvido (LDHP sintética)
O primeiro classificador de Maya devolvia "read" para tudo o que não estava no conjunto de escritas. Um revisor perguntou o que o código 8 (diagnósticos) devolveria. A resposta — "read" — estava errada: algumas subfunções de diagnóstico reiniciam as comunicações. Ela mudou o padrão para "unknown" e acrescentou o teste acima.
Caso sintético — Lakeside District Heating Plant. O classificador é uma ferramenta didática para capturas offline, não um dispositivo de imposição.
8.4 Registrar decisões para revisão
Cada decisão que a ferramenta toma deve ser registrada com a entrada que a produziu, a regra que disparou e a versão do script, por exemplo fc=8 -> unknown (rule: default) v=3f2a91c. Um engenheiro de controle que revisa uma semana de capturas pode então filtrar por "unknown" e decidir, caso a caso, se o classificador precisa de uma nova regra. Esse registro também é o que permite mostrar, mais tarde, que um resultado surpreendente veio de uma versão conhecida do código, e não de uma edição feita depois.
Erros e limites
Os testes provam os casos que você escreveu, não os que você esqueceu. Registre a versão do script (um hash de commit do git) ao lado de todo resultado que você publicar.
Exercícios
- EX022 — Classificando diagnósticos. O que
classify(8)devolve na versão final, e por que isso é preferível?Mostrar critérios de avaliação
Rubrica: 3 = "unknown"; diagnósticos podem alterar o estado do dispositivo, então não se deve supor leitura; 2 = só o valor; 1 = "read"; 0 = nada. - EX023 — Um caso de teste ausente. Escreva uma asserção adicional que teria pego o defeito original de Maya.
Mostrar critérios de avaliação
Rubrica: 3 = assertEqual(classify(8), "unknown") ou outro código semelhante que não seja de leitura; 2 = testa um código de escrita; 1 = testa o código 3; 0 = nada. - EX024 — Reproduzindo um resultado antigo. Cite duas coisas a registrar junto com uma análise publicada para que ela possa ser reproduzida seis meses depois.
Mostrar critérios de avaliação
Rubrica: 3 = hash do commit do script e hash/data exatos do arquivo de entrada; 2 = uma; 1 = "salvar a saída"; 0 = nada.
Síntese
Ferramentas de TO revisáveis são puras, testadas, falham fechadas e são versionadas — propriedades que permitem a um engenheiro cético confiar na sua saída.