Imagem gerada com a ferramenta Criador de Imagens do Bing.
A criação de testes é uma parte crucial do processo de desenvolvimento de software. Pois garante que o software funcione corretamente e atenda às expectativas dos usuários.
No entanto, um desafio enfrentado pelos desenvolvedores é obter dados falsos e aleatórios para serem usados nestes testes. Dados falsos são necessários para simular cenários realistas e garantir que o software seja capaz de lidar com diferentes situações.
Para auxiliar na geração de dados falsos para os testes, existe uma excelente biblioteca chamada Bogus, disponível nesse repositório do Nuget.
Esta biblioteca auxilia na geração de instâncias de dados fakes, de acordo com as classes do seu projeto.
Um pequeno exemplo:
public class NotaFiscal
public long Id { get; set; }
public int Operacao { get; set; }
public string TipoEmissao { get; set; }
public string ModeloDocumento { get; set; }
public string Situacao { get; set; }
public int Serie { get; set; }
public int Numero { get; set; }
public DateTime DataEmissao { get; set; }
public DateTime DataEntradaSaida { get; set; }
}
Para gerar uma instância fake da classe NotaFiscal, poderíamos fazer o seguinte código usando o Bogus:
using Bogus;
namespace Exemplo
{
public class NotaFiscalFaker : Faker<NotaFiscal>
{
public NotaFiscalFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Operacao, f => f.Random.Int(1));
RuleFor(n => n.TipoEmissao, f => f.Random.String2(10));
RuleFor(n => n.ModeloDocumento, f => f.Random.String2(10));
RuleFor(n => n.Situacao, f => f.Random.String2(10));
RuleFor(n => n.Serie, f => f.Random.Int(1));
RuleFor(n => n.Numero, f => f.Random.Int(1));
RuleFor(n => n.DataEmissao, f=>f.Date.Recent());
RuleFor(n=>n.DataEntradaSaida,f=>f.Date.Recent());
}
}
}
Você pode usar esse builder da seguinte maneira:
var faker = new NotaFiscalFaker();
var fakeNotaFiscal = faker.Generate();
Com este pequeno exemplo, dá pra perceber que o Bogus, é uma mão-na-roda. Mas imagine um cenário em que tenhamos centenas de classes de dados extensas, daria um trabalhão, gerar um builder para cada uma dessas classes. Manter esses builders, à medida que estas classes vão sendo evoluídas, também dará um trabalho extra.
O Chat do novo Bing, pode nos ajudar com este trabalho braçal e maçante.
Abaixo, descrevo minha conversa com o Chat do Bing, e mostro o excelente resultado que ele me deu, durante a geração de builders, para as seguintes classes em c#:
NotaFiscal:
public class NotaFiscal
{
public long Id { get; set; }
/// <summary>
/// IND_OPER - Indicador do tipo de operação:
///
/// <para>0 - Entrada</para>
/// <para>1 - Saída</para>
/// </summary>
public int Operacao { get; set; }
/// <summary>
/// IND_EMIT - Indicador do emitente do documento fiscal:
///
/// <para>0 - Emissão própria</para>
/// <para>1 - Terceiros</para>
/// </summary>
public string TipoEmissao { get; set; }
public NotaFiscalProdutoNaturezaOperacao NaturezaOperacao { get; set; }
public Participante Participante { get; set; }
public string ModeloDocumento { get; set; }
public string Situacao { get; set; }
public int Serie { get; set; }
public int Numero { get; set; }
public string Chave { get; set; }
public DateTime DataEmissao { get; set; }
public DateTime DataEntradaSaida { get; set; }
public decimal ValorTotal { get; set; }
public int TipoPagamento { get; set; }
public decimal ValorDesconto { get; set; }
public decimal ValorAbatimento { get; set; }
public decimal ValorMercadorias { get; set; }
public int TipoTransporte { get; set; }
public decimal ValorFrete { get; set; }
public decimal ValorSeguro { get; set; }
public decimal ValorDespesas { get; set; }
public decimal ICMS_BC { get; set; }
public decimal ICMS_Aliquota { get; set; }
public decimal ICMS_Valor { get; set; }
public decimal ICMS_ST_BC_Valor { get; set; }
public decimal ICMS_ST_Retido_Valor { get; set; }
public decimal IPI_Valor { get; set; }
public decimal PIS_Valor { get; set; }
public decimal PIS_ST_Valor { get; set; }
public decimal COFINS_Valor { get; set; }
public decimal COFINS_ST_Valor { get; set; }
public List<NotaFiscalProduto> Produtos { get; set; }
}
Participante:
public class Participante
{
public long Id { get; set; }
public string Codigo { get; set; }
public string Nome { get; set; }
public string Cod_Pais { get; set; }
public string CNPJ { get; set; }
public string CPF { get; set; }
public string IE { get; set; }
public string SUFRAMA { get; set; }
public string EnderecoCod_Mun { get; set; }
public string EnderecoLogradouro { get; set; }
public string EnderecoNumero { get; set; }
public string EnderecoComplemento { get; set; }
public string EnderecoBairro { get; set; }
}
Produto:
public class Produto
{
public long Id { get; set; }
public string Codigo { get; set; }
public string Descricao { get; set; }
public NotaFiscalProdutoUnidade Unidade { get; set; }
public int Origem { get; set; }
public string NCM { get; set; }
public string CEST { get; set; }
public decimal ICMS_Aliquota { get; set; }
}
NotaFiscalProduto:
public class NotaFiscalProduto
{
public long NotaFiscalId { get; set; }
public int Numero { get; set; }
public Produto Produto { get; set; }
public decimal Quantidade { get; set; }
public decimal ValorTotal { get; set; }
public decimal Desconto { get; set; }
public int Movimentado { get; set; }
public string ICMS_CST { get; set; }
public string CFOP { get; set; }
public decimal ICMS_BC { get; set; }
public decimal ICMS_Aliquota { get; set; }
public decimal ICMS_Valor { get; set; }
public decimal ICMS_ST_BC { get; set; }
public decimal ICMS_ST_Aliquota { get; set; }
public decimal ICMS_ST_Valor { get; set; }
public int IPI_Apuracao { get; set; }
public string IPI_CST { get; set; }
public string IPI_Enquadramento { get; set; }
public decimal IPI_BC { get; set; }
public decimal IPI_Aliquota { get; set; }
public decimal IPI_Valor { get; set; }
public string PIS_CST { get; set; }
public decimal PIS_BC { get; set; }
public decimal PIS_Aliquota { get; set; }
public decimal PIS_BC_Quantidade { get; set; }
public decimal PIS_Aliquota_Reais { get; set; }
public decimal PIS_Valor { get; set; }
public string COFINS_CST { get; set; }
public decimal COFINS_BC { get; set; }
public decimal COFINS_Aliquota { get; set; }
public decimal COFINS_BC_Quantidade { get; set; }
public decimal COFINS_Aliquota_Reais { get; set; }
public decimal COFINS_Valor { get; set; }
public string ContaContabil { get; set; }
public decimal ValorAbatimento { get; set; }
}
NotaFiscalProdutoUnidade:
public class NotaFiscalProdutoUnidade
{
public long Id { get; set; }
public string Codigo { get; set; }
public string Simbolo { get; set; }
}
NotaFiscalProdutoNaturezaOperacao:
public class NotaFiscalProdutoNaturezaOperacao
{
public long Id { get; set; }
public string Codigo { get; set; }
public string Descricao { get; set; }
}
Abaixo, a transcrição da minha conversa com o chat do Bing:
Meu prompt:
1 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "NotaFiscalProdutoNaturezaOperacao".
Resposta do Chat:
Então segui, com os seguintes prompts:
2 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "NotaFiscalProdutoUnidade".
3 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "NotaFiscalProduto".
4 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "Produto".
5 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "Participante".
Neste momento, algo interessante ocorreu: Eu esqueci de informar para o chat do Bing, a definição da classe Participante:
6 - Usando a biblioteca Bogus para .Net, gere um builder para criar instâncias fakes da classe "NotaFiscal".
Em alguns minutos, consegui criar os builders para todo o modelo de dados da API:
Obtendo como resultado as seguintes classes:
NotaFiscalProdutoNaturezaOperacaoFaker
public class NotaFiscalProdutoNaturezaOperacaoFaker : Faker<NotaFiscalProdutoNaturezaOperacao>
{
public NotaFiscalProdutoNaturezaOperacaoFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Codigo, f => f.Random.String2(10));
RuleFor(n => n.Descricao, f => f.Lorem.Sentence());
}
}
NotaFiscalProdutoUnidadeFaker
public class NotaFiscalProdutoUnidadeFaker : Faker<NotaFiscalProdutoUnidade>
{
public NotaFiscalProdutoUnidadeFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Codigo, f => f.Random.String2(10));
RuleFor(n => n.Simbolo, f => f.Random.String2(3));
}
}
NotaFiscalProdutoFaker
public NotaFiscalProdutoFaker()
{
RuleFor(n => n.NotaFiscalId, f => f.Random.Long(1));
RuleFor(n => n.Numero, f => f.Random.Int(1));
RuleFor(n => n.Produto, f => new ProdutoFaker().Generate());
RuleFor(n => n.Quantidade, f => f.Random.Decimal(1));
RuleFor(n => n.ValorTotal, f => f.Random.Decimal(1));
RuleFor(n => n.Desconto, f => f.Random.Decimal(1));
RuleFor(n => n.Movimentado, f => f.Random.Int(1));
RuleFor(n => n.ICMS_CST, f => f.Random.String2(10));
RuleFor(n => n.CFOP, f => f.Random.String2(10));
RuleFor(n => n.ICMS_BC, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_ST_BC, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_ST_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_ST_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.IPI_Apuracao, f => f.Random.Int(1));
RuleFor(n => n.IPI_CST, f => f.Random.String2(10));
RuleFor(n => n.IPI_Enquadramento, f => f.Random.String2(10));
RuleFor(n => n.IPI_BC, f => f.Random.Decimal(1));
RuleFor(n => n.IPI_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.IPI_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_CST, f => f.Random.String2(10));
RuleFor(n => n.PIS_BC, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_BC_Quantidade, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_Aliquota_Reais, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_CST, f => f.Random.String2(10));
RuleFor(n => n.COFINS_BC, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_BC_Quantidade, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_Aliquota_Reais, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_Valor, f => f.Random.Decimal(1));
}
ProdutoFaker
public class ProdutoFaker : Faker<Produto>
{
public ProdutoFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Codigo, f => f.Random.String2(10));
RuleFor(n => n.Descricao, f => f.Lorem.Sentence());
RuleFor(n => n.Unidade, f => new NotaFiscalProdutoUnidadeFaker().Generate());
RuleFor(n => n.Origem, f => f.Random.Int(1));
RuleFor(n => n.NCM, f => f.Random.String2(10));
RuleFor(n => n.CEST, f => f.Random.String2(10));
RuleFor(n => n.ICMS_Aliquota, f => f.Random.Decimal(1));
}
}
ParticipanteFaker
public class ParticipanteFaker : Faker<Participante>
{
public ParticipanteFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Codigo, f => f.Random.String2(10));
RuleFor(n => n.Nome, f => f.Name.FullName());
RuleFor(n => n.Cod_Pais, f => f.Address.CountryCode());
RuleFor(n => n.CNPJ, f => f.Company.Cnpj());
RuleFor(n => n.CPF, f => f.Person.Cpf());
RuleFor(n => n.IE, f => f.Random.String2(10));
RuleFor(n => n.SUFRAMA, f => f.Random.String2(10));
RuleFor(n => n.EnderecoCod_Mun, f => f.Random.String2(10));
RuleFor(n => n.EnderecoLogradouro, f => f.Address.StreetName());
RuleFor(n => n.EnderecoNumero, f => f.Address.BuildingNumber());
RuleFor(n => n.EnderecoComplemento, f => f.Address.SecondaryAddress());
RuleFor(n => n.EnderecoBairro, f => f.Address.County());
}
}
NotaFiscalFaker
public class NotaFiscalFaker : Faker<NotaFiscal>
{
public NotaFiscalFaker()
{
RuleFor(n => n.Id, f => f.Random.Long(1));
RuleFor(n => n.Operacao, f => f.PickRandom(new int[] { 0, 1 }));
RuleFor(n => n.TipoEmissao, f => f.PickRandom(new string[] { "0", "1" }));
RuleFor(n => n.NaturezaOperacao, f => new NotaFiscalProdutoNaturezaOperacaoFaker().Generate());
RuleFor(n => n.Participante, f => new ParticipanteFaker().Generate());
RuleFor(n => n.ModeloDocumento, f => f.Random.String2(10));
RuleFor(n => n.Situacao, f => f.Random.String2(10));
RuleFor(n => n.Serie, f => f.Random.Int(1));
RuleFor(n => n.Numero, f => f.Random.Int(1));
RuleFor(n => n.Chave, f => f.Random.String2(10));
RuleFor(n => n.DataEmissao, f => f.Date.Recent());
RuleFor(n => n.DataEntradaSaida, f => f.Date.Recent());
RuleFor(n => n.ValorTotal, f => f.Random.Decimal(1));
RuleFor(n => n.TipoPagamento, f => f.Random.Int(1));
RuleFor(n => n.ValorDesconto, f => f.Random.Decimal(1));
RuleFor(n => n.ValorAbatimento, f => f.Random.Decimal(1));
RuleFor(n => n.ValorMercadorias, f => f.Random.Decimal(1));
RuleFor(n => n.TipoTransporte, f => f.Random.Int(1));
RuleFor(n => n.ValorFrete, f => f.Random.Decimal(1));
RuleFor(n => n.ValorSeguro, f => f.Random.Decimal(1));
RuleFor(n => n.ValorDespesas, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_BC, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_Aliquota, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_ST_BC_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.ICMS_ST_Retido_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.IPI_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.PIS_ST_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.COFINS_ST_Valor, f => f.Random.Decimal(1));
RuleFor(n => n.Produtos, f => new NotaFiscalProdutoFaker().Generate(f.Random.Int(5)));
}
}
Repare que ele entendeu os comentários das propriedades da classe NotaFiscal:
/// <summary>
/// IND_OPER - Indicador do tipo de operação:
///
/// <para>0 - Entrada</para>
/// <para>1 - Saída</para>
/// </summary>
public int Operacao { get; set; }
/// <summary>
/// IND_EMIT - Indicador do emitente do documento fiscal:
///
/// <para>0 - Emissão própria</para>
/// <para>1 - Terceiros</para>
/// </summary>
public string TipoEmissao { get; set; }
Fazendo a personalização dos valores que podem ser incluidos nestas propridades:
RuleFor(n => n.Operacao, f => f.PickRandom(new int[] { 0, 1 }));
RuleFor(n => n.TipoEmissao, f => f.PickRandom(new string[] { "0", "1" }));
Com estas classes geradas, ao escrever os testes unitários, ou até os testes de integração, sempre que precisar de uma instância com dados totalmente randômicos destas classes, tudo que tenho a fazer é invocar os builders, assim:
var faker = new NotaFiscalProdutoNaturezaOperacaoFaker();
var fakeNotaFiscalProdutoNaturezaOperacao = faker.Generate();
var faker = new NotaFiscalProdutoNaturezaOperacaoFaker();
var fakeNotaFiscalProdutoNaturezaOperacao = faker.Generate();
var faker = new NotaFiscalProdutoUnidadeFaker();
var fakeNotaFiscalProdutoUnidade = faker.Generate();
var faker = new NotaFiscalProdutoFaker();
var fakeNotaFiscalProduto = faker.Generate();
var faker = new ProdutoFaker();
var fakeProduto = faker.Generate();
var faker = new ParticipanteFaker();
var fakeParticipante = faker.Generate();
var faker = new NotaFiscalFaker();
var fakeNotaFiscal = faker.Generate();
Não é objetivo deste artigo, mostrar como criar os testes, o objetivo aqui foi somente mostrar como as inteligências artificiais, podem nos ajudar a fazer o trabalho chato e altamente suscetível à erros, de forma automática. Tudo que você precisa fazer é fornecer um contexto e caprichar nos prompts.
Top comments (0)