<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marlo Henrique</title>
    <description>The latest articles on Forem by Marlo Henrique (@marlo2222).</description>
    <link>https://forem.com/marlo2222</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F865778%2Fa4415229-3acd-4e00-a8a5-10ef5e205f87.jpeg</url>
      <title>Forem: Marlo Henrique</title>
      <link>https://forem.com/marlo2222</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marlo2222"/>
    <language>en</language>
    <item>
      <title>Modelos abertos e fechados em testes de performance com k6.</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Tue, 24 Feb 2026 00:35:22 +0000</pubDate>
      <link>https://forem.com/marlo2222/modelos-abertos-e-fechados-em-testes-de-performance-com-k6-2ej7</link>
      <guid>https://forem.com/marlo2222/modelos-abertos-e-fechados-em-testes-de-performance-com-k6-2ej7</guid>
      <description>&lt;p&gt;Ao modelar um teste de performance, uma das decisões mais importantes e que requer bom planejamento é frequentemente ignorada, a escolha do modelo de carga que será utilizado.&lt;/p&gt;

&lt;p&gt;Essa escolha impacta diretamente na fidelidade do cenário e do ambiente de carga que se deseja reproduzir, sendo uma peça chave na confiabilidade dos resultados obtidos.&lt;/p&gt;

&lt;p&gt;O K6 suporta dois modelos de carga distintos: o modelo fechado e o modelo aberto. Cada um deles possui características próprias, casos de uso específicos e executores dedicados. &lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar as diferenças entre esses modelos, e como se aplicam aos diferentes tipos de testes de performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;K6 instalado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Modelos de carga⚖️
&lt;/h2&gt;

&lt;p&gt;Antes de abordar o assunto modelos abertos e fechados, é importante entender que em um teste de performancea, eles representam a forma como o sistema controla a chegada e a saída de usuários virtuais (VUs) durante o ciclo de execução de um teste.&lt;/p&gt;

&lt;p&gt;A escolha do modelo muda completamente a semântica do teste de performance planejado. Em alguns cenários por exemplo, esperamos controlar melhor quantos usuários estão ativos ao mesmo tempo, já em outros, podemos estar mais preocupados em garantir que uma determinada taxa de requisições(RPS) seja mantida, independentemente de quantos usuários são necessários para atingir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelo Fechado🔒
&lt;/h2&gt;

&lt;p&gt;No modelo fechado, o número de VUs é fixo e controlado. Um novo usuário só inicia sua próxima iteração quando a anterior é concluída. Isso significa que a concorrência permanece constante ao longo do teste.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
  scenarios: {
    modelo_fechado: {
      executor: 'constant-vus',
      vus: 50,
      duration: '1m',
    },
  },
};

export default function () {
  // sua lógica de teste
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizar esse modelo nos gera uma consequência importante: se o sistema ficar lento, a taxa de requisições cai automaticamente, pois as VUs ficam aguardando a resposta antes de iniciar uma nova iteração. O pool de usuários ativos nunca cresce além do valor configurado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quando utilizar o modelo fechado?
&lt;/h3&gt;

&lt;p&gt;O modelo fechado é ideal para sistemas onde o número de usuários simultâneos é previsível e limitado, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aplicações internas corporativas: onde apenas um grupo fixo de funcionários acessa o sistema simultaneamente.&lt;/li&gt;
&lt;li&gt;Sistemas com sessões controladas: como plataformas de streaming com limite de conexões por conta.&lt;/li&gt;
&lt;li&gt;Testes de resistência (Soak Tests): onde o objetivo é manter uma carga constante por longos períodos e observar o comportamento do sistema ao longo do tempo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Executores do modelo fechado
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;constant-vus&lt;/td&gt;
&lt;td&gt;Mantém um número fixo de VUs durante a execução do teste.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ramping-vus&lt;/td&gt;
&lt;td&gt;Aumenta ou diminui gradualmente o número de VUs ao longo do tempo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;per-vu-iterations&lt;/td&gt;
&lt;td&gt;Cada VU executa um número fixo de iterações antes de encerrar.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shared-iterations&lt;/td&gt;
&lt;td&gt;Um pool de VUs compartilha um número total fixo de iterações.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Modelo Aberto 🔓
&lt;/h2&gt;

&lt;p&gt;No modelo aberto, novos usuários chegam em uma taxa constante e independente do que os usuários já ativos estão fazendo. Esse comportamento é muito mais próximo do que acontece em sistemas reais, onde usuários chegam continuamente sem esperar que outros terminem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
  scenarios: {
    modelo_aberto: {
      executor: 'constant-arrival-rate',
      rate: 100,
      timeUnit: '1s',
      duration: '1m',
      preAllocatedVUs: 50,
      maxVUs: 200,
    },
  },
};

export default function () {
  // sua lógica de teste
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;No script acima temos um rate constante de 100 VUs, e um numero máximo de 200 VUs que podem ser utilizadas, com 50 pré alocadas antes de o testes de percormance iniciar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O comportamento é o oposto do modelo fechado: se o sistema ficar lento, o K6 precisará de mais VUs para manter a taxa configurada. &lt;/p&gt;

&lt;h3&gt;
  
  
  Quando utilizar o modelo aberto?
&lt;/h3&gt;

&lt;p&gt;O modelo aberto é ideal para sistemas de alto tráfego, onde a taxa de chegada de usuários é independente do tempo de resposta, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs REST públicas: onde múltiplos clientes realizam requisições continuamente.&lt;/li&gt;
&lt;li&gt;E-commerces e portais web: onde os usuários chegam de forma independente.&lt;/li&gt;
&lt;li&gt;Testes de pico (Spike Tests): onde o objetivo é simular um aumento repentino e intenso de tráfego para verificar como o sistema reage.&lt;/li&gt;
&lt;li&gt;Testes de capacidade (Capacity Tests): onde o objetivo é descobrir quantas requisições por segundo o sistema consegue sustentar antes de degradar.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Executores do modelo aberto
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;constant-arrival-rate&lt;/td&gt;
&lt;td&gt;Mantém uma taxa fixa de iterações por unidade de tempo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ramping-arrival-rate&lt;/td&gt;
&lt;td&gt;Aumenta ou diminui gradualmente a taxa de chegada de iterações ao longo do tempo.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Comparando os modelos🧠
&lt;/h2&gt;

&lt;p&gt;A tabela resumimos as principais diferenças entre os dois modelos:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Característica&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Modelo Fechado&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;*&lt;em&gt;Modelo Aberto *&lt;/em&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;O que é controlado&lt;/td&gt;
&lt;td&gt;Número de VUs&lt;/td&gt;
&lt;td&gt;Taxa de chegada de iterações&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comportamento sob lentidão&lt;/td&gt;
&lt;td&gt;Taxa de requisições cai&lt;/td&gt;
&lt;td&gt;Número de VUs aumenta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Realismo&lt;/td&gt;
&lt;td&gt;Menor&lt;/td&gt;
&lt;td&gt;Maior para sistemas web&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tipos de teste&lt;/td&gt;
&lt;td&gt;Smoke, Soak, Load, Stress&lt;/td&gt;
&lt;td&gt;Load, Spike, Capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Executores K6&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;constant-vus&lt;/code&gt;, &lt;code&gt;ramping-vus&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;constant-arrival-rate&lt;/code&gt;, &lt;code&gt;ramping-arrival-rate&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Um erro comum na escolha🙅🏻‍♂️
&lt;/h2&gt;

&lt;p&gt;Muitos times ainda utilizam o modelo fechado para todos os seus testes por ser o padrão e o mais simples de configurar. o que é um problema em sistemas web com tráfego orgânico, isso pode mascarar problemas sérios de performance.&lt;/p&gt;

&lt;p&gt;Imagine o cenário: o sistema começa a responder lentamente devido a uma sobrecarga. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No modelo fechado as VUs ficam aguardando as respostas, e a taxa de requisições cai automaticamente, o que reduz a pressão sobre a aplicação e pode resultar em uma falsa impressão de que ele estabilização do ambiente. - No modelo aberto, o comportamento seria o inverso, novos usuários continuariam chegando na taxa configurada, expondo a degradação real da aplicação.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Modelo fechado: a taxa de requisições cai quando o sistema fica lento
executor: 'constant-vus', vus: 100

// Modelo aberto: a pressão é mantida, e o sistema é exposto
executor: 'constant-arrival-rate', rate: 100, timeUnit: '1s'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;O K6 oferece uma flexibilidade na modelagem de cenários de carga, e entender a diferença entre os modelos aberto e fechado é fundamental para criar testes que realmente reflitam o comportamento do seu sistema em produção.&lt;/p&gt;

&lt;p&gt;Use o modelo fechado quando o número de usuários simultâneos é o que importa, e o modelo aberto quando a taxa de chegada de requisições é o fator crítico.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Confira meu curso na Udemy!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>performance</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>Como testar a performance de query em banco de dados usando K6.</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Sun, 01 Feb 2026 17:57:11 +0000</pubDate>
      <link>https://forem.com/marlo2222/como-testar-a-performance-de-queries-em-banco-de-dados-usando-k6-29g1</link>
      <guid>https://forem.com/marlo2222/como-testar-a-performance-de-queries-em-banco-de-dados-usando-k6-29g1</guid>
      <description>&lt;p&gt;Garantir que uma API responda de forma rápida para os percentis p(99) e p(95) envolve inúmeros fatores, desde a distribuição de conteúdo em múltiplas zonas para reduzir latência até a arquitetura da aplicação consumida. O consumo de APIs terceiras ou de outros componentes da arquitetura, como bancos de dados, pode representar gargalos mascarados no tempo de resposta da sua aplicação.&lt;/p&gt;

&lt;p&gt;Neste artigo, veremos como testar a performance de queries no banco de dados utilizando o plugin &lt;code&gt;xk6-sql&lt;/code&gt; do K6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/" rel="noopener noreferrer"&gt;K6 instalado&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conhecendo o modulo xk6-sql🧠
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://github.com/grafana/xk6-sql" rel="noopener noreferrer"&gt;xk6-sql&lt;/a&gt; é uma extensão oficial do K6 que permite executar consultas SQL diretamente em testes de performance. Com ele, é possível conectar-se a diferentes bancos de dados relacionais, como MySQL, PostgreSQL, SQL Server, SQLite entre outros, realizando operações como criação de tabelas, inserção de dados e consultas durante os ciclos de teste de performance.&lt;/p&gt;

&lt;p&gt;Para utilizá o xk6-sql, é necessário importar o módulo &lt;code&gt;k6/x/sql&lt;/code&gt; junto com o driver correspondente ao banco de dados escolhido, por exemplo: &lt;code&gt;xk6-sql-driver-postgres&lt;/code&gt;. Após a importação do módulo, você pode abrir uma conexão com o banco de dados, executar comandos SQL na fase de configuração (setup), manipular dados das entidades na fase de execução e fechar a conexão na fase de desmontagem (teardown).&lt;/p&gt;

&lt;h2&gt;
  
  
  Aplicação utilizada🛝
&lt;/h2&gt;

&lt;p&gt;O Padrinho, uma aplicação de discovery de vagas, que possui rotas públicas onde os usuários acessam detalhes de cada oportunidade diretamente pelo frontend. Mesmo com cache ativado nessas rotas, a consulta de detalhes envolve junções entre varias entidades e representa cerca de 60% a 65% de todas as requisições processadas pela aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bijlfygb1vvqdu5hc8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bijlfygb1vvqdu5hc8y.png" alt=" " width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além de garantir a consistência das informações retornadas, também precisávamos lidar com a disponibilidade da nossa única instância de &lt;code&gt;PostgreSQL no Supabase&lt;/code&gt;, especialmente, durante períodos de maior tráfego, como nos acessos de first visit, quando uma vaga é consultada pela primeira vez e ainda não existe no cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando nosso script👷🏻‍♀️
&lt;/h2&gt;

&lt;p&gt;Na fase de inicialização, vamos definir os principais módulos a serem utilizados no nosso script, com destaque para os módulos sql e o driver do Postgres. Além dos imports de módulos, também vamos adicionar uma importação de arquivo local, onde será definido o script SQL que será utilizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sql from "k6/x/sql";
import postgres from "k6/x/sql/driver/postgres";
import { SharedArray } from "k6/data";
import { check} from "k6";
import { QUERY_DETALHE_VAGA } from "./query.js";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um ponto importante, na versão &lt;code&gt;1.2.1&lt;/code&gt; do K6 foi introduzida a feature &lt;em&gt;Automatic extension resolution.&lt;/em&gt; Com ela, não existe mais a necessidade de criação de um binário customizável para os &lt;em&gt;módulos xk6&lt;/em&gt; ou módulos que não façam parte do core do K6, bastando que a flag &lt;code&gt;K6_ENABLE_COMMUNITY_EXTENSIONS&lt;/code&gt; esteja configurada como true, como podemos ver no log abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO[0000] Automatic extension resolution is enabled. The current k6 binary doesn't satisfy all dependencies, it's required to provision a custom binary.  deps="k6/x/faker*"
INFO[0000] A new k6 binary has been provisioned with version(s): k6:v1.4.2 k6/x/faker:v0.4.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inicialmente na fase de configuração, vamos definir um volume de iterações e o tempo limite em que nossas iterações precisam ser realizadas. Não utilizaremos nenhum executor do K6:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
    vus: 10,
    iterations: 100,
    duration: "5s",
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Estamos definindo que um total de 100 iterações serão realizadas com o banco de dados, em um tempo maximo de 5 segundos. Serão utilizadas 10 VUs para a execução.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alem das configurações de duração, quantidade de VUs e duração, vamos adicionar um limite(thresold) no percentil de p(90), definindo um baseline deperformance da query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
    vus: 5,
    iterations: 100,
    duration: "5s",
    thresholds: {
        iteration_duration: ["p(90)&amp;lt;300"],
    },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Em bancos de dados com constantes evoluções, nosso threshold é um aliado na identificação da degradação da performance do banco, a medida que novas tabelas, relacionamentos e ausência de indices em consultas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É preciso realizar duas etapas importantes, a primeira delas é a abertura de conexão com nosso banco de dados, por meio de uma string de conexão. Para isso, vamos precisar das seguintes variaveis de ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const host = __ENV.DB_HOST;
const port = __ENV.DB_PORT;
const dbname = __ENV.DB_NAME;
const user = __ENV.DB_USER;
const password = __ENV.DB_PASSWORD;
const ssl = __ENV.DB_SSL || "disable"; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Importante que os valores não sejam definidos diretamente no código, evitando exposição de dados.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em seguida, podemos montar nossa string de conexão e realizar a abertura de conexão com o banco de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function setup() {

    if (!host || !port || !dbname || !user || !password) {
        throw new Error("Variáveis DB_HOST, DB_PORT, DB_NAME, DB_USER e DB_PASSWORD são obrigatórias.");
    }

    const connectionString = `postgres://${user}:${password}@${host}:${port}/${dbname}?sslmode=${ssl}`;

    const db = sql.open(postgres, connectionString);

    return db;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na segunda etapa, será definido as massas que serão utilizadas para consulta na nossa base de dados, utilizaremos alguns IDs de consultas, definidos em um arquivo .json, sendo necessario sua leitura em uma estrutura de SharedArray:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nanoIds = new SharedArray("nano_ids", () =&amp;gt; {
  return JSON.parse(open("./nanoids.json"));
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com as massas definidas e a conexão com o banco de dados aberta, podemos definir nossa consulta na fase de execução. O propósito é distribuir os IDs carregados no sharedArray entre todas as VUs planejadas durante o tempo de execução, realizar uma consulta ao banco, e confirmar que foram retornados dados da consulta. Como não definiremos um atraso nas configurações, as VUs vão realizar quantas requisições conseguirem no intervalo de tempo configurado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function (db) {
  const nanoId = nanoIds[Math.floor(Math.random() * nanoIds.length)];

  const result = db.query(QUERY_DETALHE_VAGA, nanoId);

  check(result, {
    "consulta executada": (rows) =&amp;gt; rows.length &amp;gt;= 0,
  });

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pós execução, na fase de desmontagem, finalizaremos fechando nossa conexão com o banco de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function teardown(db) {
  db.close();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resultados do script🧑‍🔬
&lt;/h2&gt;

&lt;p&gt;No resultado de saída pós-execução, teremos os principais indicadores das iterações, incluindo avg, min, med, max e os percentis p(90) e p(95).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  █ THRESHOLDS

    iteration_duration
    ✗ 'p(90)&amp;lt;300' p(90)=494.15ms


  █ TOTAL RESULTS

    checks_total.......: 100     21.726862/s
    checks_succeeded...: 100.00% 100 out of 100
    checks_failed......: 0.00%   0 out of 100

    ✓ consulta executada

    EXECUTION
    iteration_duration...: avg=458.63ms min=324.57ms med=408.59ms max=1.06s p(90)=494.15ms p(95)=1.06s
    iterations...........: 100 21.726862/s
    vus..................: 10  min=10      max=10
    vus_max..............: 10  min=10      max=10

    NETWORK
    data_received........: 0 B 0 B/s
    data_sent............: 0 B 0 B/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Dois pontos importantes dos resultados obtidos com script contruido acima: o primeiro é que não atingimos o limite estabelecido, nosso percentil p(90) ficou em 494ms. O segundo, o drop de conexões com o banco de dados. O tempo mínimo de resposta obtido da nossa query foi de 324ms, ou seja, o menor valor obtido das 100 iterações também esteve bem acima do nosso baseline.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Otimizando nossa consulta👩‍💻
&lt;/h2&gt;

&lt;p&gt;Agora, com as ferramentas de IA Generativa como nossas aliadas durante todo o ciclo de desenvolvimento, podemos fornecer nossas queries ao banco, a modelagem lógica e receber sugestões de melhorias de performance. Foi o que realizamos, fornecemos nossa consulta ao Claude e recebemos algumas sugestões, entre elas a criação dos seguintes índices no banco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Filtro principal por identificador público (ex: slug, uuid, hash)
CREATE UNIQUE INDEX idx_main_public_id
  ON main_entity (public_id);

-- Índices para JOINs por chave estrangeira
CREATE INDEX idx_main_fk_company
  ON main_entity (company_id);

CREATE INDEX idx_main_fk_details
  ON main_entity (details_id);

-- JOIN crítico por campo textual (ex: URL, username, email)
CREATE INDEX idx_related_text_key
  ON related_entity (text_key);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Foram preservadas os nomes reais de entidades do banco de dados.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reexecutando nosso script após a criação dos índices no banco de dados e mantendo a mesma query, obtivemos os seguintes resultados&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  █ THRESHOLDS

    iteration_duration
    ✗ 'p(90)&amp;lt;300' p(90)=411.45ms


  █ TOTAL RESULTS

    checks_total.......: 100     5.006751/s
    checks_succeeded...: 100.00% 100 out of 100
    checks_failed......: 0.00%   0 out of 100

    ✓ consulta executada

    EXECUTION
    iteration_duration...: avg=399.1ms min=279ms med=408.2ms max=1.16s p(90)=411.45ms p(95)=416.13ms
    iterations...........: 100 5.006751/s
    vus..................: 10   min=2      max=2
    vus_max..............: 10   min=2      max=2

    NETWORK
    data_received........: 0 B 0 B/s
    data_sent............: 0 B 0 B/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos observar no nosso segundo resultado, a simples criação de índices melhorou nosso percentil p(90), com uma redução de aproximadamente 90ms, e nosso valor mínimo obtido esteve abaixo dos 300ms do baseline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nosso experimento foi conduzido em execução única utilizando um banco de dados free da ferramenta Supabase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;A performance de queries no banco de dados é um fator crítico que impacta diretamente a experiência do usuário e a escalabilidade de aplicações. &lt;/p&gt;

&lt;p&gt;Como demonstrado neste artigo, com o uso do &lt;code&gt;xk6-sql&lt;/code&gt; foi possivel identificar gargalos de performance em consultas SQL de forma isolada, permitindo estabelecer baselines claros e monitorar a degradação ao longo do tempo. &lt;/p&gt;

&lt;p&gt;Integrar testes de performance de banco de dados conduzindo experimentos no seu cilco de desenvolvimento, não apenas previne problemas em produção, mas também fornece métricas objetivas para priorizar otimizações e validar melhorias antes que impactem os usuários finais.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Confira meu curso na Udemy!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>performance</category>
      <category>testing</category>
      <category>ai</category>
      <category>k6</category>
    </item>
    <item>
      <title>Leitura de arquivos CSV com k6</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Sun, 12 Oct 2025 21:15:59 +0000</pubDate>
      <link>https://forem.com/marlo2222/leitura-de-arquivos-csv-com-k6-36lo</link>
      <guid>https://forem.com/marlo2222/leitura-de-arquivos-csv-com-k6-36lo</guid>
      <description>&lt;p&gt;Na realização de testes de performance e outros tipos de testes funcionais e não funcionais, a parametrização de informações de forma dinâmica é frequentemente utilizada. Entre os tipos de arquivos mais comuns, podemos citar CSV e JSON.&lt;/p&gt;

&lt;p&gt;Neste artigo, veremos como podemos manipular dados de arquivos CSV de forma eficiente com K6 utilizando o módulo experimental &lt;code&gt;k6/experimental/csv&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;K6 instalado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conhecendo o módulo CSV👩‍💻
&lt;/h2&gt;

&lt;p&gt;O módulo CSV foi introduzido ao K6 na versão 0.54, estando atualmente no ciclo de vida experimental, onde a comunidade pode sugerir melhorias e sugestões via &lt;a href="https://github.com/grafana/k6/issues" rel="noopener noreferrer"&gt;issue&lt;/a&gt; no GitHub do K6.&lt;/p&gt;

&lt;p&gt;Foi construído pensando em oferecer aos usuários uma solução com equilíbrio entre desempenho e utilização de memória, oferecendo a possibilidade de analisar arquivos completos ou em fluxo via streaming, utilizando as seguintes operações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;csv.parse()&lt;/strong&gt;: função que analisa um arquivo CSV completo utilizando uma estrutura de SharedArray distribuída entre todas as VUs por meio do processamento baseado em Go.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;csv.Parser&lt;/strong&gt;: classe utilizada como um fluxo de streaming que lê os arquivos CSV linha por linha, otimizando o uso de memória.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configurações disponíveis para utilização📋
&lt;/h2&gt;

&lt;p&gt;Tanto o &lt;code&gt;csv.parse()&lt;/code&gt; quanto a classe &lt;code&gt;csv.Parser&lt;/code&gt; permitem informar um objeto de options via construtor no momento de utilização, onde podemos descrever &lt;a href="https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/csv/options/" rel="noopener noreferrer"&gt;algumas configurações&lt;/a&gt; que queremos utilizar na manipulação do arquivo CSV.&lt;/p&gt;

&lt;p&gt;Entre as principais propriedades que podemos definir nesse objeto, temos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;delimiter&lt;/strong&gt;: caractere delimitador no seu CSV, onde o padrão é &lt;code&gt;,&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;asObjects&lt;/strong&gt;: &lt;code&gt;true&lt;/code&gt; se deseja que seu arquivo seja analisado como um objeto JavaScript. Caso &lt;code&gt;false&lt;/code&gt;, os dados serão analisados como matrizes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;skipFirstLine&lt;/strong&gt;: se a primeira linha do CSV deve ser ignorada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fromLine&lt;/strong&gt;: a partir de qual linha gostaria de iniciar a leitura do CSV&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;toLine&lt;/strong&gt;: em qual linha a leitura do CSV deve ser interrompida&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ponto de atenção⚠️
&lt;/h3&gt;

&lt;p&gt;Caso você defina a configuração &lt;code&gt;asObjects&lt;/code&gt; como &lt;code&gt;true&lt;/code&gt; e adicione a configuração &lt;code&gt;skipFirstLine&lt;/code&gt; também como &lt;code&gt;true&lt;/code&gt;, receberá uma saída com o seguinte erro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERRO[0000] failed to create a new parser; reason: the 'header' option cannot be enabled when 'skipFirstLine' is true  hint="script exception"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso ocorre porque os cabeçalhos do CSV são necessários para o mapeamento correto do objeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lendo um arquivo CSV📄
&lt;/h2&gt;

&lt;p&gt;Para este tutorial, utilizaremos o seguinte arquivo CSV:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;email, senha
0.09343697636021378@mail.com,user123
0.9820042509287148@mail.com,user123
0.8563382158459437@mail.com,user123
0.8227514039300216@mail.com,user123
0.9817821397952566@mail.com,user123
0.914560286115773@mail.com,user123
0.6211272282511351@mail.com,user123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inicialmente, na fase de inicialização, precisamos definir dois módulos que são essenciais: &lt;code&gt;k6/experimental/fs&lt;/code&gt; e &lt;code&gt;k6/experimental/csv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { open } from 'k6/experimental/fs';
import csv from 'k6/experimental/csv';
import { scenario } from 'k6/execution';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Em alguns tutoriais, pode ser observada a utilização da função &lt;code&gt;open&lt;/code&gt; do JavaScript. A utilização da função &lt;code&gt;open&lt;/code&gt; do módulo experimental fs nos dá todos os benefícios de um módulo nativo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Analisando um arquivo completo🔍
&lt;/h3&gt;

&lt;p&gt;Podemos utilizar a função open para criar uma constante para nosso arquivo CSV:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const file = await open('usuarios.csv');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por meio da função &lt;code&gt;parser()&lt;/code&gt;, carregar nossos dados como uma matriz em um sharedArray, informando o arquivo aberto anteriomente, e o objeto de options com as configurações de leitura do CSV:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const usuariosCsv = new csv.parser(file, { delimiter: ',', skipFirstLine: true });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nesse exemplo, estamos definindo as configurações de delimitação das linhas e ignorarando a primeira linha do arquivo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E para acessa o conteudo do CSV podemos simplismente acessar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default async function () {
  console.log(usuariosCsv[scenario.iterationInTest]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Estamos utilizando as iterações do K6 como um índice para acessar as linhas do nosso CSV. Como todo o arquivo é carregado como uma matriz em um SharedArray, podemos acessar os valores individualmente com os índices das linhas e colunas, exemplo: &lt;code&gt;usuariosCsv[indiceLinha][indiceColuna]&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caso seja utilizada a propriedade &lt;code&gt;asObjects: true&lt;/code&gt;, o acesso às informações da linha pode ser simplesmente feito como um objeto chave-valor::&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const usuariosCsv = new csv.parser(file, { delimiter: ',', asObjects: true });

export default async function () {
  console.log(usuariosCsv[scenario.iterationInTest].email);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Analisando um arquivo como um fluxo🌀
&lt;/h3&gt;

&lt;p&gt;Semelhante ao passo anterior, vamos utilizar a função open para criar uma constante para nosso arquivo CSV:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const file = await open('usuarios.csv');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por meio da classe &lt;code&gt;Parser()&lt;/code&gt;, carregar as informações do nosso CSV como um fluxo de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const usuariosCsv = new csv.Parser(file, { skipFirstLine: true });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E para acessa o conteudo do CSV, podemos utilizar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const { done, value } = await usuariosCsv.next();

  console.log(`usuario: ${value[0]}, senha: ${value[1]}`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;usuariosCsv.next()&lt;/code&gt; retorna um objeto com duas propriedades: a primeira, um valor booleano que indica se o fim do arquivo CSV foi alcançado; e a segunda, os dados em si da linha do arquivo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como estamos falando de um fluxo, temos otimização de recursos. No entanto, devemos nos preocupar com tratativas de acesso a linhas inexistentes.&lt;/p&gt;

&lt;p&gt;Assim como no exemplo anterior, também podemos considerar o fluxo de leitura de dados como um objeto com a propriedade &lt;code&gt;asObjects: true&lt;/code&gt;, onde nosso código será algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const file = await open('usuarios.csv');
const usuariosCsv = new csv.Parser(file, { asObjects: true });

export default async function () {

   const { done, value } = await usuariosCsv.next();

   console.log(`usuario: ${value.usuario}, senha: ${value.senha}`);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;O K6 tem passado por um processo de modernização, priorizando módulos nativos e otimizados. Os módulos CSV e fs são um retrato desse momento.&lt;br&gt;
Quanto às estratégias de leitura, arquivo completo ou fluxo, podemos tirar dois aprendizados importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leitura completa com csv.parse()&lt;/strong&gt;: pode levar ao aumento do uso de memória e do tempo de inicialização quando lida com arquivos muito grandes. No entanto, é extremamente eficiente em leitura e acesso distribuído entre VUs utilizando SharedArray.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leitura em fluxo com csv.Parser&lt;/strong&gt;: lê o arquivo linha por linha, mantendo o uso de memória baixo e evitando carregar todo o CSV na memória, mantendo um maior controle do usuário sobre o processamento das informações. No entanto, o usuário deve estar atento à sua responsabilidade de implementação de controle de fluxo ao atingir o fim do arquivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Confira meu curso na Udemy!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>programming</category>
      <category>performance</category>
      <category>testing</category>
    </item>
    <item>
      <title>How i simplified my performance testing setup with StackSpot AI</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Sun, 27 Jul 2025 18:17:49 +0000</pubDate>
      <link>https://forem.com/marlo2222/how-i-simplified-my-performance-testing-setup-with-stackspot-ai-1g6a</link>
      <guid>https://forem.com/marlo2222/how-i-simplified-my-performance-testing-setup-with-stackspot-ai-1g6a</guid>
      <description>&lt;p&gt;A utilização de ferramentas de IA tem se tornado uma pratica comum no ciclo de desenvolvimento de software, o que inclui a etapa de testes. &lt;/p&gt;

&lt;p&gt;Soluções baseadas em IA e Agentes especialidos tem sido utilizados em todas as etapas de teste, desde plnejamento, modelagem e execução, auxiliando em procesos antes extremanente manuais e simplificando atualmente os processos automatizados.&lt;/p&gt;

&lt;p&gt;Como em testes funcionais, os testes não funcionais tambem necessitam de planejamento, modelagem e execução, nesse artigo, veremos como uma Agent de IA especializado em testes de performance criado com StackSpot AI, pode simplificar a criação de testes de performance com K6.&lt;/p&gt;

&lt;h2&gt;
  
  
  StackSpot AI
&lt;/h2&gt;

&lt;p&gt;A Stackspot AI é uma solução de agents inteligentes que auxiliam em todo ciclo de desenvolvimento de software e que fazem parte da plataforma de desenvolvimento Stackspot. Enquanto outras ferramentas de IA generativa podem em inumera situações te fornecer respostas genéricas (ou até alucinações por falta de contexto), a StackSpot AI trabalha com hipercontextualização.&lt;/p&gt;

&lt;p&gt;Na prática, isso significa que a StackSpot AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conhece seu código: Entende padrões, estruturas e convenções do seu projeto.&lt;/li&gt;
&lt;li&gt;Respeita sua stack: Não vai sugerir tecnologias aleatórias que não fazem sentido.&lt;/li&gt;
&lt;li&gt;Considera regras de negócio: Incorpora documentação, APIs e especificações da sua empresa.
Adapta-se ao time: Aprende com as práticas e metodologias estabelecidas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não é somente sobre entender o projeto atual, a StackSpot AI compreende o ecossistema completo da sua organização. Ela conecta diferentes projetos, padrões corporativos e conhecimento institucional para entregar sugestões realmente relevantes.&lt;/p&gt;

&lt;p&gt;Existem alguns conceitos extremamente importantes sobre StackSpot AI, e que serão abordados nesse artigo, sendo eles: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge Source&lt;/li&gt;
&lt;li&gt;Quick Command&lt;/li&gt;
&lt;li&gt;Agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Knowledge Sources são as bases de conhecimento que você alimenta na ferramenta - desde snippets de código e documentação técnica até APIs e padrões internos da empresa. É aqui que mora a mágica da hipercontextualização: quanto mais conhecimento relevante você adicionar, mais precisas ficam as sugestões e respostas da STackspot AI.&lt;/p&gt;

&lt;p&gt;Quick Commands funcionam como atalhos inteligentes para tarefas repetitivas do dia a dia. Quer gerar testes unitários, documentar código ou fazer refatoração? Podemos transforma isso em comandos rapidos.&lt;/p&gt;

&lt;p&gt;Agents são especialistas virtuais focados em áreas específicas do desenvolvimento. Pense neles como colegas de equipe que nunca se cansam: um para revisar código, outro para transformar requisitos em user stories detalhadas, outro para caçar vulnerabilidades de segurança. Cada agent é treinado para uma função específica, garantindo expertise e qualidade nas entregas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como leitura complementar recomendo o artigo &lt;a href="https://stackspot.com/pt/blog/stackspot-ai" rel="noopener noreferrer"&gt;StackSpot AI: sua plataforma multiagentes de Inteligência Artificial para o ciclo de desenvolvimento de software&lt;/a&gt; do blog oficial da StackSpot, bem como o artigo &lt;a href="https://dev.to/rafaelbercam/mudando-o-jogo-com-stackspot-ai-testes-automatizados-155a"&gt;Mudando o Jogo com StackSpot AI &amp;amp; Testes Automatizados&lt;/a&gt; do colega &lt;a href="https://www.linkedin.com/in/rafaelbercam/" rel="noopener noreferrer"&gt;Rafael Berçam&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Como o K6 entra no topico AI?
&lt;/h2&gt;

&lt;p&gt;Quem acompanha minhas publicações aqui no dev.to, deve esta familiariazado com inumeras publicações sobre o assunto testes de performance &amp;amp; K6. &lt;/p&gt;

&lt;p&gt;o &lt;a href="https://github.com/grafana/k6" rel="noopener noreferrer"&gt;k6&lt;/a&gt; é uma ferramenta open source para realização de testes de performance modernos baseados em script, pensada para desenvolvedores e testadores na nova era do DevOps. É uma solução open source que hoje faz parte da Grafana Labs.&lt;/p&gt;

&lt;p&gt;Por ser uma solução Open Source e recente no mercado, correções e novas funcionalidades estão frequentemente sendo lançadas e disponibilizadas para a comunidade, isso implicar em muitas resposta de ferramentas de IA com contexto de versões antigas da ferramenta. vejamos dois experimentos basicos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leitura eficiente de um arquivo CSV
&lt;/h3&gt;

&lt;p&gt;Ao realizamos a simples pergunta &lt;code&gt;_You're an expert at creating performance tests with the K6 tool. How can you read a mass of data in CSV format most efficiently using the tool?_&lt;/code&gt; aos principais modelos do mercado: &lt;code&gt;Claude&lt;/code&gt;, &lt;code&gt;Gemini&lt;/code&gt;e &lt;code&gt;GPT&lt;/code&gt;, observamos um vies de resposta com base em soluções de versões antigas do K6, como baseadas na jslib.k6, menos performatica que os recentes modulos nativos: &lt;/p&gt;

&lt;h4&gt;
  
  
  Claude Sonnet 4
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SharedArray } from 'k6/data';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';

const csvData = new SharedArray('users', function () {
  return papaparse.parse(open('./users.csv'), { header: true }).data;
});

export default function () {
  // Access data efficiently
  const user = csvData[Math.floor(Math.random() * csvData.length)];
  console.log(user.email);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  GPT-4o
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SharedArray } from 'k6/data';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';

const csvData = new SharedArray('user data', function () {
  const f = open('../data/users.csv');
  return papaparse.parse(f, { header: true }).data;
});

export default function () {
  const user = csvData[Math.floor(Math.random() * csvData.length)];

  // Example use
  console.log(`Using user ${user.username}`);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Gemini 2.5 Flash
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { open } from 'k6/experimental/fs';
import csv from 'k6/experimental/csv';
import { SharedArray } from 'k6/data';
import http from 'k6/http';
import { check, sleep } from 'k6';
import { vu } from 'k6/execution';


const csvData = new SharedArray('CSV data', function () {
    const file = open('./users.csv');
    // asObjects: true will parse each row into an object using header names as keys
    return csv.parse(file, { header: true, asObjects: true });
});

export const options = {
    vus: 10,
    duration: '30s',
    thresholds: {
        http_req_failed: ['rate&amp;lt;0.01'], // http errors should be less than 1%
        http_req_duration: ['p(95)&amp;lt;200'], // 95% of requests should be below 200ms
    },
};

export default function () {
    // Get a unique row of data for each VU iteration
    // A common pattern is to use __VU or __ITER to select unique data.
    // Ensure you have enough data in your CSV for the number of VUs and iterations.
    const user = csvData[vu.idInTest % csvData.length]; // Example: round-robin selection

    console.log(`VU ${vu.idInTest} using user: ${user.username}`);

    const payload = JSON.stringify({
        username: user.username,
        password: user.password,
    });

    const params = {
        headers: {
            'Content-Type': 'application/json',
        },
    };

    const res = http.post('https://api.example.com/login', payload, params);

    check(res, {
        'status is 200': (r) =&amp;gt; r.status === 200,
        'login successful': (r) =&amp;gt; r.json().message === 'Login successful',
    });

    sleep(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Uma resalva ao modelo do Google. O Gemini foi o unico modelo a mencionar o novo modulo do k6 de leitura de CSV k6/experimental/csv, lançado na versão v0.57.0, a pouco menos de 4 meses atras, na data que escrevo essa publicação. No entanto, tambem mencionou, baseados em soluções do jslib.k6.&lt;/p&gt;

&lt;p&gt;Claude e GPT se basearam na solução baseado em um modulo papaparse da jslib.k6, menos eficiente e com mais utilização de recursos computacionais.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  utilizando um modulo para geração de dados fakes
&lt;/h3&gt;

&lt;p&gt;Este é um outro ponto que quem trabalha com k6 frequentemente vai utilizar, a geração de dados com o modulo faker.&lt;/p&gt;

&lt;p&gt;Até um certo tempo atrás havia a necessidade de utilização de uma solução chamada XK6 que permitia a utilização de alguns modulos experimentais, gerando um binario alternativo do k6 para execução. No entanto isso abandonado na versão v1.0.0, necessitando apenas informar a flag &lt;code&gt;K6_BINARY_PROVISIONING=true&lt;/code&gt; na cli, e o k6 ficando responsavel pelo restante.&lt;/p&gt;

&lt;p&gt;Ao executar o seguinte prompt: &lt;code&gt;Create a simple k6 performance testing script that uses the k6/x/faker module to efficiently generate fake data, providing instructions for executing the script at the end.&lt;/code&gt; Podemos observar que as instruções de execução dos modelos ainda utilizavam um contexto antigo de solução como resposta.&lt;/p&gt;

&lt;h4&gt;
  
  
  Claude Sonnet 4
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Install k6 (if not already installed):

#Install the k6 faker extension:

# Download and install xk6 (k6 extension builder)
go install go.k6.io/xk6/cmd/xk6@latest

# Build k6 with the faker extension
xk6 build --with github.com/szkiba/xk6-faker@latest

# This creates a custom k6 binary with faker support

$Running the Script
./k6 run performance-test.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  GPT-4o
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ How to Run This Script
Note: The x/faker module is an extension and requires a custom k6 binary built with xk6.

1. 🧰 Install xk6 (if not already installed)

go install go.k6.io/xk6/cmd/xk6@latest
2. 🔧 Build a custom k6 binary with x/faker

xk6 build latest --with github.com/szkiba/xk6-faker
This will create a k6 binary in your current directory.

3. ▶️ Run the script
./k6 run script.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Gemini 2.5 Flash
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To execute this script, follow these steps:

Install k6: If you don't have k6 installed, you can download it from the official k6 website: https://k6.io/docs/getting-started/installation/

Install the xk6-faker extension: The k6/x/faker module is part of the xk6-faker extension. You need to build a custom k6 binary with this extension. Open your terminal or command prompt and run:

k6 run --bundle github.com/k6io/xk6-faker@latest

This command will download the xk6-faker extension and build a k6 binary that includes it. The command will also run the bundle.

Save the script: Copy the provided JavaScript code and save it as a .js file (e.g., faker_test.js).

Run the k6 test: Navigate to the directory where you saved faker_test.js in your terminal or command prompt, and then run the test using the custom k6 binary you just built:

k6 run faker_test.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Consideramos apenas a resposta dos modelos as instruções de execução. Todos os modelos criaram scripts funcionais para o modulo k6/x/faker, no entanto com instruções defasadas de execução.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Escolha do melhor executor para teste de performance
&lt;/h3&gt;

&lt;p&gt;Como ultimo cenario sobre contextualização dos modelos do mercado, podemos analisar funcionalidades do k6 que não tiverão mudanças significativa ao longa do seu ciclo de vida, uma dessa funcionalidades sao os &lt;a href="https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/" rel="noopener noreferrer"&gt;executores&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Para testes de performance com K6, a escolha do executor correto está muita das vezes atrelado ao sucesso do testes baseado nos requisitos não funcionais definidos. &lt;/p&gt;

&lt;p&gt;Utilizamos os requisito não funcionais da documentação publica do &lt;a href="https://openbanking-brasil.github.io/areadesenvolvedor-fase1/#schemas-nivel-de-desempenho" rel="noopener noreferrer"&gt;open finance fase 1&lt;/a&gt; para criar o seguinte prompt referente aos  limites de tráfego de requisições: &lt;code&gt;Given the following non-functional performance requirements of a central bank integration solution, specify which best executor should be configured in a performance test script with k6, the main focus of this script is to ensure the achievement of the stipulated TPS&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Claude Sonnet 4
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';

// Custom metrics to track rate limiting
const rateLimitErrors = new Rate('rate_limit_errors');

export const options = {
  scenarios: {
    // Primary scenario for TPS testing - uses constant-arrival-rate executor
    tps_load_test: {
      executor: 'constant-arrival-rate',
      rate: 300, // 300 TPS globally as specified
      timeUnit: '1s',
      duration: '5m', // 5 minute test duration
      preAllocatedVUs: 50, // Pre-allocated VUs for immediate start
      maxVUs: 200, // Maximum VUs that can be spawned
      tags: { test_type: 'tps_validation' },
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  GPT-4o
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  scenarios: {
    global_tps_test: {
      executor: 'constant-arrival-rate',
      rate: 300, // 300 iterations (transactions) per second
      timeUnit: '1s', // 300 iterations per 1 second
      duration: '5m', // Test duration for 5 minutes
      preAllocatedVUs: 50, // Initial number of VUs to pre-allocate
      maxVUs: 500, // Maximum number of VUs k6 can spin up
    },
  },
  thresholds: {
    http_req_failed: ['rate&amp;lt;0.01'], // http errors should be less than 1%
    http_req_duration: ['p(95)&amp;lt;2000'], // 95% of requests should be below 2000ms
    'http_req_duration{status:429}': ['count&amp;lt;100'], // Example: Allow up to 100 429 responses
  },
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Gemini 2.5 Flash
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check } from 'k6';

export const options = {
  scenarios: {
    tps_target: {
      executor: 'constant-arrival-rate',
      rate: 300, // 300 requisições por segundo
      timeUnit: '1s',
      duration: '1m', // duração do teste
      preAllocatedVUs: 100, // estimativa inicial de VUs
      maxVUs: 500, // máximo permitido
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;É evidente uma maior acertividade dos modelos em especificações mais antigas da ferramenta, onde o contexto fornecido no momento de treinamento, permitiu uma acertividade por todos os modelos utilizados para o prompt informado. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Montando um agent hipercontextualização em k6
&lt;/h3&gt;

</description>
      <category>ai</category>
      <category>performance</category>
      <category>k6</category>
      <category>stackspot</category>
    </item>
    <item>
      <title>Utilizando SharedArray com k6</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Wed, 09 Apr 2025 23:15:50 +0000</pubDate>
      <link>https://forem.com/marlo2222/utilizando-sharedarray-com-k6-1iig</link>
      <guid>https://forem.com/marlo2222/utilizando-sharedarray-com-k6-1iig</guid>
      <description>&lt;p&gt;O uso de dados em testes de performance é uma etapa essencial do planejamento e, ao mesmo tempo, um dos grandes desafios dessa prática. A conhecida massa de teste, frequentemente utilizada em testes funcionais, apresenta obstáculos como manutenção, validade e renovação dos dados. &lt;/p&gt;

&lt;p&gt;Em testes não funcionais, esses desafios se tornam ainda mais evidentes devido à necessidade de grandes volumes de dados para simular cenários em alta escala, o que pode resultar em um alto consumo de recursos computacionais.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos como o K6 gerência dados de teste, e de que forma o SharedArray pode otimizar o uso de recursos, tornando seus testes mais eficientes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;K6 instalado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Um erro comum🗣️
&lt;/h2&gt;

&lt;p&gt;Como o K6 utiliza a sintaxe do JavaScript para a criação de scripts, muitos usuários acabam, erroneamente, empregando funções nativas da linguagem de forma inadequada. Um dos erros mais comuns é o uso da função &lt;code&gt;open()&lt;/code&gt; para abertura e manipulação de arquivos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
    vus: 5,
    duration: '10s',
}

const data = JSON.parse(open('./data.json'));

export default function () {
  console.log(data[0].username);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, cada VU terá sua própria cópia do conteúdo de &lt;code&gt;data.json&lt;/code&gt;, manipulando-o ao longo do seu ciclo de vida. Em um cenário simples, o impacto no uso de memória e CPU pode não ser perceptível para o usuário ou o ambiente. No entanto, vamos analisar um cenário mais realista:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
    stages: [
    { duration: '15m', target: 300 },
    { duration: '30m', target: 300 },
    { duration: '15m', target: 0 },
  ],
}

const data = JSON.parse(open('./data.json'));

export default function () {
  console.log(data[0].username);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, modelamos um cenário um pouco diferente: um teste com pico de 300 VUs rodando em um ambiente com memória limitada. Se o arquivo &lt;code&gt;data.json&lt;/code&gt; for grande o suficiente, a execução do script pode ser interrompida por falta de memória.&lt;/p&gt;

&lt;p&gt;Além disso, mesmo que haja memória disponível, o impacto no uso da CPU pode ser significativo. Como o K6 é escrito em Go, ele conta com um garbage collector que percorre todos os objetos instanciáveis, incluindo os do Javascript, para identificar quais podem ser descartados. Em cenários onde grandes matrizes de dados são copiadas centenas de vezes, esse processo pode gerar uma sobrecarga adicional na CPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  O modulo fs🧠
&lt;/h2&gt;

&lt;p&gt;O K6 disponibiliza um módulo experimental de file system(fs), oferecendo uma alternativa mais eficiente para lidar com interações com arquivos dentro dos scripts de teste. Esse módulo permite abrir arquivos, ler seu conteúdo, realizar buscas e recuperar metadados de forma otimizada.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { open } from 'k6/experimental/fs';&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Uma das principais vantagens de utilização da função &lt;code&gt;open()&lt;/code&gt; do modulo file system é sua eficiência na utilização de memória. Diferente da função &lt;code&gt;open()&lt;/code&gt; tradicional do javascript, que carrega um arquivo várias vezes em memória para cada Vu, o módulo file system reduz o uso de memória carregando o arquivo o mínimo possível e compartilhando o mesmo endereço de memoria entre todas as VUs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { open } from 'k6/experimental/fs';

const data = await open('./data.txt');

export default async function () {
  console.log(JSON.parse(data));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conhecendo o modulo SharedArray📚
&lt;/h2&gt;

&lt;p&gt;O SharedArray é uma função disponível no módulo &lt;code&gt;k6/data&lt;/code&gt; e oferece uma forma eficiente de manipular dados em testes de performance com o K6. Ele atua como um array que é inicializado apenas uma vez e compartilha seu endereço de memória entre todas as VUs, reduzindo o consumo de recursos e melhorando a eficiência dos testes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SharedArray } from 'k6/data';

const data = new SharedArray('some name', function () {
  const dataArray = [];
  // more operations
  return dataArray; // must be an array
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;O SharedArray deve ser criado durante a fase de inicialização do teste. Entre os requisitos para sua configuração, é necessário atribuir um nome a função anônima e garantir que o retorno seja um array. Caso a criação do sharedArray ocorra fora do escopo de inicialização, uma exceção será lançada durante a execução do teste.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quando falamos em dados compartilhados, é comum pensar em condições de corrida ou concorrência. No entanto, o SharedArray funciona apenas para leitura, eliminando esses problemas. As operações suportadas incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Obter o número de elementos com length&lt;/li&gt;
&lt;li&gt;Acessar um elemento pelo índice usando array[index]&lt;/li&gt;
&lt;li&gt;Iterar sobre os dados com for-of loops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para conjuntos de dados pequenos, o SharedArray pode ter um desempenho inferior à função &lt;code&gt;open()&lt;/code&gt; do módulo filesystem e a função &lt;code&gt;open()&lt;/code&gt; do javascript. No entanto, a eficiência depende do caso de uso e do modelo do teste.&lt;/p&gt;

&lt;p&gt;Para fins de comparação, a equipe do K6 realizou um experimento com 100 VUs, executando um script com arquivos de diferentes tamanhos e quantidade de linhas para avaliar o impacto no desempenho.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { check } from 'k6';
import http from 'k6/http';
import { SharedArray } from 'k6/data';

const n = parseInt(__ENV.N);
function generateArray() {
  const arr = new Array(n);
  for (let i = 0; i &amp;lt; n; i++) {
    arr[i] = { something: 'something else' + i, password: '12314561' };
  }
  return arr;
}

let data;
if (__ENV.SHARED === 'true') {
  data = new SharedArray('my data', generateArray);
} else {
  data = generateArray();
}

export default function () {
  const iterationData = data[Math.floor(Math.random() * data.length)];
  const res = http.post('https://quickpizza.grafana.com/api/post', JSON.stringify(iterationData), {
    headers: { 'Content-type': 'application/json' },
  });
  check(res, { 'status 200': (r) =&amp;gt; r.status === 200 });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Script utilizado para benchmark.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para arquivos de até 1.000 linhas, a abordagem de compartilhamento de dados do SharedArray e a cópia de dados na memória da função &lt;code&gt;open()&lt;/code&gt; do JavaScript apresentaram resultados semelhantes. No entanto, para arquivos com mais de 10.000 linhas, observou-se uma diferença significativa no uso de recursos, como pode ser visto na tabela abaixo:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Qtd linhas&lt;/th&gt;
&lt;th&gt;Compartilhado&lt;/th&gt;
&lt;th&gt;CPU %&lt;/th&gt;
&lt;th&gt;Uso de MEM&lt;/th&gt;
&lt;th&gt;Solicitações HTTP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;verdadeiro&lt;/td&gt;
&lt;td&gt;70-79%&lt;/td&gt;
&lt;td&gt;213-217 MB&lt;/td&gt;
&lt;td&gt;92191-98837&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;falso&lt;/td&gt;
&lt;td&gt;74-75%&lt;/td&gt;
&lt;td&gt;224-232 MB&lt;/td&gt;
&lt;td&gt;96851-98643&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;verdadeiro&lt;/td&gt;
&lt;td&gt;74-79%&lt;/td&gt;
&lt;td&gt;209-216 MB&lt;/td&gt;
&lt;td&gt;98251-98806&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;falso&lt;/td&gt;
&lt;td&gt;75-77%&lt;/td&gt;
&lt;td&gt;333-339 MB&lt;/td&gt;
&lt;td&gt;98069-98951&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;verdadeiro&lt;/td&gt;
&lt;td&gt;78-79%&lt;/td&gt;
&lt;td&gt;213-217 MB&lt;/td&gt;
&lt;td&gt;97953-98735&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;falso&lt;/td&gt;
&lt;td&gt;80-83%&lt;/td&gt;
&lt;td&gt;1364-1400 MB&lt;/td&gt;
&lt;td&gt;96816-98852&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;verdadeiro&lt;/td&gt;
&lt;td&gt;78-79%&lt;/td&gt;
&lt;td&gt;238-275 MB&lt;/td&gt;
&lt;td&gt;98103-98540&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;falso&lt;/td&gt;
&lt;td&gt;120-124%&lt;/td&gt;
&lt;td&gt;8,3-9,1 GB&lt;/td&gt;
&lt;td&gt;96003-97802&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Compartilhado representa a utilização de sharedArray. Números puramente ilustrativos em experimento conduzido pela equipe do K6.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Utilizando SharedArray
&lt;/h2&gt;

&lt;p&gt;O processo de utilização do SharedArray em arquivos é bastante simples. O usuário precisa apenas encapsular sua estrutura de dados dentro do SharedArray.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = new SharedArray('nome funcao', function () {
  return dataArray; // must be an array
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Arquivos JSON📄
&lt;/h3&gt;

&lt;p&gt;Para a leitura de arquivos json, podemos utilizar a função &lt;code&gt;open()&lt;/code&gt; do javascript ou do modulo file system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SharedArray } from 'k6/data';

const data = new SharedArray('leitura dados', function () {
  return JSON.parse(open('./data.json')).users;
});

export default function () {
  console.log(data[0].username);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "users": [
    { "username": "test", "password": "qwerty" },
    { "username": "test", "password": "qwerty" }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a abertura do arquivo, podemos realizar o parse para JSON utilizando a função &lt;code&gt;JSON.parse()&lt;/code&gt;. A estrutura de dados retornada pela nossa função anônima será encapsulada pelo SharedArray, e os dados serão distribuídos entre todas as VUs por meio da constante data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arquivos CSV📄
&lt;/h3&gt;

&lt;p&gt;Na leitura de arquivos CSV, utilizava-se o módulo PapaParse juntamente com o k6.jslib para realizar o parse dos dados lidos. Em seguida, o SharedArray era utilizado para distribuir os dados entre as VUs de forma eficiente.&lt;/p&gt;

&lt;p&gt;Na leitura de arquivos CSV, utilizava-se o módulo &lt;code&gt;PapaParse&lt;/code&gt; da  &lt;code&gt;k6.jslib&lt;/code&gt; para realizar o parse dos dados lidos. Em seguida, o SharedArray é utilizado para distribuir os dados entre as VUs de forma eficiente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';
import { SharedArray } from 'k6/data';

const csvData = new SharedArray('leitura csv', function () {
  // Leitura e parse do CSV
  return papaparse.parse(open('./data.csv'), { header: true }).data;
});

export default function () {
  // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir da versão &lt;strong&gt;0.54&lt;/strong&gt; do K6, foi introduzido o módulo experimental &lt;code&gt;k6/experimental/csv&lt;/code&gt;, que simplifica esse processo. Agora, não é mais necessário utilizar o módulo PapaParse para realizar o parse dos dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { open } from 'k6/experimental/fs';
import csv from 'k6/experimental/csv';

const file = await open('data.csv');

const dadosCsv = await csv.parse(file, { delimiter: ',' });

export default async function () {
  // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma combinação dos modulos file system e csv simplifica o processo de leitura, onde a função csv.parse() já encpasula os dados brutos em um sharedArray para melhorar o desempenho de utilização de dados.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ambos os modulos csv e fs estão atualmente em fase experimental, ou seja, passando por melhorias e análise de possiveis problemas pela comunidade, antes de se tornarem parte do core do k6. Para conhecer melhor ambos os modulos acesse: &lt;a href="https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/csv/" rel="noopener noreferrer"&gt;csv&lt;/a&gt; e  &lt;a href="https://grafana.com/docs/k6/latest/javascript-api/k6-experimental/fs/" rel="noopener noreferrer"&gt;fs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;O K6 é conhecido por sua alta performance e baixo consumo de recursos. No entanto, a performance pode ser comprometida à medida que se adotam soluções inadequadas ou mal modeladas nos scripts de teste.&lt;/p&gt;

&lt;p&gt;Como podemos observar, a utilização do SharedArray não terá um impacto significativo em testes com baixa volumetria e poucos dados manipulados. Contudo, em cenários de alta volumetria e grande volume de dados, sua utilização se torna essencial para garantir a eficiência e o desempenho do teste.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Confira meu curso na Udemy!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>testing</category>
      <category>performance</category>
      <category>go</category>
    </item>
    <item>
      <title>Visualização de métricas k6 em tempo real com Prometheus remote write</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Tue, 23 Jul 2024 00:22:49 +0000</pubDate>
      <link>https://forem.com/marlo2222/visualizacao-de-metricas-k6-em-tempo-real-com-prometheus-remote-write-3hj4</link>
      <guid>https://forem.com/marlo2222/visualizacao-de-metricas-k6-em-tempo-real-com-prometheus-remote-write-3hj4</guid>
      <description>&lt;p&gt;O ciclo de vida de um teste de performance envolve diversas fases cruciais para garantir o sucesso em cenários de testes de alta complexidade. Essas fases são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Levantamento e Análise de Requisitos&lt;/li&gt;
&lt;li&gt;Planejamento do Teste&lt;/li&gt;
&lt;li&gt;Projeto do Teste&lt;/li&gt;
&lt;li&gt;Configuração do Ambiente de Teste&lt;/li&gt;
&lt;li&gt;Execução do Teste&lt;/li&gt;
&lt;li&gt;Monitoramento e Análise&lt;/li&gt;
&lt;li&gt;Geração de Relatório&lt;/li&gt;
&lt;li&gt;Resolução de Problemas&lt;/li&gt;
&lt;li&gt;Reteste&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em testes mais simples, algumas fases tendem a ser ignoradas ou adiadas para outro momento. No entanto, em testes mais complexos, especialmente aqueles de larga escala e maior duração, ignorar algumas das fases mencionadas anteriormente pode levar o ciclo de testes de performance a resultados inesperados.&lt;/p&gt;

&lt;p&gt;O tempo dos testes de performance deve sempre ser considerado. Por exemplo, em uma execução simples com o k6, o resultado é fornecido ao usuário apenas ao término do teste ou caso algum limite configurado seja ultrapassado, resultando na interrupção do teste. É nesse contexto que entram as ferramentas de monitoramento em tempo real.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar o Prometheus e como utilizá-lo para a visualização de métricas em tempo real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prometheus📚
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/prometheus/prometheus" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt; é uma ferramenta de monitoramento e alerta de sistemas de código aberto, originalmente desenvolvida na SoundCloud em 2012. Desde então, muitas empresas e organizações adotaram o Prometheus, que conta com uma comunidade ativa de desenvolvedores e usuários. &lt;/p&gt;

&lt;p&gt;Em 2016, o Prometheus tornou-se um projeto independente e foi incorporado à &lt;a href="https://www.cncf.io/" rel="noopener noreferrer"&gt;Cloud Native Computing Foundation&lt;/a&gt;, destacando-se como o segundo projeto hospedado, após o Kubernetes.&lt;/p&gt;

&lt;p&gt;O Prometheus coleta e armazena métricas como séries temporais, ou seja, os dados são registrados com um carimbo de tempo e pares de chave-valor opcionais chamados rótulos. Suas principais características incluem um modelo de dados multidimensional, a linguagem de consulta PromQL, independência de armazenamento distribuído, coleta de séries temporais via modelo pull sobre HTTP, suporte ao push de dados via gateway intermediário, descoberta de alvos via service discovery ou configuração estática, e suporte a vários modos de visualização e dashboarding.&lt;/p&gt;

&lt;p&gt;A maioria dos componentes do Prometheus é escrita em Go, o que facilita sua construção e implantação como binários estáticos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prometheus com k6👀
&lt;/h2&gt;

&lt;p&gt;Ao acessar o catalogo de extenções do k6, podemos observa alguma soluções referentes ao uso do Prometheus. Uma das mais interresantes, é o modulo Prometheus remote write, que a parti da versão  v0.42.0 foi introduzido como um modulo experimental ao core do k6.&lt;/p&gt;

&lt;p&gt;O Prometheus remote write é um protocolo que permite a transmissão confiável de dados em tempo real entre um remetente e um receptor, com várias implementações e integrações de armazenamento compatíveis. Por exemplo, ao executar seu teste de performance, e utilizar a saída experimental-prometheus-rw, o k6 pode enviar métricas de resultados de testes diretamente para o endpoint remoto e armazená-las no Prometheus.&lt;/p&gt;

&lt;p&gt;Durante a execução do k6, todos os pontos de dados de séries temporais gerados são capturados e convertidos em séries temporais no formato Prometheus, sendo então enviados ao endpoint de escrita remota. As métricas do k6 são mapeadas para tipos de métricas equivalentes no Prometheus, seguindo as melhores práticas de nomenclatura.&lt;/p&gt;

&lt;p&gt;Existem inumeras abordagens de utilização do prometheus. Nesse artigo utilizaremos um serviço auto gerenciado da Grafana cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;K6 instalado&lt;/li&gt;
&lt;li&gt;Conta free Grafana Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configurando Grafana cloud Prometheus🛠️
&lt;/h2&gt;

&lt;p&gt;Uma vez autenticado na &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;Grafana Cloud&lt;/a&gt;, acesse send metrics para o serviço prometheus:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe3z3oyni7s111y1cw5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foe3z3oyni7s111y1cw5t.png" alt="Image description" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copie as informações de remote write endpoint bem como o username/instance ID para sua conta:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ljxvsgry1cer4sbza3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ljxvsgry1cer4sbza3c.png" alt="Image description" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida você precisa gerar o API token para escrita remota com prometheus. Em password/API token, selecione a opção &lt;em&gt;Generate now&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo31k6g1qjzpjfb5spl2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo31k6g1qjzpjfb5spl2q.png" alt="Image description" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wqlzp7sol7n4ziwfbin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wqlzp7sol7n4ziwfbin.png" alt="Image description" width="800" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Atribua um nome ao seu token e selecione o botão &lt;em&gt;create token&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3755iqv1udvweobywf0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3755iqv1udvweobywf0u.png" alt="Image description" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Armazene o seu token gerado, vamos precisar dele posteriomente!&lt;/p&gt;
&lt;h2&gt;
  
  
  Script utilizado👩‍💻
&lt;/h2&gt;

&lt;p&gt;O script de teste de performance que será utilizado é o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import {sleep, check} from 'k6';

export const options = {
    stages: [
        { duration: '10s', target: 10 }, 
        { duration: '10s', target: 10 },
        { duration: '10s', target: 0 } 
    ],
    thresholds: {
        checks: ['rate &amp;gt; 0.95'],
        http_req_duration: ['p(95) &amp;lt; 500']
    }
}

export default function(){

    const BASE_URL = 'https://test-api.k6.io/public/crocodiles';
    const res = http.get(BASE_URL)

    check(res,{
        'status 200': (r) =&amp;gt; r.status === 200
    });
    sleep(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nenhuma modificação será necessaria nas fases de inicialização, configuração, execução ou desmontagem do script. A utilização do prometheus remote write necessita apenas de flags no comando da sua CLI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Executando nosso script📈
&lt;/h2&gt;

&lt;p&gt;O processo de execução do nosso script não necessita de autenticação no grafana cloud k6 via CLI. &lt;/p&gt;

&lt;p&gt;Basicamente precisamos fornece três informações que obtivemos anteriomente: &lt;code&gt;K6_PROMETHEUS_RW_USERNAME&lt;/code&gt; sendo o valor que obtivemos do campo username/instance_ID, &lt;code&gt;K6_PROMETHEUS_RW_PASSWORD&lt;/code&gt; sendo o token que geramos e o&lt;code&gt;K6_PROMETHEUS_RW_SERVER_URL&lt;/code&gt; que é nossa URL de escrita remota. &lt;/p&gt;

&lt;p&gt;Na CLI precisaremos tambem utilizar a flag &lt;code&gt;-o&lt;/code&gt; para especificar um output para nosso teste, sendo nesse exemplo o &lt;code&gt;experimental-prometheus-rw&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nosso comando apos forncer todas essa informações será o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;K6_PROMETHEUS_RW_USERNAME=USERNAME \
K6_PROMETHEUS_RW_PASSWORD=API_KEY \
K6_PROMETHEUS_RW_SERVER_URL=REMOTE_WRITE_ENDPOINT \
k6 run -o experimental-prometheus-rw script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na CLI podemos observar que o resultando de saida já aponta para nosso endpoint de escrita remota:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32zjc6o4vjemnwwr9ffg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32zjc6o4vjemnwwr9ffg.png" alt="Image description" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se acessarmos o explorer da nossa conta grafana cloud, podemos observar que todas as metricas k6 foram enviadas e armazenadas no prometheus:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zct4v1qdqs6tuimlqd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zct4v1qdqs6tuimlqd8.png" alt="Image description" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;O uso de bancos de séries temporais, como o Prometheus, facilita a integração com ferramentas de visualização, especialmente o Grafana. &lt;/p&gt;

&lt;p&gt;O Grafana Cloud permite, com poucos cliques, criar dashboards que obtêm dados de fontes como o Prometheus, oferecendo novas possibilidades para visualizar métricas de forma eficiente.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Confira meu curso na Udemy!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>prometheus</category>
      <category>k6</category>
      <category>performance</category>
    </item>
    <item>
      <title>Criando um modulo xk6 para k6</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Thu, 13 Jun 2024 11:25:15 +0000</pubDate>
      <link>https://forem.com/marlo2222/criando-um-modulo-xk6-para-k6-3c64</link>
      <guid>https://forem.com/marlo2222/criando-um-modulo-xk6-para-k6-3c64</guid>
      <description>&lt;p&gt;Uma das grandes vantagens do K6 é sua capacidade de permitir a criação de módulos personalizados, os quais podem ser facilmente adicionados aos scripts de teste de performance, e até mesmo, se torna uma solução oficial para o K6. &lt;/p&gt;

&lt;p&gt;Esse caminho de criação de módulos, abre novas possibilidades para a rápida disponibilização de soluções baseadas em pacotes Go. &lt;/p&gt;

&lt;p&gt;Neste artigo, veremos como utilizar o XK6 para desenvolver um novo módulo, baseado em uma solução em Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/k6/latest/" rel="noopener noreferrer"&gt;K6 instalado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Go instalado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana/xk6" rel="noopener noreferrer"&gt;XK6 instalado&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O problema👥
&lt;/h2&gt;

&lt;p&gt;Para quem conduz testes no contexto brasileiro, é notavel que informações como CPF e CNPJ desempenham um papel crucial nos cenários de negócios de muitas aplicações.&lt;/p&gt;

&lt;p&gt;Atualmente, o K6 não oferece um módulo que permita a geração de &lt;a href="https://pt.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas" rel="noopener noreferrer"&gt;CPF&lt;/a&gt; para uso em scripts de teste de performance, o que restringe as opções de implementação de alguns scripts que necessitem de grandes volumes dessa massa. &lt;/p&gt;

&lt;p&gt;A ausência desse recurso deixa os usuários sem alternativas além de recorrer a módulos Javascript, que podem apresentar desempenho inferior quando incorporados a scripts no K6.&lt;/p&gt;

&lt;p&gt;Ao analisar as soluções disponíveis em Go, percebemos que a comunidade brasileira disponibiliza diversos pacotes para a geração e validação de CPF e CNPJ. Um exemplo notável é a biblioteca &lt;a href="https://github.com/mvrilo/go-cpf" rel="noopener noreferrer"&gt;go-cpf&lt;/a&gt;, que oferece a possibilidade de geração de CPF com e sem mascara de formatação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um modulo XK6📚
&lt;/h2&gt;

&lt;p&gt;Em um diretorio de sua preferencia, utilize o comando &lt;code&gt;go mod init xk6-cpf&lt;/code&gt; para iniciar um novo modulo Go. Caso o modulo seja iniciado com sucesso, na raiz do seu diretorio, será criado um arquivo &lt;code&gt;go.mod&lt;/code&gt; que registra as dependências do seu projeto, incluindo os módulos que você importa e suas versões.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Neste exemplo, nosso modulo foi iniciado em um diretorio de nome xk6-cpf.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No mesmo diretorio onde nosso modulo foi iniciado, vamos criar um arquivo de nome &lt;code&gt;cpf.go&lt;/code&gt;, utilizaremos esse arquivo para realizar toda a configuração do nosso modulo. &lt;/p&gt;

&lt;p&gt;Inicialmente vamos definir o nome do nosso pacote Go, para que ele possa ser utilizado por outros arquivos Go, bem como para ser usado em scripts Javascript com o k6.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package cpf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, vamos importar os pacotes necessários para o nosso módulo. O pacote &lt;code&gt;go-cpf&lt;/code&gt; fornece funcionalidades para a criação de CPFs com e sem máscara. Já o pacote &lt;code&gt;k6/js/modules&lt;/code&gt; é utilizado para registrar módulos personalizados, permitindo seu uso em scripts Javascript com o k6.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "github.com/mvrilo/go-cpf"
        "go.k6.io/k6/js/modules"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um dos pontos importantes quando falamos em utilizar modulos XK6, é o registro do nosso modulo. Vamos utilizar a função especial &lt;code&gt;init()&lt;/code&gt; do Go, para registramos o modulo &lt;code&gt;xk6-cpf&lt;/code&gt; como &lt;code&gt;k6/x/cpf&lt;/code&gt;, utilizando a função &lt;code&gt;Register&lt;/code&gt; do pacote &lt;code&gt;k6/js/modules&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func init() {
    modules.Register("k6/x/cpf", new(CPF))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Essa nomenclatura é utilizada para que o módulo possa ser importado no script de teste de performance, com uma sintaxe semelhante à seguinte: import cpf from 'k6/x/cpf'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos definir uma estrutura do tipo CPF, que conterá as funções disponíveis para uso no Javascript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type CPF struct{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Precisamos criar uma função do tipo &lt;code&gt;CPF&lt;/code&gt; que receba um argumento booleano. Esse argumento será usado para definir se o usuário deseja um CPF formatado ou não. A função de geração do nosso módulo será a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (*CPF) Cpf(formatado bool) string {
    if formatado {
        return cpf.GeneratePretty()
    }   
    return cpf.Generate()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao final, nosso arquivo cpf.go terá a seguinte estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package cpf

import (
    "github.com/mvrilo/go-cpf"
        "go.k6.io/k6/js/modules"
)

func init() {
    modules.Register("k6/x/cpf", new(CPF))
}

type CPF struct{}

func (*CPF) Cpf(formatado bool) string {
    if formatado {
        return cpf.GeneratePretty()
    }   
    return cpf.Generate()

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para gerar uma versão do binário do k6 que contenha o módulo que acabamos de construir, podemos utilizar o seguinte comando xk6:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xk6 build --with xk6-cpf=.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilizando o modulo xk6-cpf👩‍💻
&lt;/h2&gt;

&lt;p&gt;Para utilizar o módulo que acabamos de criar, podemos importá-lo em nosso script conforme definido no modules.Register. Na fase de inicialização, importamos nosso módulo xk6 com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import cpf from 'k6/x/cpf';
import { sleep } from 'k6';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na fase de configuração, vamos definir uma carga para observar a geração de CPFs utilizando nosso módulo xk6:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
  vus: 1,
  duration: '3s',

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na fase de execução, podemos utilizar a função Cpf do módulo XK6 para verificar a geração de CPFs válidos para uso em nosso script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function () {
  console.log(`Gerando um novo CPF: ${cpf.cpf(false)}`);
  sleep(0.5);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;O argumento &lt;em&gt;&lt;strong&gt;false&lt;/strong&gt;&lt;/em&gt; informando na função cpf indica que queremos um cpf sem mascara de formatação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para executar nosso script, podemos utilizar o comando &lt;code&gt;.\k6.exe run teste.js&lt;/code&gt;, podemos observar o resultado de saida:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: .\teste.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 33s max duration (incl. graceful stop):
              * default: 1 looping VUs for 3s (gracefulStop: 30s)

INFO[0000] Gerando um novo CPF: 73810645290              
INFO[0000] Gerando um novo CPF: 87306215426              
INFO[0001] Gerando um novo CPF: 48732015607              
INFO[0001] Gerando um novo CPF: 83652407180              
INFO[0002] Gerando um novo CPF: 58263410762              
INFO[0002] Gerando um novo CPF: 81254037608              

     data_received........: 0 B 0 B/s
     data_sent............: 0 B 0 B/s
     iteration_duration...: avg=507.56ms min=500.64ms med=506.57ms max=516.19ms p(90)=514.37ms p(95)=515.28ms
     iterations...........: 6   1.970294/s
     vus..................: 1   min=1      max=1
     vus_max..............: 1   min=1      max=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Utilizando um modulo remoto☁️
&lt;/h2&gt;

&lt;p&gt;No exemplo anterior, o nosso módulo XK6 foi gerado localmente. Uma alternativa de utilização é disponibilizar um módulo remoto para uso.&lt;/p&gt;

&lt;p&gt;Para isso, na sua ferramenta de linha de comando, utilize o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xk6 build --with github.com/marlo2222/xk6-cpf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando o script anteriomente contruido, podemos utilizar o seguinte comando para execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.\k6.exe run teste.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E como resultado de saida teremos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: .\teste.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 33s max duration (incl. graceful stop):
           * default: 1 looping VUs for 3s (gracefulStop: 30s)

INFO[0000] Gerando um novo CPF: 78153206435              source=console
INFO[0000] Gerando um novo CPF: 57281364008              source=console
INFO[0001] Gerando um novo CPF: 24567310853              source=console
INFO[0001] Gerando um novo CPF: 20584713690              source=console
INFO[0002] Gerando um novo CPF: 51068423790              source=console
INFO[0002] Gerando um novo CPF: 62453071807              source=console

     data_received........: 0 B 0 B/s
     data_sent............: 0 B 0 B/s
     iteration_duration...: avg=506.57ms min=501.61ms med=507.81ms max=508.64ms p(90)=508.61ms p(95)=508.62ms
     iterations...........: 6   1.973951/s
     vus..................: 1   min=1      max=1
     vus_max..............: 1   min=1      max=1


running (03.0s), 0/1 VUs, 6 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  3s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;Como podemos observar, o XK6 abre inúmeras possibilidades para criarmos nossos próprios módulos, preenchendo lacunas existentes na ferramenta atualmente.&lt;/p&gt;

&lt;p&gt;Módulos populares no K6 surgiram como iniciativas da comunidade, e a equipe do K6 está sempre receptiva a novas sugestões de módulos para integrar à ferramenta.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>go</category>
      <category>testing</category>
      <category>performance</category>
    </item>
    <item>
      <title>Enviando notificações com xk6 notification ✉</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Wed, 17 Apr 2024 00:18:50 +0000</pubDate>
      <link>https://forem.com/marlo2222/enviando-notificacoes-com-xk6-notification-25ml</link>
      <guid>https://forem.com/marlo2222/enviando-notificacoes-com-xk6-notification-25ml</guid>
      <description>&lt;p&gt;Em ambientes de integração contínua, a comunicação e notificação efetiva dos resultados dos testes de software é de suma importância.&lt;/p&gt;

&lt;p&gt;As notificações podem ser tanto o envio de um e-mail para canal quando uma mensagem de comunicação em um chat, ou mesmo, eventos de callback realizados via webhook.&lt;/p&gt;

&lt;p&gt;Nesse artigo veremos como podemos utilizar o modulo xk6-notification para o disparo de notificações do resultado dos testes de performance com k6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;K6 instalado&lt;/li&gt;
&lt;li&gt;xk6 configurado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conhecendo o xk6-notification📚
&lt;/h2&gt;

&lt;p&gt;O modulo &lt;a href="https://github.com/grafana/xk6-notification" rel="noopener noreferrer"&gt;xk6-notification&lt;/a&gt; oferece uma solução versátil para o envio de notificações via webhook, permitindo integração com uma variedade de serviços de notificação de sua escolha.&lt;/p&gt;

&lt;p&gt;O modulo foi construido utilizando a biblioteca &lt;a href="https://containrrr.dev/shoutrrr/v0.8/" rel="noopener noreferrer"&gt;shoutrrr&lt;/a&gt;, uma lib GoLang utilizada para envio de notificações.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s8fbxuwungquym3flfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s8fbxuwungquym3flfh.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando o xk6-notification👩‍💻
&lt;/h2&gt;

&lt;p&gt;Antes de iniciar a instalação do modulo xk6-notification, é importante destacar que a configuração do xk6 deve ter sido realizada. &lt;a href="https://dev.to/marlo2222/utilizando-modulos-do-xk6-com-k6-4nk1"&gt;No artigo utilizando modulo do xk6 com k6&lt;/a&gt; abordamos com mais detalhes essa configuração.&lt;/p&gt;

&lt;p&gt;Com o xk6 configurado, realize o build do binário do xk6-notification utilizando o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xk6 build --with github.com/dgzlopes/xk6-notification@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configurando nosso script🪛
&lt;/h2&gt;

&lt;p&gt;O script abaixo executa um teste de carga na API de listagem de crocodilos do K6 por 10 segundos, empregando 5(VUs) nesse periodo. É definido um limite para o número de requisições com falha, esperando um resultado inferior a 5% do total de requisições realizadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check } from 'k6';

export const options = {
    vus: 5,
    duration: '10s',
    thresholds: {
        http_req_failed: ['rate &amp;lt; 0.05'],
    }
}

export default function(){
    const BASE_URL = 'https://test-api.k6.io/public/crocodiles/';

    const res = http.get(BASE_URL);

    check(res, {
        'status code 200': (r) =&amp;gt; r.status === 200
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro ajuste necessário em nosso script é na fase de inicialização, onde devemos adicionar o módulo xk6-notification. Adicionar a seguinte linha ao seu script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import notification from 'k6/x/notification';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a importação do modulo, vamos incluir uma função &lt;code&gt;handleSummary&lt;/code&gt; na fase de desmontagem. Nessa etapa realizaremos o envio de notificação com os resultados do teste assim que ele for concluído:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function teardown(data) {
  notification.send('url', 'message');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Observe que estamos utilizando o módulo &lt;code&gt;notification&lt;/code&gt;, mais precisamente a função &lt;code&gt;send&lt;/code&gt;, para o envio de mensagens. Dois argumentos são necessarios: url de destino e messagem a ser enviada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No campo da URL, é necessário fornecer o endereço do webhook do serviço selecionado. Neste exemplo, utilizaremos um webhook para enviar mensagens para um canal no Telegram. A estrutura do webhook será a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const url = `telegram://${__ENV.TOKEN}@telegram?channels=${__ENV.CANAL}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A URL do webhook precisa receber dois argumentos definidos como variaveis de ambiente. O primeiros deles é o TOKEN do seu bot criado no telegram,  o segundo, o CANAL onde a mensagem deve ser enviada.&lt;/p&gt;

&lt;p&gt;Caso opte por utilizar outro serviços de notificação, segue a documentação para o envio de mensagems utilizando webhook das plataformas &lt;a href="https://api.slack.com/messaging/webhooks" rel="noopener noreferrer"&gt;slack&lt;/a&gt; e &lt;a href="https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=newteams%2Cdotnet" rel="noopener noreferrer"&gt;teams&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para o conteúdo da nossa mensagem, podemos incluir todas as métricas obtidas durante o teste, as quais estão disponíveis no argumento data da função handleSummary. &lt;/p&gt;

&lt;p&gt;Portanto, vamos estabelecer uma função auxiliar para formatar a mensagem destinada a nossa notificação. A função terá o seguinte escopo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function format_message(data) {
    let checks = data.metrics.checks.values.fails == 0 ? '✅' : '❌';
    let thresholds = data.metrics.http_req_failed.thresholds['rate &amp;lt; 0.05'].ok ? '✅' : '❌';

    return `Resultado de execução do teste: 
    - Quantidade de VUs: ${data.metrics.vus.values['value']}
    - Duração total(ms): ${data.state.testRunDurationMs}
    - Iteraçoes(RPS): ${data.metrics.iterations.values['count']}

Req Durations(ms):
    - min: ${data.metrics.http_req_duration.values.min},
    - med: ${data.metrics.http_req_duration.values.med},
    - max: ${data.metrics.http_req_duration.values.max},
    - p(90): ${data.metrics.http_req_duration.values['p(90)']},
    - p(95): ${data.metrics.http_req_duration.values['p(95)']}

Checks:
    - status code 200: ${checks}

Thresholds: 
    - http_req_failed &amp;lt; 5%: ${thresholds}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Essa função tem como objetivo principal montar uma mensagem com algumas informações relevantes sobre o teste, além de realizar verificações nos resultados dos thresholds e checks que foram definidos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Assim, podemos fazer as modificações necessárias na nossa função de notificação, ajustando-a para utilizar a URL que definimos para nosso webhook e a mensagem correspondente. Após todos os ajustes, o script final ficará da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check } from 'k6';
import notification from 'k6/x/notification';

const url = `telegram://${__ENV.TOKEN}@telegram?channels=${__ENV.CANAL}`;

export const options = {
    vus: 15,
    duration: '10s',
    thresholds: {
        http_req_failed: ['rate &amp;lt; 0.05'],
    }
}

export default function () {
    const BASE_URL = 'https://test-api.k6.io/public/crocodiles/';

    const res = http.get(BASE_URL);

    check(res, {
        'status code 200': (r) =&amp;gt; r.status === 200
    });
}

export function handleSummary(data) {
    notification.send(url, format_message(data));
}

export function format_message(data) {
    let checks = data.metrics.checks.values.fails &amp;gt; 0 ? '✅' : '❌';
    let thresholds = data.metrics.http_req_failed.thresholds['rate &amp;lt; 0.05'].ok ? '✅' : '❌';

    return `Resultado de execução do teste: 
    - Quantidade de VUs: ${data.metrics.vus.values['value']}
    - Duração total(ms): ${data.state.testRunDurationMs}
    - Iteraçoes(RPS): ${data.metrics.iterations.values['count']}

Req Durations(ms):
    - min: ${data.metrics.http_req_duration.values.min},
    - med: ${data.metrics.http_req_duration.values.med},
    - max: ${data.metrics.http_req_duration.values.max},
    - p(90): ${data.metrics.http_req_duration.values['p(90)']},
    - p(95): ${data.metrics.http_req_duration.values['p(95)']}

Checks:
    - status code 200: ${checks}

Thresholds: 
    - http_req_failed &amp;lt; 5%: ${thresholds}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Executando nosso teste🚀
&lt;/h2&gt;

&lt;p&gt;Antes de iniciarmos nossos testes, é crucial destacar um ponto que frequentemente gera dúvidas entre os usuários dos módulos do xk6.&lt;/p&gt;

&lt;p&gt;Quando utilizamos o xk6 para instalar um módulo desenvolvido pela comunidade, o que obtemos é uma versão personalizada (binário) do K6 que está presente em sua máquina, além do próprio módulo que foi construído.&lt;/p&gt;

&lt;p&gt;Se executarmos o comando &lt;code&gt;dir&lt;/code&gt;, podemos observar que uma versão personalizada do K6 está disponível. Portanto, é essencial realizar a execução dos testes utilizando esta versão personalizada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        14/04/2024     16:59       37777920 k6.exe
-a----        15/04/2024     20:58           1581 script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Comando realizado utilizando o prompt do windows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esclarecido esse ponto, podemos realizar a execução do nosso script utilizando o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.\k6.exe run -e TOKEN=seu_token -e CANAL=seu_canal script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como resultado de saida teremos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: script.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 31s max duration (incl. graceful stop):
           * default: 1 looping VUs for 1s (gracefulStop: 30s)


running (01.6s), 0/1 VUs, 2 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  1s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mensagem que sera enviada ao canal especificado terá a seguinte estrutura: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5umjnea5sbqupnkul7m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5umjnea5sbqupnkul7m0.png" alt="Image description" width="382" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;Como podemos observar, a utilização do módulo xk6 notification simplifica o processo de envio de notificações sobre os resultados dos seus testes.&lt;/p&gt;

&lt;p&gt;No exemplo deste artigo, exploramos uma mensagem contendo apenas algumas informações do resultado do teste, acessíveis através do objeto &lt;code&gt;data&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Inúmeras melhorias podem ser implementadas, como a parametrização de environments em sua ferramenta de integração contínua, ou até mesmo a utilização de outros serviços, como o Slack, que oferece recursos avançados de customização de mensagens e envio via webhook.&lt;/p&gt;

&lt;p&gt;Agradecimentos ao &lt;a href="https://github.com/dgzlopes" rel="noopener noreferrer"&gt;Daniel González Lopes&lt;br&gt;
&lt;/a&gt;, pelo modulo, ajudem a manter esse projeto com uma ⭐.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA" rel="noopener noreferrer"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>testing</category>
      <category>performance</category>
      <category>go</category>
    </item>
    <item>
      <title>Gerando dados com K6 utilizando xk6-faker</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Thu, 14 Mar 2024 23:36:53 +0000</pubDate>
      <link>https://forem.com/marlo2222/gerando-dados-com-k6-utilizando-xk6-faker-47ck</link>
      <guid>https://forem.com/marlo2222/gerando-dados-com-k6-utilizando-xk6-faker-47ck</guid>
      <description>&lt;p&gt;O processo de teste de software pode ser dividido em várias etapas. Durante a fase de implementação dos testes, é comum utilizar artifícios para gerar dados destinados às massas de testes. Esses dados incluem informações como nomes aleatórios, números de telefone fictícios e outros elementos necessários para simular cenários de teste.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos como podemos aproveitar a extensão xk6-faker para gerar dados de teste em scripts de teste de desempenho com K6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faker👥
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/faker-js/faker"&gt;Faker.js &lt;/a&gt;é uma biblioteca Javascript que oferece funções para gerar dados aleatórios sob demanda. Esses dados podem incluir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Localizações: endereços, CEPs, nomes de ruas, estados e países.&lt;/li&gt;
&lt;li&gt;Dados Baseados em Tempo: Passado, presente, futuro.&lt;/li&gt;
&lt;li&gt;Finanças: detalhes de contas, transações e endereços de criptomoedas fictícios.&lt;/li&gt;
&lt;li&gt;Produtos: preços, nomes de produtos, adjetivos e descrições.&lt;/li&gt;
&lt;li&gt;Nomes: identidades virtuais completas, online e offline.&lt;/li&gt;
&lt;li&gt;Números: números e sequências aleatórias.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Mais detalhes sobre os diferentes tipos de dados que podem ser gerados estão disponiveis na documentação da ferramenta: &lt;a href="https://github.com/faker-js/faker"&gt;Documentação&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ESM
import { faker } from '@faker-js/faker';

// CJS
const { faker } = require('@faker-js/faker');

export function createRandomUser(): User {
  return {
    userId: faker.string.uuid(),
    username: faker.internet.userName(),
    email: faker.internet.email(),
    avatar: faker.image.avatar(),
    password: faker.internet.password(),
    birthdate: faker.date.birthdate(),
    registeredAt: faker.date.past(),
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Exemplo de um codigo para geração de um usuario com dados aleatorios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Por que utilizar xk6-faker👀
&lt;/h2&gt;

&lt;p&gt;Embora o Faker e outras bibliotecas Javascript possam ser utilizadas em scripts de teste de desempenho com k6 como um módulo remoto, optar por uma abordagem que envolva um módulo Javascript apresenta várias desvantagens, incluindo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tamanho do download&lt;/li&gt;
&lt;li&gt;Uso de memória&lt;/li&gt;
&lt;li&gt;Tempo de inicialização&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por outro lado, o xk6-faker oferece um desempenho superior, pois é uma implementação nativa em Go. No entanto, em troca dessa vantagem, o xk6-faker pode oferecer um conjunto menor de recursos em comparação com os populares geradores de dados falsos em Javascript.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A lista completa de funções disponiveis &lt;code&gt;gofakeit&lt;/code&gt; que é a base do modulo xk6-faker pode ser encontrada no seguinte link: &lt;a href="https://github.com/brianvoe/gofakeit?tab=readme-ov-file#functions"&gt;full list functions&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pré-requisitos📑
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://k6.io/docs/get-started/installation/"&gt;K6 instalado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/"&gt;Go instalado&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Instalando o XK6🔨
&lt;/h3&gt;

&lt;p&gt;Primeiramente, vamos nos certificar que o Go está instalado corretamente. Em qualquer ferramenta de linha de comando de sua preferencia utilize o comando &lt;code&gt;go version&lt;/code&gt; para verificar a versão do Go instalada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go version go1.19.5 windows/amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Esse tutorial será feito em maquina com sistema windows, utilizando o git bash.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para adicionar o xk6 binário ao seu Go path, utilize o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go install go.k6.io/xk6/cmd/xk6@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Caso você esteja enfrentando problemas relacionados à desativação de módulos pelo &lt;code&gt;GO111MODULE&lt;/code&gt;, você pode resolver executando o seguinte comando: &lt;code&gt;go env -w GO111MODULE=on&lt;/code&gt;. Isso irá ativar os módulos Go e permitir o correto funcionamento do gerenciamento de dependências.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O comando acima instalará o binário xk6 em &lt;code&gt;$GOPATH/bin&lt;/code&gt;. É importante garantir que o GOPATH esteja configurado corretamente. Caso deseje configurar o GOPATH, você pode utilizar o seguinte comando ao iniciar o seu shell: &lt;code&gt;export PATH=$(go env GOPATH)/bin:$PATH&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Para obter mais informações sobre o GOPATH, consulte o seguinte material: &lt;a href="https://go.dev/doc/gopath_code#GOPATH"&gt;gopath&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Utilizando o xk6-faker😁
&lt;/h3&gt;

&lt;p&gt;Para instalação do plugin &lt;a href="https://github.com/szkiba/xk6-faker"&gt;xk6-faker&lt;/a&gt; podemos utilizar o seguinte comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;xk6 build --with github.com/szkiba/xk6-faker@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Agora que o modulo está instalado, temos uma nova e poderosa opção para geraração de dados aleatorios.&lt;/p&gt;

&lt;p&gt;Vamos utilizar o seguinte script de exemplo para execução e geração de dados ramdomicos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 2,
  duration: '5s',
  thresholds: {
    http_req_failed: ['rate &amp;lt; 0.05'],
  }
}

export default function () {

  let data = {
    nome: 'Crocodilo',
    email: 'crocrodilo@mail.com',
    password: 'dino123',
    administrador: 'true'
  }

  const BASE_URL = 'https://serverest.dev/usuarios';

  const res = http.post(BASE_URL, JSON.stringify(data), {
    headers: { 'Content-Type': 'application/json' },
  });

  check(res, {
    'status code 200': (r) =&amp;gt; r.status === 201,
    'Message sucesso': (r) =&amp;gt; r.json('message') === 'Cadastro realizado com sucesso'
  });

  sleep(1)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro passo é a adição do modulo xk6-faker na fase de inicialização, vamos adicionar a seguinte linha ao script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import faker from "k6/x/faker";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após importarmos o módulo, podemos utilizar as funções no xk6-faker. Nosso exemplo de script contém um objeto &lt;code&gt;data&lt;/code&gt; com algumas informações necessárias para a criação de um novo usuário, no entanto, essas informações são estáticas.&lt;/p&gt;

&lt;p&gt;Ao realizar as modificações necessárias e utilizar o módulo xk6-faker para gerar dados aleatórios, o objeto &lt;code&gt;data&lt;/code&gt; terá a seguinte estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let data = {
    nome: faker.person.firstName(),
    email: faker.person.email(),
    password: faker.internet.password(),
    administrador: 'true'
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao executar nosso script, observamos que, para cada iteração de criação de um novo usuário, os dados são gerados aleatoriamente para as informações do objeto data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: script.js
        output: -

     scenarios: (100.00%) 1 scenario, 2 max VUs, 35s max duration (incl. graceful stop):
              * default: 2 looping VUs for 5s (gracefulStop: 30s)

INFO[0000] {"nome":"Darrick","email":"martinemann@spencer.org","password":"93PsD8CoPjDW","administrador":"true"}  source=console     
INFO[0000] {"nome":"Ari","email":"kristofferlang@christiansen.com","password":"?Qsz9@WM\u0026_#j","administrador":"true"}  source=console
INFO[0001] {"nome":"Anais","email":"sidneyzemlak@rosenbaum.name","password":"3MkcN0NR6w__","administrador":"true"}  source=console   
INFO[0001] {"nome":"Eliseo","email":"ardellaharris@rice.org","password":"DU2U.s8l!Ai5","administrador":"true"}  source=console       
INFO[0003] {"nome":"Andre","email":"cleobartoletti@lind.info","password":"IJI7P*W#73kc","administrador":"true"}  source=console      
INFO[0003] {"nome":"Sophia","email":"edsanford@grady.name","password":"v.npjnR_3GO*","administrador":"true"}  source=console
INFO[0004] {"nome":"Alanis","email":"roycebeer@muller.name","password":"kCx1bWjKl9zB","administrador":"true"}  source=console        
INFO[0004] {"nome":"Maybell","email":"sibylgleichner@maggio.io","password":"-RG0G@lA?o9X","administrador":"true"}  source=console    

     ✓ status code 200
     ✓ Message sucesso

     checks.........................: 100.00% ✓ 16       ✗ 0
     data_received..................: 12 kB   2.2 kB/s
     data_sent......................: 2.7 kB  498 B/s
     http_req_blocked...............: avg=90.95ms  min=0s       med=0s       max=364.06ms p(90)=363.73ms p(95)=363.89ms
     http_req_connecting............: avg=11.72ms  min=0s       med=0s       max=46.89ms  p(90)=46.89ms  p(95)=46.89ms
     http_req_duration..............: avg=262.08ms min=201.18ms med=263.25ms max=329.54ms p(90)=327.53ms p(95)=328.53ms
       { expected_response:true }...: avg=262.08ms min=201.18ms med=263.25ms max=329.54ms p(90)=327.53ms p(95)=328.53ms
   ✓ http_req_failed................: 0.00%   ✓ 0        ✗ 8
     http_req_receiving.............: avg=771.35µs min=0s       med=0s       max=3.83ms   p(90)=2.14ms   p(95)=2.99ms
     http_req_sending...............: avg=275.33µs min=0s       med=282.7µs  max=756.7µs  p(90)=535.7µs  p(95)=646.2µs
     http_req_tls_handshaking.......: avg=71.09ms  min=0s       med=0s       max=284.36ms p(90)=284.36ms p(95)=284.36ms
     http_req_waiting...............: avg=261.03ms min=199.99ms med=263.03ms max=326.22ms p(90)=325.86ms p(95)=326.04ms
     http_reqs......................: 8       1.471271/s
     iteration_duration.............: avg=1.35s    min=1.21s    med=1.32s    max=1.57s    p(90)=1.56s    p(95)=1.57s
     iterations.....................: 8       1.471271/s
     vus............................: 2       min=2      max=2
     vus_max........................: 2       min=2      max=2


running (05.4s), 0/2 VUs, 8 complete and 0 interrupted iterations                                                                    
default ✓ [======================================] 2 VUs  5s        
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;Os módulos xk6 oferecem uma maneira poderosa de criar extensões para o k6, aproveitando as robustas ferramentas já disponíveis em Go, como é o caso do gofakeit.&lt;/p&gt;

&lt;p&gt;O uso de dados randômicos pode ser incrivelmente útil ao modelar testes de desempenho, especialmente quando se trata de testar recursos relacionados à geração de informações em sua aplicação.&lt;/p&gt;

&lt;p&gt;Agradecimentos aos &lt;a href="https://github.com/szkiba"&gt;Iván Szkiba&lt;/a&gt;, pela criação desse modulo, ajudem a manter esse projeto com uma ⭐.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>performance</category>
      <category>k6</category>
      <category>go</category>
    </item>
    <item>
      <title>Gerando dashboard ao resultado de saida com K6🖼</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Tue, 06 Feb 2024 23:19:16 +0000</pubDate>
      <link>https://forem.com/marlo2222/gerando-dashboard-ao-resultado-de-saida-com-k6-bhg</link>
      <guid>https://forem.com/marlo2222/gerando-dashboard-ao-resultado-de-saida-com-k6-bhg</guid>
      <description>&lt;p&gt;Uma das funcionalidades altamente aguardadas pelos usuários de ferramentas de testes é a capacidade de gerar métricas e painéis de visualização de resultados.&lt;/p&gt;

&lt;p&gt;Gráficos que apresentam dados tendem a agregar muito mais valor do que dados brutos vistos por meio de linhas de comando ou arquivos de saída.&lt;/p&gt;

&lt;p&gt;O K6 se destaca como uma ferramenta extremamente poderosa quando se trata de visualização de métricas em gráficos e painéis do ecossistema do Grafana. No entanto, a geração de dashboards ou relatórios HTML anteriormente dependia de plugins externos, como o &lt;a href="https://github.com/benc-uk/k6-reporter"&gt;K6 reporter&lt;/a&gt; e o &lt;a href="https://github.com/grafana/xk6-dashboard"&gt;xk6-dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos como gerar relatórios nativamente, eliminando a necessidade de plugins externos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard web🖥️
&lt;/h2&gt;

&lt;p&gt;Na versão v.0.49.0 do K6, foi introduzido um novo recurso de visualização em tempo real das métricas do K6. Esse painel está disponível ao usar uma flag específica via CLI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lbqgx6urqtl0qdqokg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lbqgx6urqtl0qdqokg6.png" alt="Image description" width="800" height="755"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerando dashboard🖨️
&lt;/h2&gt;

&lt;p&gt;Para geração do dashboard, basta utilizar a flag &lt;code&gt;K6_WEB_DASHBOARD&lt;/code&gt;, vamos realizar uma execução de exemplo para o seguinte script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
    vus: 5,
    duration: '30s',
}

export default function(){
    const BASE_URL = 'https://test-api.k6.io/public/crocodiles/';

    const res = http.get(BASE_URL);

    sleep(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao executar o comando &lt;code&gt;K6_WEB_DASHBOARD=true k6 run teste.js&lt;/code&gt;, você pode acessar o endpoint &lt;a href="http://localhost:5665"&gt;http://localhost:5665&lt;/a&gt; para visualizar as métricas em tempo real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eap29jz0ynmrwxvfhgs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eap29jz0ynmrwxvfhgs.gif" alt="Image description" width="1333" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O painel atualiza a cada 10 segundos, portanto, em testes muito curtos, as métricas provavelmente não serão carregadas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Exportando o resultado em relatorio📃
&lt;/h1&gt;

&lt;p&gt;Para exportar o dashboard para um relatório HTML, você pode adicionar a propriedade &lt;code&gt;K6_WEB_DASHBOARD_EXPORT&lt;/code&gt;. Ao modificar nosso comando de execução, teremos algo como: &lt;code&gt;K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=report.html k6 run teste.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasl5hrci3fbtkm26w75m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasl5hrci3fbtkm26w75m.gif" alt="Image description" width="1333" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Observe que é necessario informar o nome do arquivo de saida e o formato html.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusão❤️
&lt;/h2&gt;

&lt;p&gt;Com a nova funcionalidade de dashboard em tempo real, agora podemos demonstrar métricas de forma visual, agregando valor aos resultados e informações obtidas.&lt;/p&gt;

&lt;p&gt;A capacidade de exportação para arquivo HTML abre caminho para a geração de relatórios sem a necessidade de módulos externos ou configuração adicional a fase de desmontagem.&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>grafana</category>
      <category>testing</category>
      <category>performance</category>
      <category>k6</category>
    </item>
    <item>
      <title>Adicionando percentil ao resultado de saída do K6📊</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Mon, 22 Jan 2024 23:48:52 +0000</pubDate>
      <link>https://forem.com/marlo2222/adicionando-percentil-ao-resultado-de-saida-do-k6-4c36</link>
      <guid>https://forem.com/marlo2222/adicionando-percentil-ao-resultado-de-saida-do-k6-4c36</guid>
      <description>&lt;p&gt;Quando decidimos realizar testes de performance para avaliar o desempenho de nossa aplicação, um dos pontos a ser definidos quando estamos a fase de definição de métricas e criação de limites são os percentis a serem avaliados.&lt;/p&gt;

&lt;p&gt;Um percentil é uma medida estatística que indica a posição relativa de um valor, dentro de um conjunto de dados ordenados.&lt;/p&gt;

&lt;p&gt;Por exemplo, se o tempo de resposta de uma API para o percentil de 80% é de 50 segundos, significa que 80% das requisições tiveram um tempo igual ou menor a 50 segundos.&lt;/p&gt;

&lt;p&gt;Nesse artigo, aprenderemos como podemos adicionar mais percentis ao resultado de saída do K6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resultados de saida do K6🖨️
&lt;/h2&gt;

&lt;p&gt;Ao analisarmos os percentis apresentados pelo K6 na saída do console, notamos que a ferramenta exibe resultados apenas para os percentis de 90% e 95%.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data_received..................: 8.0 kB 2.1 kB/s
     data_sent......................: 708 B  187 B/s
     http_req_blocked...............: avg=123.42ms min=0s      med=0s       max=370.26ms p(90)=296.21ms p(95)=333.23ms
     http_req_connecting............: avg=32.73ms  min=0s      med=0s       max=98.21ms  p(90)=78.57ms  p(95)=88.39ms
     http_req_duration..............: avg=132.55ms min=106.9ms med=116.76ms max=173.97ms p(90)=162.53ms p(95)=168.25ms
       { expected_response:true }...: avg=132.55ms min=106.9ms med=116.76ms max=173.97ms p(90)=162.53ms p(95)=168.25ms
     http_req_failed................: 0.00%  ✓ 0        ✗ 3
     http_req_receiving.............: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s
     http_req_sending...............: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s
     http_req_tls_handshaking.......: avg=49.21ms  min=0s      med=0s       max=147.64ms p(90)=118.11ms p(95)=132.87ms
     http_req_waiting...............: avg=132.55ms min=106.9ms med=116.76ms max=173.97ms p(90)=162.53ms p(95)=168.25ms
     http_reqs......................: 3      0.790669/s
     iteration_duration.............: avg=1.26s    min=1.11s   med=1.17s    max=1.49s    p(90)=1.43s    p(95)=1.46s
     iterations.....................: 3      0.790669/s
     vus............................: 1      min=1      max=1
     vus_max........................: 1      min=1      max=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em algumas métricas, a avaliação de percentis mais elevados ou mais baixos pode ser necessária, como exemplificado no artigo &lt;a href="https://dev.to/marlo2222/entendendo-as-metricas-do-k6-parte-3-m1g"&gt;Entendendo as métricas do K6 - Parte 3&lt;/a&gt;. No contexto das métricas &lt;em&gt;web do Core Web Vitals&lt;/em&gt;, por exemplo, o critério de avaliação adotado foi o percentil de 75%.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adicionando novos percentis🧮
&lt;/h1&gt;

&lt;p&gt;A inclusão de novos percentis é realizada por meio da adição da flag summaryTrendStats, proporcionando a personalização das informações de saída, tanto através da linha de comando (CLI) quanto configurando no escopo de options do nosso script.&lt;/p&gt;

&lt;p&gt;A título de demonstração, utilizaremos o seguinte script::&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
    vus: 1,
    duration: '3s',
}

export default function(){
    const BASE_URL = 'https://test-api.k6.io/public/crocodiles/';

    const res = http.get(BASE_URL);

    sleep(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para incorporar novos percentis aos resultados de saída por meio da CLI, basta adicionar a flag &lt;em&gt;--summary-trend-stats&lt;/em&gt;, seguida das métricas desejadas para exibição no resultado final. No comando a seguir, solicitaremos que o k6 gere métricas para média (med), mínimo (min), máximo (max), além dos percentis de 70%, 80%, 90% e 99.99%.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;k6 run --summary-trend-stats="min,med,max,p(70),p(80),p(90), p(99.99)" teste.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; http_req_blocked...............: min=0s       med=0s       max=298.58ms p(70)=119.43ms p(80)=179.15ms p(90)=238.87ms p(99.99)=298.52ms
     http_req_connecting............: min=0s       med=0s       max=103.81ms p(70)=41.52ms  p(80)=62.28ms  p(90)=83.04ms  p(99.99)=103.79ms
     http_req_duration..............: min=108.17ms med=190.32ms max=234.47ms p(70)=207.98ms p(80)=216.81ms p(90)=225.64ms p(99.99)=234.46ms
       { expected_response:true }...: min=108.17ms med=190.32ms max=234.47ms p(70)=207.98ms p(80)=216.81ms p(90)=225.64ms p(99.99)=234.46ms
     http_req_failed................: 0.00%  ✓ 0        ✗ 3
     http_req_receiving.............: min=0s       med=0s       max=2.07ms   p(70)=830.39µs p(80)=1.24ms   p(90)=1.66ms   p(99.99)=2.07ms
     http_req_sending...............: min=0s       med=0s       max=0s       p(70)=0s       p(80)=0s       p(90)=0s       p(99.99)=0s
     http_req_tls_handshaking.......: min=0s       med=0s       max=125.19ms p(70)=50.07ms  p(80)=75.11ms  p(90)=100.15ms p(99.99)=125.16ms
     http_req_waiting...............: min=108.17ms med=188.25ms max=234.47ms p(70)=206.73ms p(80)=215.98ms p(90)=225.22ms p(99.99)=234.46ms
     http_reqs......................: 3      0.778617/s
     iteration_duration.............: min=1.2s     med=1.23s    max=1.41s    p(70)=1.3s     p(80)=1.34s    p(90)=1.37s    p(99.99)=1.41s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quanto à inclusão dos mesmos percentis no resultado através da adição de uma configuração ao escopo de options do seu script, é necessario incorporar a propriedade summaryTrendStats. Ao modificar nosso script de exemplo, a fase de configuração ficará da seguinte maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const options = {
    vus: 1,
    duration: '3s',
summaryTrendStats: ["med","min", "max", "p(70)", "p(80)", "p(90)" "p(99.99)"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Durante a execução, ao incorporar a configuração nas opções do seu script, é possível realizar a execução sem a necessidade de flags adicionais na CLI, bastando utilizar o comando &lt;code&gt;k6 run teste.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: percentis.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 33s max duration (incl. graceful stop):
           * default: 1 looping VUs for 3s (gracefulStop: 30s)


     data_received..................: 8.0 kB 2.2 kB/s
     data_sent......................: 708 B  195 B/s
     http_req_blocked...............: min=0s       med=0s       max=262.21ms p(70)=104.88ms p(80)=157.32ms p(90)=209.77ms p(99.99)=262.16ms
     http_req_connecting............: min=0s       med=0s       max=102.59ms p(70)=41.03ms  p(80)=61.55ms  p(90)=82.07ms  p(99.99)=102.57ms
     http_req_duration..............: min=112.49ms med=117.03ms max=120.7ms  p(70)=118.5ms  p(80)=119.23ms p(90)=119.96ms p(99.99)=120.7ms
       { expected_response:true }...: min=112.49ms med=117.03ms max=120.7ms  p(70)=118.5ms  p(80)=119.23ms p(90)=119.96ms p(99.99)=120.7ms
     http_req_failed................: 0.00%  ✓ 0       ✗ 3
     http_req_receiving.............: min=0s       med=245.4µs  max=3.2ms    p(70)=1.42ms   p(80)=2.02ms   p(90)=2.61ms   p(99.99)=3.2ms
     http_req_sending...............: min=0s       med=0s       max=0s       p(70)=0s       p(80)=0s       p(90)=0s       p(99.99)=0s
     http_req_tls_handshaking.......: min=0s       med=0s       max=152.1ms  p(70)=60.84ms  p(80)=91.26ms  p(90)=121.68ms p(99.99)=152.07ms
     http_req_waiting...............: min=112.25ms med=117.03ms max=117.49ms p(70)=117.21ms p(80)=117.31ms p(90)=117.4ms  p(99.99)=117.49ms
     http_reqs......................: 3      0.82531/s
     iteration_duration.............: min=1.11s    med=1.13s    max=1.38s    p(70)=1.23s    p(80)=1.28s    p(90)=1.33s    p(99.99)=1.38s
     iterations.....................: 3      0.82531/s
     vus............................: 1      min=1     max=1
     vus_max........................: 1      min=1     max=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante ressaltar que ao utilizar a flag &lt;em&gt;--summary-trend-stats&lt;/em&gt; ou configurar o &lt;em&gt;summaryTrendStats&lt;/em&gt;, a saída resultante exibirá exclusivamente as estatísticas especificadas por você. Por exemplo, ao executar &lt;code&gt;k6 run --summary-trend stats="min"&lt;/code&gt;, serão apresentadas apenas as estatísticas mínimas para todas as métricas do seu teste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão💖
&lt;/h2&gt;

&lt;p&gt;Conforme visto, os resultados de saída e as estatísticas associadas a cada métrica no K6 podem ser facilmente configurados de acordo com os critérios que o usuário deseja avaliar. Essa flexibilidade permite uma adaptação personalizada, possibilitando uma análise mais precisa e alinhada às necessidades específicas do usuário&lt;/p&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>k6</category>
      <category>testing</category>
      <category>grafana</category>
      <category>performance</category>
    </item>
    <item>
      <title>Entendendo as métricas do K6 - Parte 3</title>
      <dc:creator>Marlo Henrique</dc:creator>
      <pubDate>Sun, 17 Dec 2023 20:23:06 +0000</pubDate>
      <link>https://forem.com/marlo2222/entendendo-as-metricas-do-k6-parte-3-m1g</link>
      <guid>https://forem.com/marlo2222/entendendo-as-metricas-do-k6-parte-3-m1g</guid>
      <description>&lt;p&gt;Durante esta série de publicações em que exploramos as métricas geradas pelo K6, tivemos a oportunidade de aprofundar nosso entendimento sobre métricas em diferentes protocolos, assim como compreender os conceitos fundamentais associados a cada indicador.&lt;/p&gt;

&lt;p&gt;Na &lt;a href="https://dev.to/marlo2222/entendendo-as-metricas-do-k6-parte-1-4kig"&gt;parte 1&lt;/a&gt;, discutimos as métricas padrão geradas pelo K6 e esclarecemos um dos conceitos mais cruciais da ferramenta: as iterações.&lt;/p&gt;

&lt;p&gt;Já na &lt;a href="https://dev.to/marlo2222/entendendo-as-metricas-do-k6-parte-2-3053"&gt;parte 2&lt;/a&gt;, abordamos as métricas dos principais protocolos de rede atualmente suportados pela ferramenta, incluindo HTTP, gRPC e WebSockets.&lt;/p&gt;

&lt;p&gt;Nesse ultimo artigo exploraremos as métricas geradas pelo &lt;a href="https://k6.io/docs/using-k6-browser/overview/"&gt;K6 Browser&lt;/a&gt;, modulo para a realização de testes de performance na camada web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Métricas web💻
&lt;/h2&gt;

&lt;p&gt;O módulo K6 browser gera métricas baseadas nos &lt;a href="https://web.dev/explore/learn-core-web-vitals?hl=pt-br"&gt;Core Web Vitals&lt;/a&gt;, uma iniciativa que busca oferecer diretrizes unificadas sobre os principais indicadores de qualidade para garantir uma experiência ideal do usuário na Web.&lt;/p&gt;

&lt;p&gt;O conjunto atual da Core web vitals se concentra nos seguintes aspectos da experiência do usuário (carregamento, interatividade e estabilidade visual) e as seguinte métricas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maior exibição de conteúdo (LCP): Avalia o tempo de carregamento. Para uma boa experiência do usuário, é crucial que o LCP ocorra em até 2,5 segundos após o início do carregamento da página.&lt;/li&gt;
&lt;li&gt;Latência na primeira entrada (FID): Mensura a interatividade. Para uma experiência satisfatória do usuário, as páginas devem ter um FID de 100 milissegundos ou menos, garantindo uma resposta rápida às interações.&lt;/li&gt;
&lt;li&gt;Mudança de layout cumulativa (CLS): Avalia a estabilidade visual. Uma boa experiência do usuário é alcançada quando as páginas mantêm um CLS de 0.1 ou menos, evitando movimentos inesperados ou desconcertantes na interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dentre as métricas web primárias produzidas pelo K6, algumas das principais são:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Métrica&lt;/th&gt;
    &lt;th&gt;Descrição&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;browser_web_vital_lcp&lt;/td&gt;
    &lt;td&gt;informa o tempo de renderização da maior imagem ou bloco de texto visível na janela de visualização em relação ao momento em que a página começou a ser carregada.&lt;/td&gt;
  &lt;/tr&gt;
 &lt;tr&gt;
    &lt;td&gt;browser_web_vital_fid&lt;/td&gt;
    &lt;td&gt;mede o tempo entre a primeira interação do usuário com uma página, até o momento em que o navegador consegue começar a processar manipuladores de eventos em resposta a essa interação.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;browser_web_vital_cls&lt;/td&gt;
    &lt;td&gt;medida do maior burst de pontuações de troca de layout para cada mudança inesperada que ocorre durante toda a vida útil de uma página.&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;browser_web_vital_ttfb&lt;/td&gt;
    &lt;td&gt;mede o tempo entre a solicitação de um recurso e quando o primeiro byte de uma resposta começa a chegar.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;browser_web_vital_fcp&lt;/td&gt;
    &lt;td&gt;mede o tempo entre o início do carregamento da página e o momento em que qualquer parte do conteúdo dela é renderizada na tela.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;browser_web_vital_inp&lt;/td&gt;
    &lt;td&gt;avalia a capacidade de resposta geral de uma página às interações do usuário observando a latência de todas as interações de clique, toque e teclado que ocorrem durante a vida útil de uma visita do usuário a uma página.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Como mencionado anteriormente, algumas das métricas web do K6 estão relacionadas aos Core Web Vitals, especificamente os indicadores: &lt;em&gt;browser_web_vital_lcp, browser_web_vital_fid e browser_web_vital_cls&lt;/em&gt;. Para alcançar resultados positivos nessas métricas, é recomendável visar o percentil P(75) para os valores esperados de LCP, FID e CLS.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;Bom&lt;/th&gt;
&lt;th&gt;Ruim&lt;/th&gt;
&lt;th&gt;Percentil&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;(LCP)&lt;/td&gt;
&lt;td&gt;≤ 2.500 ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 4.000 ms&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(FID)&lt;/td&gt;
&lt;td&gt;≤ 100 ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 300 ms&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(CLS)&lt;/td&gt;
&lt;td&gt;≤ 0,1&lt;/td&gt;
&lt;td&gt;&amp;gt; 0,25&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Além dos Core Web Vitals, as métricas web do K6 também trazem resultados para outros pontos vitais como: &lt;a href="https://web.dev/articles/inp?hl=pt-br"&gt;browser_web_vital_inp&lt;/a&gt;, &lt;a href="https://web.dev/articles/fcp?hl=pt-br"&gt;browser_web_vital_fcp&lt;/a&gt; e &lt;a href="https://web.dev/articles/ttfb?hl=pt-br"&gt;browser_web_vital_ttfb&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vale ressaltar que, como as métricas mencionadas não são classificadas como Core Web Vitals, não é estritamente obrigatório que os sites atinjam o nível 'bom' nessas métricas, contanto que isso não influencie negativamente a pontuação das métricas fundamentais para a experiência do usuário(LCP, FID, CLS).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusão💖
&lt;/h2&gt;

&lt;p&gt;Atualmente, o K6 se destaca como uma ferramenta versátil para realizar testes de desempenho tanto na camada web quanto na camada de backend, proporcionando a flexibilidade de estratégias híbridas.&lt;/p&gt;

&lt;p&gt;O módulo web do K6 oferece análises detalhadas sobre o desempenho de nossa aplicação web, permitindo identificar gargalos críticos que podem afetar a experiência do usuário.&lt;/p&gt;

&lt;p&gt;A pagina do &lt;a href="https://web.dev/explore/learn-core-web-vitals?hl=pt-br"&gt;Core Web Vitals&lt;/a&gt;, traz uma serie de recomendações de otimizações para: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/optimize-cls?hl=pt-br"&gt;Otimizar a mudança de layout cumulativa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/optimize-lcp?hl=pt-br"&gt;Otimizar a maior exibição de conteúdo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/optimize-fid?hl=pt-br"&gt;Otimizar a latência na primeira entrada&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gostou do conteúdo e quer saber mais sobre testes de performance com K6? Então não deixe de conferir meu curso na Udemy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA"&gt;Teste de performance com K6&lt;/a&gt; ✨&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>go</category>
      <category>performance</category>
      <category>k6</category>
    </item>
  </channel>
</rss>
