Criando um modulo xk6 para k6
Tags: k6, go, testing, performance
Published: 2024-06-13 11:25:15

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. 

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

Neste artigo, veremos como utilizar o XK6 para desenvolver um novo módulo, baseado em uma solução em Go.

## Pré-requisitos📑

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

## O problema👥

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.

Atualmente, o K6 não oferece um módulo que permita a geração de [CPF](https://pt.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas) 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. 

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.

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 [go-cpf](https://github.com/mvrilo/go-cpf), que oferece a possibilidade de geração de CPF com e sem mascara de formatação.

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

> Neste exemplo, nosso modulo foi iniciado em um diretorio de nome xk6-cpf.

No mesmo diretorio onde nosso modulo foi iniciado, vamos criar um arquivo de nome `cpf.go`, utilizaremos esse arquivo para realizar toda a configuração do nosso modulo. 

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.

```
package cpf
```

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

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

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

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

> 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'

Vamos definir uma estrutura do tipo CPF, que conterá as funções disponíveis para uso no Javascript.

```
type CPF struct{}
```
Precisamos criar uma função do tipo `CPF` 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: 

```
func (*CPF) Cpf(formatado bool) string {
	if formatado {
		return cpf.GeneratePretty()
	}	
	return cpf.Generate()
}
```
Ao final, nosso arquivo cpf.go terá a seguinte estrutura:
 
```
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()
	
}
```
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:

```
xk6 build --with xk6-cpf=.
```

## Utilizando o modulo xk6-cpf👩‍💻
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:

```
import cpf from 'k6/x/cpf';
import { sleep } from 'k6';
```

Na fase de configuração, vamos definir uma carga para observar a geração de CPFs utilizando nosso módulo xk6: 

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

}
```
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.

```
export default function () {
  console.log(`Gerando um novo CPF: ${cpf.cpf(false)}`);
  sleep(0.5);
}
```

> O argumento _**false**_ informando na função cpf indica que queremos um cpf sem mascara de formatação.

Para executar nosso script, podemos utilizar o comando `.\k6.exe run teste.js`, podemos observar o resultado de saida: 

```
          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .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
```
## Utilizando um modulo remoto☁️
No exemplo anterior, o nosso módulo XK6 foi gerado localmente. Uma alternativa de utilização é disponibilizar um módulo remoto para uso.

Para isso, na sua ferramenta de linha de comando, utilize o seguinte comando:

```
xk6 build --with github.com/marlo2222/xk6-cpf
```

Utilizando o script anteriomente contruido, podemos utilizar o seguinte comando para execução: 

```
.\k6.exe run teste.js
```
E como resultado de saida teremos: 

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

## Conclusão❤️
Como podemos observar, o XK6 abre inúmeras possibilidades para criarmos nossos próprios módulos, preenchendo lacunas existentes na ferramenta atualmente.

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.

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) ✨