Cover do episódio 103: "Funciona na minha máquina" — a mentira que eu acreditei por meses
#10330 de setembro, 20192 min leituraInfra que Aprendi na PráticaS3 · 2018–2019

"Funciona na minha máquina" — a mentira que eu acreditei por meses

Em 2019 eu disse essa frase pelo menos três vezes. Cada vez era verdade. E cada vez o ambiente de produção ou do cliente contava outra história.

AmbientesDevOpsDebuggingProdução

"Funciona na minha máquina."

Falei isso em outubro de 2019 com a maior confiança. Tinha testado. Rodei três vezes. Funcionou sempre.

O cliente testou e não funcionou.

Eu tinha Python 3.7. O servidor do cliente tinha 3.6. Um f-string que eu usava funcionava diferente nas duas versões. Um detalhe de 0.1 de versão, imperceptível no dia a dia, que só apareceu quando os ambientes eram diferentes.


Ambiente diferente é uma das fontes mais frustrantes de bug porque o código está correto — só está correto para um ambiente específico, não para todos.

Ambiente diferente é uma das fontes mais frustrantes de bug porque o código está correto — só está correto para um ambiente específico. Versão de runtime, sistema operacional (case sensitivity de filesystem no macOS vs Linux, por exemplo), variáveis de ambiente que você tem local e produção não tem, banco de dados com versão ou dados diferentes, dependências transitivas instaladas em versão diferente. Qualquer dessas pode fazer o código se comportar diferente.

"Funciona na minha máquina" é verdade — e irrelevante. O que importa é se funciona no ambiente onde vai rodar.


A solução que eu aprendi a partir de 2020 foi containerização (Docker). Mas em 2019, antes de chegar lá, o que ajudou foi tornar o ambiente explícito:

# .python-version (pyenv)
3.7.4

# requirements.txt (versões fixas)
requests==2.22.0
sqlalchemy==1.3.8
python-dotenv==0.10.3

E documentar os pré-requisitos do projeto. Não "instale Python" — "instale Python 3.7.x (testado com 3.7.4)".

Parece óbvio. Na época, eu assumia que o ambiente do outro lado era igual ao meu.


A mudança de mentalidade foi mais importante que qualquer ferramenta.

Quando algo funciona local mas não funciona em outro ambiente, o bug não é "no outro ambiente" — é no código, que tem uma suposição implícita sobre o ambiente que deveria ser explícita.

Se o código assume Python 3.7+, deve checar (ou documentar) isso. Se assume encoding UTF-8, deve garantir isso. Se assume uma variável de ambiente, deve falhar com mensagem clara quando ela não está presente.

import os

DATABASE_URL = os.environ.get("DATABASE_URL")
if not DATABASE_URL:
    raise RuntimeError("DATABASE_URL environment variable is required")

Erro claro na inicialização é infinitamente melhor que comportamento inesperado na hora de usar.

A frase correta não é "funciona na minha máquina". É "funciona sob estas condições específicas". E a pergunta que segue é: essas condições estão garantidas em todos os ambientes onde vai rodar?