
Passo 1 de 7
Definir o fluxo real a verificar
Delimite um fluxo de integração local e identifique quais resultados observáveis comprovam seu funcionamento.
Trilha de aprendizado · Nível 8 · Tutorial 5
Testar a colaboração entre componentes de processamento e persistência usando arquivos reais em diretórios temporários controlados pelo pytest.
Definir o fluxo real a verificar
Delimite um fluxo de integração local e identifique quais resultados observáveis comprovam seu funcionamento. 2 min
Receber um diretório com tmp_path
Solicite ao pytest um diretório temporário exclusivo e construa caminhos de entrada e saída dentro dele. 3 min
Preparar uma entrada conhecida
Crie um JSON sintético dentro de tmp_path, chame o leitor real e compare os dados carregados com uma expectativa definida diretamente no teste. 3 min
Verificar o resultado persistido de forma independente
Teste o fluxo completo de leitura, soma e gravação, conferindo o JSON persistido sem reutilizar a própria implementação para produzir a expectativa. 3 min
Provocar falhas reproduzíveis
Crie cenários controlados de arquivo ausente e JSON malformado, verificando as exceções propagadas e a ausência do arquivo de saída. 3 min
Manter os testes independentes
Reconheça como diretórios exclusivos, caminhos explícitos e dados sintéticos evitam dependências entre testes, mesmo quando o pytest mantém resíduos temporários no disco. 2 min
Consolidar e executar a suíte de integração
Reúna o fluxo e os testes em arquivos locais, execute os três cenários e confirme que a suíte permanece isolada e repetível. 4 min

Passo 1 de 7
Delimite um fluxo de integração local e identifique quais resultados observáveis comprovam seu funcionamento.
No tutorial anterior, os substitutos permitiram verificar componentes isoladamente. Agora, o foco muda: vamos exercitar a colaboração entre componentes reais e o sistema de arquivos local.
O caso condutor recebe dois caminhos explicitamente — entrada e saída — e executa este fluxo:
total.O escopo continua controlado: não há banco de dados, rede ou outro serviço externo.

A integração atravessa componentes locais reais e termina em um efeito observável no arquivo de saída.
Um retorno correto não basta para comprovar todo o fluxo. A operação também precisa produzir o arquivo de saída no caminho recebido, com o conteúdo previsto pelo contrato.
Por isso, o resultado principal da integração é o conteúdo persistido. A verificação deve alcançar o último ponto observável do percurso, em vez de parar no valor calculado em memória.
Exemplo
Entrada JSON: [4, 7, 2]
Saída esperada, interpretada como JSON: {"total": 13}
Se a operação retornar 13, mas não gravar esse resumo no caminho de saída, a colaboração está incompleta. Espaços ou indentação diferentes não mudam o significado do JSON.
Associe cada observação ao que ela permite concluir sobre o fluxo.
Toque em um item e depois no par correspondente.

Passo 2 de 7
Solicite ao pytest um diretório temporário exclusivo e construa caminhos de entrada e saída dentro dele.
Para receber um diretório temporário, inclua tmp_path como parâmetro da função de teste. Ao executar o teste, o pytest reconhece esse nome e fornece um objeto pathlib.Path que aponta para um diretório temporário exclusivo daquele teste.
Você não cria tmp_path nem importa uma variável com esse nome. O recurso é solicitado pela assinatura da função.

O pytest cria o diretório e entrega seu caminho ao teste; os caminhos dos arquivos são construídos dentro dele.
O diretório indicado por tmp_path já existe quando o teste começa. Use o operador / de Path para construir caminhos filhos, sem depender de caminhos absolutos ou específicos da sua máquina.
Construir entrada e saida não cria esses arquivos. Eles somente passarão a existir quando alguma operação gravar conteúdo neles.
Salve como tests/test_caminhos.py e execute com python -m pytest tests/test_caminhos.py.
def test_constroi_caminhos_no_diretorio_temporario(tmp_path):
entrada = tmp_path / "quantidades.json"
saida = tmp_path / "resumo.json"
assert tmp_path.is_dir()
assert entrada.parent == tmp_path
assert saida.parent == tmp_path
assert not entrada.exists()
assert not saida.exists()
Dica
Não chame essa função de teste manualmente. Execute-a com o pytest para que o parâmetro tmp_path seja preenchido.
Complete o parâmetro que faz o pytest fornecer o diretório temporário:
def test_processamento(_____):
Depois, o teste poderá construir entrada = tmp_path / "dados.json".
Após executar entrada = tmp_path / "dados.json", o arquivo dados.json já existe no diretório temporário.

Passo 3 de 7
Crie um JSON sintético dentro de tmp_path, chame o leitor real e compare os dados carregados com uma expectativa definida diretamente no teste.
Neste cenário, o próprio teste cria um arquivo JSON conhecido dentro de tmp_path. Em seguida, chama o leitor real e compara o resultado com uma lista esperada.
A entrada deve ser gravada diretamente pelo teste. Se usássemos o gravador da aplicação para preparar o arquivo, um defeito nele poderia interferir na verificação do leitor.
O recurso temporário participa das três etapas: o teste prepara o JSON, o leitor real acessa o arquivo e o valor carregado é comparado com a expectativa.

O teste cria seus próprios dados antes de chamar o leitor real.
Na raiz de uma pasta local, crie processamento.py com o código completo abaixo. O módulo reúne leitura, processamento e persistência para os próximos testes. Nesta etapa, o foco é carregar_quantidades, que recebe o caminho explicitamente e lê texto em UTF-8.
import json
from pathlib import Path
def carregar_quantidades(caminho: Path) -> list[int]:
texto = caminho.read_text(encoding="utf-8")
return json.loads(texto)
def calcular_total(quantidades: list[int]) -> int:
return sum(quantidades)
def salvar_resumo(caminho: Path, total: int) -> None:
resumo = {"total": total}
texto = json.dumps(resumo, ensure_ascii=False)
caminho.write_text(texto, encoding="utf-8")
def executar_fluxo(entrada: Path, saida: Path) -> None:
quantidades = carregar_quantidades(entrada)
total = calcular_total(quantidades)
salvar_resumo(saida, total)
Crie a pasta tests e, dentro dela, o arquivo test_processamento.py. O caminho entrada.json fica sob o diretório recebido por este teste. O arquivo ainda não existe quando o caminho é composto; write_text o cria com dados sintéticos e previsíveis.
from processamento import carregar_quantidades
def test_carrega_quantidades_de_arquivo_temporario(tmp_path):
entrada = tmp_path / "entrada.json"
entrada.write_text("[4, 7, 2]", encoding="utf-8")
quantidades = carregar_quantidades(entrada)
assert quantidades == [4, 7, 2]
Dica
Escreva a expectativa diretamente no teste. Aqui, [4, 7, 2] expressa claramente o que deve resultar da leitura do JSON preparado, sem pedir à própria aplicação que produza o valor esperado.
Coloque as operações na ordem adequada para verificar a leitura de uma entrada temporária conhecida.

Passo 4 de 7
Teste o fluxo completo de leitura, soma e gravação, conferindo o JSON persistido sem reutilizar a própria implementação para produzir a expectativa.
No fluxo completo, a operação recebe os caminhos de entrada e saída localizados sob tmp_path, lê as quantidades, calcula a soma e grava o resumo.
A verificação não deve se limitar ao retorno da função nem apenas confirmar que a saída existe. O teste precisa abrir o arquivo realmente gravado, decodificar seu JSON e comparar o conteúdo com uma expectativa definida pelo próprio cenário.
Para evitar que erros compatíveis se escondam, confira a saída com read_text() e json.loads(), da biblioteca padrão, em vez de usar o leitor da aplicação como única forma de testar o gravador.

A operação produz a saída; o teste segue um caminho independente para observar e comparar o conteúdo persistido.
No arquivo de testes usado no step anterior, adicione o teste abaixo. Ajuste apenas o nome do módulo importado caso você tenha usado outro nome para o arquivo da aplicação.
import json
from processamento import processar_arquivo
def test_processa_e_grava_resumo(tmp_path):
entrada = tmp_path / "quantidades.json"
saida = tmp_path / "resumo.json"
entrada.write_text("[4, 7, 9]", encoding="utf-8")
esperado = {"total": 20}
processar_arquivo(entrada, saida)
obtido = json.loads(saida.read_text(encoding="utf-8"))
assert obtido == esperado
Dica
saida.read_text() já exige que o arquivo tenha sido criado. json.loads() exige conteúdo JSON decodificável, e a comparação entre dicionários verifica o significado dos dados. Espaços, indentação e ordem textual das chaves não afetam o teste, pois não fazem parte deste contrato.
Qual verificação detecta conteúdo incorreto mesmo que o arquivo de saída exista?
Execute o teste no seu projeto com python -m pytest. Depois, altere temporariamente esperado para {"total": 21} e execute novamente: o teste deve falhar porque o conteúdo persistido não corresponde à expectativa. Restaure {"total": 20} e confirme que ele volta a passar.
O que você observou nas execuções? Explique também por que {"total": 20} é uma expectativa independente da implementação.
Escreva pelo menos 80 caracteres (0/80).

Passo 5 de 7
Crie cenários controlados de arquivo ausente e JSON malformado, verificando as exceções propagadas e a ausência do arquivo de saída.
Um teste de integração também deve verificar falhas previsíveis. Neste step, a operação processar_arquivo(entrada, saida) continua sendo exercitada com componentes reais, mas recebe duas entradas problemáticas:
Nos dois casos, a leitura falha antes que a operação abra o arquivo de saída. Portanto, além da exceção específica, o contrato deste exemplo permite verificar que a saída não foi criada.
Os dois cenários param na etapa de leitura e não chegam à gravação.

Arquivo ausente e JSON malformado falham antes da gravação no fluxo deste exemplo.
Atenção
A verificação assert not saida.exists() é válida porque a implementação do exemplo lê e processa a entrada antes de abrir a saída. Ela não representa uma garantia geral de recuperação ou de gravação atômica.
Com tmp_path, compor um caminho não cria o arquivo. Isso permite provocar FileNotFoundError sem apagar arquivos existentes nem tocar em pastas pessoais.
Adicione este teste ao arquivo de testes que já importa pytest e a operação processar_arquivo:
def test_nao_cria_saida_quando_entrada_nao_existe(tmp_path):
entrada = tmp_path / "quantidades.json"
saida = tmp_path / "resumo.json"
# O caminho foi construído, mas o arquivo não foi criado.
with pytest.raises(FileNotFoundError):
processar_arquivo(entrada, saida)
assert not saida.exists()Dica
Prefira fabricar uma ausência dentro do diretório temporário. Não dependa de permissões, falta de espaço, caminhos fixos ou arquivos pessoais: essas condições variam entre máquinas.
Agora a entrada deve existir. Grave deliberadamente um texto como [10, 20,, que começa uma lista e termina sem fechá-la. Ao tentar decodificá-lo, json.load ou json.loads gera json.JSONDecodeError, propagado pela operação integrada.
Isso é diferente de um JSON sintaticamente válido com dados inadequados ao domínio. Por exemplo, {"quantidade": "muitas"} pode ser um JSON válido, ainda que não atenda ao contrato da aplicação. Aqui, o foco é exclusivamente a falha de decodificação.
Garanta que o arquivo de testes também tenha import json:
import json
def test_nao_cria_saida_quando_json_e_invalido(tmp_path):
entrada = tmp_path / "quantidades.json"
saida = tmp_path / "resumo.json"
entrada.write_text("[10, 20,", encoding="utf-8")
with pytest.raises(json.JSONDecodeError):
processar_arquivo(entrada, saida)
assert not saida.exists()Exemplo
pytest.raises(json.JSONDecodeError) confirma a falha específica de decodificação. Já assert not saida.exists() confirma o efeito observável previsto pelo contrato deste fluxo: a gravação não começou após a entrada inválida.
Associe cada preparação ao resultado esperado.
Toque em um item e depois no par correspondente.
Se quantidades.json contiver apenas [5,, qual exceção o teste deve esperar e qual deve ser o estado de resumo.json após a chamada?
Escreva pelo menos 40 caracteres (0/40).

Passo 6 de 7
Reconheça como diretórios exclusivos, caminhos explícitos e dados sintéticos evitam dependências entre testes, mesmo quando o pytest mantém resíduos temporários no disco.
Duas funções de teste podem criar entrada.json e saida.json com os mesmos nomes. Como cada uma recebe um diretório exclusivo por tmp_path, os caminhos completos são diferentes.
Cada teste deve preparar seus próprios dados, executar a operação e verificar seu próprio resultado. Assim, a suíte não depende da ordem de execução: nenhum teste precisa consumir um arquivo produzido por outro.
Observe que nomes de arquivo iguais não representam o mesmo recurso quando estão dentro de diretórios temporários diferentes.

Cada teste trabalha em seu próprio diretório, ainda que os nomes internos dos arquivos sejam iguais.
Construa os caminhos sob tmp_path e passe-os explicitamente para a operação testada. O código não deve procurar entradas no diretório de trabalho nem depender de um caminho específico da sua máquina.
O pytest administra a retenção e a limpeza dos diretórios temporários conforme sua política e configuração. Portanto, não presuma que todo diretório será apagado imediatamente após o teste. Resíduos podem permanecer no disco, mas novas execuções não devem reutilizá-los como entrada.
Atenção
Use somente dados sintéticos criados pelo próprio teste. Não escreva rotinas que percorram ou excluam arquivos de pastas pessoais para “limpar” o cenário: o isolamento deve vir do diretório temporário e dos caminhos controlados.
Se um diretório temporário ainda existir no disco depois da execução, isso prova que o próximo teste reutilizará seus arquivos.
Um teste permanece independente quando cria seus dados sob o próprio tmp_path e passa os caminhos explicitamente ao código testado.

Passo 7 de 7
Reúna o fluxo e os testes em arquivos locais, execute os três cenários e confirme que a suíte permanece isolada e repetível.
Crie uma pasta vazia no seu computador. Dentro dela, crie processamento.py e a pasta tests, contendo test_integracao.py. O exemplo é completo e usa arquivos reais sob o diretório exclusivo recebido por cada teste.
Este módulo lê uma lista JSON, calcula o total e persiste o resumo. A entrada é lida e processada antes da abertura da saída.
import json
from pathlib import Path
def carregar_quantidades(caminho: Path) -> list[int]:
texto = caminho.read_text(encoding="utf-8")
return json.loads(texto)
def calcular_total(quantidades: list[int]) -> int:
return sum(quantidades)
def gravar_resumo(caminho: Path, total: int) -> None:
resumo = {"total": total}
caminho.write_text(
json.dumps(resumo, ensure_ascii=False),
encoding="utf-8",
)
def processar_arquivo(entrada: Path, saida: Path) -> None:
quantidades = carregar_quantidades(entrada)
total = calcular_total(quantidades)
gravar_resumo(saida, total)
Cada teste prepara seu próprio cenário sob tmp_path. O caso de sucesso confere o JSON com a biblioteca padrão; os casos de falha exigem exceções específicas e ausência de saída.
import json
import pytest
from processamento import processar_arquivo
def test_processa_e_persiste_total(tmp_path):
entrada = tmp_path / "quantidades.json"
saida = tmp_path / "resumo.json"
entrada.write_text("[7, -2, 12]", encoding="utf-8")
processar_arquivo(entrada, saida)
conteudo_persistido = json.loads(
saida.read_text(encoding="utf-8")
)
assert conteudo_persistido == {"total": 17}
def test_falha_quando_entrada_nao_existe(tmp_path):
entrada = tmp_path / "ausente.json"
saida = tmp_path / "resumo.json"
with pytest.raises(FileNotFoundError):
processar_arquivo(entrada, saida)
assert not saida.exists()
def test_falha_com_json_invalido(tmp_path):
entrada = tmp_path / "invalido.json"
saida = tmp_path / "resumo.json"
entrada.write_text("[3, 5,", encoding="utf-8")
with pytest.raises(json.JSONDecodeError):
processar_arquivo(entrada, saida)
assert not saida.exists()
Abra o terminal na pasta que contém processamento.py. Execute primeiro cada cenário, depois a suíte completa e, por fim, repita a execução completa. A repetição deve continuar aprovada porque nenhum teste depende dos arquivos produzidos por outro.
Execute os comandos na ordem apresentada.
python -m pytest tests/test_integracao.py::test_processa_e_persiste_total -q
python -m pytest tests/test_integracao.py::test_falha_quando_entrada_nao_existe -q
python -m pytest tests/test_integracao.py::test_falha_com_json_invalido -q
python -m pytest tests/test_integracao.py -q
python -m pytest tests/test_integracao.py -qDica
Na execução completa, o resultado esperado é 3 passed. O valor 17 foi definido diretamente no teste para os dados [7, -2, 12], sem chamar a função de cálculo para produzir a expectativa. As duas falhas também verificam que resumo.json não foi criado.
Execute a suíte no seu computador e relate: o resultado das execuções individual e conjunta; o resultado da repetição; o conteúdo esperado de resumo.json; as falhas exigidas; e por que os testes não dependem de caminhos pessoais, resíduos ou resultados de outros testes.
Escreva pelo menos 120 caracteres (0/120).
Resumo
Você verificou uma integração local entre leitura, processamento e persistência, dentro dos limites controlados pelo teste.
tmp_path foi solicitado como parâmetro e forneceu um diretório exclusivo para cada teste.{"total": 17} foi definida independentemente da função de processamento.Parabéns! Você concluiu: Verificar integração com arquivos temporários
100 XP
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks