Gerando dados com K6 utilizando xk6-faker
Tags: testing, performance, k6, go
Published: 2024-03-14 23:36:53

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.

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

## Faker👥

[Faker.js ](https://github.com/faker-js/faker)é uma biblioteca Javascript que oferece funções para gerar dados aleatórios sob demanda. Esses dados podem incluir:

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

> Mais detalhes sobre os diferentes tipos de dados que podem ser gerados estão disponiveis na documentação da ferramenta: [Documentação](https://github.com/faker-js/faker)

```
// 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(),
  };
}
```
> Exemplo de um codigo para geração de um usuario com dados aleatorios.

##Por que utilizar xk6-faker👀

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:

- Tamanho do download
- Uso de memória
- Tempo de inicialização

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.

> A lista completa de funções disponiveis `gofakeit` que é a base do modulo xk6-faker pode ser encontrada no seguinte link: [full list functions](https://github.com/brianvoe/gofakeit?tab=readme-ov-file#functions).

## Pré-requisitos📑

- [K6 instalado](https://k6.io/docs/get-started/installation/)
- [Go instalado](https://go.dev/)

### Instalando o XK6🔨
Primeiramente, vamos nos certificar que o Go está instalado corretamente. Em qualquer ferramenta de linha de comando de sua preferencia utilize o comando `go version` para verificar a versão do Go instalada:

```
go version go1.19.5 windows/amd64
```
> Esse tutorial será feito em maquina com sistema windows, utilizando o git bash.

Para adicionar o xk6 binário ao seu Go path, utilize o seguinte comando:

```
go install go.k6.io/xk6/cmd/xk6@latest
```
> Caso você esteja enfrentando problemas relacionados à desativação de módulos pelo `GO111MODULE`, você pode resolver executando o seguinte comando: `go env -w GO111MODULE=on`. Isso irá ativar os módulos Go e permitir o correto funcionamento do gerenciamento de dependências.

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

Para obter mais informações sobre o GOPATH, consulte o seguinte material: [gopath](https://go.dev/doc/gopath_code#GOPATH).

### Utilizando o xk6-faker😁
Para instalação do plugin [xk6-faker](https://github.com/szkiba/xk6-faker) podemos utilizar o seguinte comando:

`xk6 build --with github.com/szkiba/xk6-faker@latest`

Agora que o modulo está instalado, temos uma nova e poderosa opção para geraração de dados aleatorios.

Vamos utilizar o seguinte script de exemplo para execução e geração de dados ramdomicos:

```
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 2,
  duration: '5s',
  thresholds: {
    http_req_failed: ['rate < 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) => r.status === 201,
    'Message sucesso': (r) => r.json('message') === 'Cadastro realizado com sucesso'
  });

  sleep(1)
}

```

O primeiro passo é a adição do modulo xk6-faker na fase de inicialização, vamos adicionar a seguinte linha ao script:

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

Ao realizar as modificações necessárias e utilizar o módulo xk6-faker para gerar dados aleatórios, o objeto `data` terá a seguinte estrutura:

```
let data = {
    nome: faker.person.firstName(),
    email: faker.person.email(),
    password: faker.internet.password(),
    administrador: 'true'
  }
```

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:

```
          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .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        
```

## Conclusão❤️
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.

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.

Agradecimentos aos [Iván Szkiba](https://github.com/szkiba), pela criação desse modulo, ajudem a manter esse projeto com uma ⭐.

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:

- [Teste de performance com K6](https://www.udemy.com/course/teste-de-performance-com-k6/?referralCode=95CCD8BC9F22A2A96BDA) ✨