惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
G
Google Developers Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
有赞技术团队
有赞技术团队
Vercel News
Vercel News
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
博客园_首页
The Cloudflare Blog
B
Blog
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
U
Unit 42
D
Docker
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
A
About on SuperTechFans

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Bruno CLI vs Apidog CLI: Rodando Testes de API na CI
Lucas · 2026-06-15 · via DEV Community

Seus testes de API passam no seu laptop. O que importa é se eles rodam em cada pull request, merge e build noturno sem intervenção humana. Para isso, você precisa de um executor de linha de comando: ele roda os testes em modo headless dentro do pipeline, retorna código de saída correto e gera relatórios que o CI consegue ler.

Experimente o Apidog hoje

Dois CLIs aparecem com frequência nessa configuração: Bruno CLI e Apidog CLI. Ambos executam testes de API em CI/CD, mas partem de modelos diferentes:

  • Bruno é git-native, offline-first e open source. O CLI executa arquivos .bru versionados no repositório.
  • Apidog é uma plataforma de API completa. O CLI executa cenários visuais criados no aplicativo, buscados por ID.

Ambos funcionam em GitHub Actions, GitLab CI, Jenkins e qualquer runner com Node.js. Ambos falham a build quando um teste falha. A diferença principal está em como você cria os testes, onde eles ficam e como o CI os acessa.

Em resumo

  • Bruno CLI (@usebruno/cli, binário bru) executa arquivos .bru diretamente de uma pasta no seu repositório Git.
  • Apidog CLI (apidog-cli, binário apidog) executa cenários de teste visuais do seu projeto Apidog usando um access token.
  • Ambos geram relatórios JUnit, JSON e HTML.
  • Ambos retornam código de saída diferente de zero quando há falha.
  • Use Bruno quando quiser testes em texto simples, versionados no repositório, sem conta e sem dependência de rede.
  • Use Apidog quando quiser criar cenários visualmente, encadear requisições, reutilizar ambientes e rodar testes data-driven sem manter código de teste manualmente.

O problema: testes que existem, mas não rodam

Um teste executado só manualmente tende a ficar desatualizado. A API muda, o teste continua parado e ninguém percebe até quebrar algo em produção.

O objetivo do CLI é transformar esses testes em um gate automatizado:

  1. Rodar sem interface gráfica.
  2. Retornar erro quando uma asserção falhar.
  3. Gerar relatório para o CI.
  4. Permitir execução por ambiente, pasta, cenário ou tag.
  5. Funcionar em pipelines repetíveis.

Se você está montando a base de CI/CD para testes de API, também vale ler sobre automatização de testes de API em CI/CD. Aqui o foco é a comparação prática entre os dois CLIs.

O que o Bruno CLI faz bem

O Bruno foi desenhado para ser git-native. Requisições, ambientes e asserções ficam em arquivos .bru no disco, dentro do repositório.

Isso traz vantagens claras para times que tratam testes como código:

  • O teste muda no mesmo pull request que altera o endpoint.
  • O diff é revisável como qualquer arquivo de texto.
  • Você pode usar grep, refatorações, busca no editor e resolução normal de conflitos.
  • O CI não precisa buscar testes em um serviço externo.
  • Não há login, token ou conta para executar localmente.

Esse modelo também funciona bem em ambientes restritos ou air-gapped, porque o CLI executa localmente os arquivos do repositório.

Instale o Bruno CLI:

npm install -g @usebruno/cli

Execute uma coleção:

bru run --env staging

Se os testes estiverem em subpastas, use execução recursiva:

bru run -r --env staging

Exemplo de estrutura comum:

api-tests/
├── environments/
│   └── staging.bru
├── users/
│   ├── create-user.bru
│   └── get-user.bru
└── orders/
    └── create-order.bru

No CI, você aponta o comando para essa pasta. Os arquivos .bru são a fonte da verdade.

Para contexto mais amplo, veja também o que torna Bruno diferente como cliente de API git-native e onde suas limitações aparecem para equipes maiores.

O que o Apidog CLI faz bem

O Apidog usa outro modelo: você cria os testes visualmente no aplicativo e o CLI executa esses cenários em modo headless.

Um cenário pode incluir:

  • várias requisições encadeadas;
  • extração de valores da resposta;
  • uso de variáveis em etapas seguintes;
  • asserções;
  • ambientes;
  • execução com arquivo CSV ou JSON.

A vantagem é que você não mantém duas versões do mesmo teste. O cenário visual é o teste. O CLI apenas executa esse cenário no pipeline.

Instale o Apidog CLI:

npm install -g apidog-cli

Exemplo de execução:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -n 1 -r html,junit

Onde:

  • --access-token autentica o CLI.
  • -t 605067 seleciona o cenário de teste.
  • -e 1629989 seleciona o ambiente.
  • -n 1 define o número de iterações.
  • -r html,junit gera relatórios HTML e JUnit.

Na prática, você não precisa memorizar esses IDs. No Apidog:

  1. Abra o cenário de teste.
  2. Vá para a aba CI/CD.
  3. Gere um access token.
  4. Copie o comando gerado.
  5. Mova o token para um segredo do CI.
  6. Referencie o token como variável de ambiente.

A referência de opções está no guia completo do Apidog CLI.

Bruno CLI vs Apidog CLI

Dimensão Bruno CLI (bru) Apidog CLI (apidog)
Pacote @usebruno/cli apidog-cli
Comando bru run apidog run
Fonte do teste Arquivos .bru no repositório Cenários no projeto Apidog
Autoria Arquivos de texto ou app Bruno Construtor visual no Apidog
Autenticação no CI Nenhuma --access-token
Seleção de testes Pasta, -r, --tags -t, -f, --test-suite
Ambiente --env <name> -e <environmentId>
Dados externos --csv-file-path, --json-file-path -d <path>
Iterações --iteration-count <n> -n <n>
Relatórios JSON, JUnit, HTML cli, html, json, junit
Falha rápida --bail --on-error end
Open source Sim Não; CLI npm gratuito
Conta necessária Não Sim, para acessar o projeto Apidog

A comparação prática é simples:

  • Bruno lê testes do disco.
  • Apidog busca testes do projeto.
  • Bruno favorece controle por Git.
  • Apidog favorece autoria visual e fluxo integrado.
  • Ambos cobrem os requisitos básicos de CI.

Relatórios e códigos de saída

No CI, duas coisas importam mais que a interface da ferramenta:

  1. O relatório gerado.
  2. O código de saída do comando.

Bruno: gerar JUnit, HTML e JSON

bru run -r --env staging \
  --reporter-junit ./results/junit.xml \
  --reporter-html ./results/report.html \
  --reporter-json ./results/report.json

Use:

  • --reporter-junit para o painel do CI.
  • --reporter-html para um artefato navegável.
  • --reporter-json para pós-processamento.
  • --bail para parar na primeira falha.

Exemplo com falha rápida:

bru run -r --env staging \
  --bail \
  --reporter-junit ./results/junit.xml

Apidog: gerar relatórios em um diretório

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 \
  -r html,junit \
  --out-dir ./apidog-reports

Controle de erro:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 \
  --on-error continue \
  -r html,junit \
  --out-dir ./apidog-reports

Opções úteis:

  • --on-error end: para na primeira falha.
  • --on-error continue: continua e coleta todas as falhas.
  • --on-error ignore: ignora erros de etapas específicas conforme configuração.

Em ambos os casos, se uma asserção falhar, o processo termina com código diferente de zero. O CI usa esse código para falhar o job.

Evite isto:

bru run -r --env staging || true

Ou isto:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 || true

Esse padrão engole o erro e quebra o gate de qualidade.

Bruno CLI no GitHub Actions

Como os arquivos .bru estão no repositório, o workflow é direto:

name: Testes de API

on:
  pull_request:
    branches: [main]

jobs:
  api-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Instalar Bruno CLI
        run: npm install -g @usebruno/cli

      - name: Executar testes de API
        working-directory: ./api-tests
        run: |
          bru run -r \
            --env staging \
            --reporter-junit ./results/junit.xml \
            --reporter-html ./results/report.html

      - name: Fazer upload dos relatórios
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: relatorio-bruno
          path: ./api-tests/results

Pontos importantes:

  • working-directory deve apontar para a pasta da coleção.
  • if: always() garante upload do relatório mesmo quando o teste falha.
  • Nenhum segredo é necessário para executar o CLI.

Apidog CLI no GitHub Actions

No Apidog, o workflow é parecido, mas usa um segredo para o token:

name: Testes de API

on:
  pull_request:
    branches: [main]

jobs:
  api-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Instalar Apidog CLI
        run: npm install -g apidog-cli

      - name: Executar cenário de teste de API
        run: |
          apidog run \
            --access-token "$APIDOG_ACCESS_TOKEN" \
            -t 605067 \
            -e 1629989 \
            -r html,junit \
            --out-dir ./apidog-reports
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}

      - name: Fazer upload dos relatórios
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: relatorio-apidog
          path: ./apidog-reports

Checklist para configurar:

  1. Gere o comando na aba CI/CD do cenário.
  2. Crie o segredo APIDOG_ACCESS_TOKEN no GitHub.
  3. Cole o ID do cenário em -t.
  4. Cole o ID do ambiente em -e.
  5. Publique os relatórios com actions/upload-artifact.

Para exemplos em outros CIs, veja o guia completo do Apidog CLI.

Execução sem instalação global

Em runners efêmeros, você pode usar npx.

Bruno:

npx @usebruno/cli run -r --env staging

Apidog:

npx apidog-cli run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t 605067 \
  -e 1629989

Isso evita instalação global persistente no runner.

Como escolher

A escolha não é apenas “qual CLI é melhor”. É qual modelo combina com seu time.

Escolha Bruno se você quer testes como código

Bruno faz sentido quando:

  • o repositório é a fonte da verdade;
  • os testes devem ser revisados no mesmo PR do código;
  • você quer arquivos de texto simples;
  • o CI precisa funcionar sem conta externa;
  • o time prefere ferramentas open source e offline;
  • você aceita editar ou manter arquivos .bru.

É uma boa opção para times que querem controle total no Git e previsibilidade em ambientes restritos.

Escolha Apidog se você quer autoria visual e fluxo integrado

Apidog faz sentido quando:

  • o time prefere criar cenários visualmente;
  • você quer encadear requisições sem escrever scripts manuais;
  • os mesmos cenários devem rodar em vários ambientes;
  • testes, documentação, mock e depuração vivem no mesmo workspace;
  • você quer gerar o comando de CI a partir da interface;
  • o time vem de ferramentas como Postman.

Nesse caso, o CLI vira apenas o executor headless do cenário já modelado visualmente.

Se você está avaliando alternativas ao Postman, veja também a comparação do Apidog como alternativa ao Postman para testes de API.

Você também pode usar os dois

Alguns times combinam os dois modelos:

  • Bruno para checks pequenos, rápidos e versionados junto ao código.
  • Apidog para cenários encadeados, regressão e testes orientados a dados.

No pipeline, eles são apenas etapas separadas:

- name: Rodar testes Bruno
  run: bru run -r --env staging

- name: Rodar cenários Apidog
  run: |
    apidog run \
      --access-token "$APIDOG_ACCESS_TOKEN" \
      -t 605067 \
      -e 1629989

Se qualquer etapa retornar erro, o job falha.

Para uma comparação mais ampla entre as plataformas, incluindo design, mocking e colaboração, veja Apidog vs Bruno.

Perguntas frequentes

O Bruno CLI é gratuito?

Sim. O Bruno CLI é open source e distribuído como o pacote npm @usebruno/cli. Ele executa localmente, sem conta ou token. O Bruno Ultimate é um nível pago separado com recursos de equipe e governança, como SSO, SCIM, integrações com gerenciadores de segredos e auditoria.

O Apidog CLI é gratuito?

O CLI é um pacote npm gratuito, apidog-cli. Ele executa cenários do seu projeto Apidog, então o que você pode executar depende do seu plano Apidog. O runner de linha de comando não é um produto pago separado.

Preciso escrever testes como código?

Depende da ferramenta.

No Bruno, os testes são arquivos .bru, que você pode editar diretamente ou criar pelo aplicativo Bruno.

No Apidog, você cria cenários visualmente no aplicativo e o CLI executa esses cenários por ID. Você não mantém manualmente arquivos de teste como código.

Ambos falham a build quando um teste falha?

Sim. Ambos retornam código de saída diferente de zero quando uma asserção falha. O CI usa esse código para marcar o job como falho e bloquear merge ou deploy.

Qual formato de relatório devo usar no CI?

Use JUnit XML para integração com painéis de CI. Use HTML como artefato navegável para depuração.

Bruno:

bru run -r --env staging \
  --reporter-junit ./results/junit.xml \
  --reporter-html ./results/report.html

Apidog:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 \
  -r html,junit \
  --out-dir ./apidog-reports

O Bruno CLI precisa de internet?

Não para executar testes locais. Ele lê os arquivos .bru do repositório e roda sem login ou busca remota.

O Apidog CLI precisa de internet?

Sim. Ele autentica com um access token e busca o cenário no projeto Apidog, então precisa de acesso à rede ao serviço Apidog durante a execução.

Posso rodar os CLIs localmente antes de configurar o CI?

Sim.

Bruno:

bru run -r --env staging

Apidog:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989

Antes de colocar no pipeline, confirme que o comando local retorna erro quando uma asserção falha. Esse comportamento é o que vai proteger seu merge no CI.