---
title: "Otimismo de Recursos"
type: "test-smell"
slug: "resource-optimism"
url: "http://localhost:3000/pt-br/test-smells/resource-optimism.md"
category: "Maus Cheiros de Fixture"
description: "Otimismo de Recursos é quando um teste presume que um recurso externo (um arquivo, diretório, tabela de banco de dados, variável de ambiente ou endpoint de rede) já existe e está em um estado conhecido, em vez de provisioná-lo e verificá-lo, fazendo o teste passar ou falhar de forma não determinística."
---
# Otimismo de Recursos

> Otimismo de Recursos é quando um teste presume que um recurso externo (um arquivo, diretório, tabela de banco de dados, variável de ambiente ou endpoint de rede) já existe e está em um estado conhecido, em vez de provisioná-lo e verificá-lo, fazendo o teste passar ou falhar de forma não determinística.

## Signs and Symptoms

Um teste toca algo _fora de si mesmo_ — um arquivo, caminho temporário, diretório, linha de banco de dados, variável de ambiente ou endpoint remoto — e simplesmente confia que ele já está lá e com o formato correto. Não há etapa de configuração que crie o recurso nem verificação de que ele existe antes de ser usado.

Sinais reveladores:

* Um caminho embutido no código é lido ou escrito sem um `existsSync`/`mkdir`/`writeFile` prévio: por exemplo, `fs.readFileSync('/tmp/app/config.json')`.
* O teste passa na sua máquina ou na primeira execução, depois falha em um checkout limpo, na CI, em um diretório temporário de outro SO, ou quando a suíte roda em ordem diferente ou em paralelo.
* O recurso de que ele precisa é, na verdade, criado por _outro_ teste (ou por uma etapa manual/exclusiva de dev), então o teste só funciona como efeito colateral da ordem de execução.
* Ele abre um arquivo/conexão e faz asserções sobre o resultado sem nunca verificar que o recurso estava presente — um recurso ausente lança uma exceção antes da asserção real, ou silenciosamente produz dados vazios que mesmo assim "passam".

```js
test('parses the config file', () => {
  // otimista: presume que /tmp/app/config.json já existe e está bem formado
  const raw = fs.readFileSync('/tmp/app/config.json', 'utf8');
  expect(JSON.parse(raw).port).toBe(8080);
});

```

A heurística canônica de detecção (testsmells.org / tsDetect): um teste usa um recurso do tipo `File` sem antes chamar uma verificação de existência/validade como `exists()`, `isFile()` ou `notExists()`.

## Reasons for the Problem

**Por que acontece**

* O recurso estava presente enquanto o teste era escrito (um arquivo de fixture no repositório, um banco de dev populado, um arquivo temporário deixado por uma etapa anterior), então o autor nunca sente a ausência dele.
* É simplesmente menos código apontar para um caminho ou tabela existente do que alocar e popular um na configuração, e depois desfazê-lo.
* Copiar e colar de outro teste que já dependia de estado compartilhado e ambiente.

**Por que prejudica**

* **Não determinismo / instabilidade (flakiness).** O resultado depende do estado do ambiente, não do código sob teste. van Deursen et al. descrevem exatamente isto: testes que "funcionam bem em um momento e falham miseravelmente em outro." Runners de CI limpos, checkouts novos, workers paralelos e diferentes locais temporários do SO são onde isso causa dor.
* **Falsa confiança.** Um teste verde pode estar passando por causa de estado remanescente de uma execução anterior ou de um teste anterior, não porque o código atual está correto — ou um recurso ausente lança uma exceção cedo e a asserção significativa nunca é executada.
* **Acoplamento oculto e dependência de ordem.** Quando um teste cria aquilo que outro consome, a suíte tem um contrato de ordenação invisível que quebra ao embaralhar ou fragmentar (sharding) os testes.
* **Difícil de reproduzir e manter.** As falhas não podem ser reproduzidas localmente porque dependem de estado de ambiente específico da máquina, então a depuração é lenta e o teste corrói a confiança.

## Treatment

Faça cada teste **possuir e controlar** todo recurso que ele toca, e nunca presuma estado de ambiente.

1. **Provisione na configuração, limpe no teardown.** Use _Setup External Resource_ — aloque e inicialize arquivos, diretórios, tabelas de banco e conexões em `beforeEach`/`beforeAll` e libere-os em `afterEach`/`afterAll` para que a próxima execução comece limpa.
2. **Crie, não presuma.** Escreva o arquivo, popule a tabela ou inicie o servidor de stub na configuração. Se você realmente precisar consumir um recurso pré-existente, verifique primeiro que ele existe para que um recurso ausente falhe de forma evidente com uma mensagem clara, em vez de corromper a asserção real.
3. **Isole por teste.** Use um diretório temporário único (`fs.mkdtemp(os.tmpdir() + …)`) ou um schema/namespace novo por teste, em vez de um caminho compartilhado embutido no código, para que execuções paralelas e reexecuções não colidam.
4. **Melhor ainda, remova a dependência.** Substitua o recurso real por um mock ou fake em memória (`fs` mockado, banco em memória, HTTP com stub) para que o teste seja totalmente autocontido e determinístico — a correção que o testsmells.org recomenda.

Antes → depois:

```js
// antes — Otimismo de Recursos
test('parses the config file', () => {
  const raw = fs.readFileSync('/tmp/app/config.json', 'utf8');
  expect(JSON.parse(raw).port).toBe(8080);
});

```

```js
// depois — o teste possui e verifica seu recurso
import { mkdtemp, writeFile, rm, readFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';

let dir;
beforeEach(async () => {
  dir = await mkdtemp(path.join(os.tmpdir(), 'cfg-'));
  await writeFile(path.join(dir, 'config.json'), JSON.stringify({ port: 8080 }));
});
afterEach(() => rm(dir, { recursive: true, force: true }));

test('parses the config file', async () => {
  const raw = await readFile(path.join(dir, 'config.json'), 'utf8');
  expect(JSON.parse(raw).port).toBe(8080);
});

```

## Detected by

- **tsDetect** `Resource Optimism` — Otimismo de Recursos (https://testsmells.org/pages/testsmells.html)
