Fala ai Radizeiros e Radizeiras, tudo bem com vocês?
Usar os testes unitários no seu software ajuda a reduzir significativamente os problemas em seus softwares, inclusive quando usamos as práticas de DEVOPs, onde você pode usar integrações contínuas em e a cada commit do seu software ele realiza os testes e em caso de sucesso ele segue a compilação e distribuição do seu software.
Então estou seguindo com mais essa série de teste unitários em Delphi, onde falamos dos principais métodos usados para testar as nossas rotinas criadas no software.
Hoje iremos preparar somente as units do nosso exemplo de testes unitários para realizar teste usando o banco de dados, com as técnicas aqui prendidas você poderá aplicar no seu cenário tranquilamente.
No código abaixo você pode observar que possuímos uma classe chamada TPessoa, onde já possuímos algumas propertys nela.
TPessoa = class private FNome: string; FDtCad: TDateTime; FStatus: integer; FSenha: string; FDtAlt: TDateTime; FGUUID: string; FTipo: integer; procedure SetNome(const Value: string); procedure SetDtAlt(const Value: TDateTime); procedure SetDtCad(const Value: TDateTime); procedure SetGUUID(const Value: string); procedure SetSenha(const Value: string); procedure SetStatus(const Value: integer); procedure SetTipo(const Value: integer); public procedure validarCampos; function TratarCPFCNPJ(value : string) : string; property Nome : string read FNome write SetNome; property GUUID : string read FGUUID write SetGUUID; property Senha : string read FSenha write SetSenha; property Tipo : integer read FTipo write SetTipo; property Status : integer read FStatus write SetStatus; property DtCad : TDateTime read FDtCad write SetDtCad; property DtAlt : TDateTime read FDtAlt write SetDtAlt; end;
Essas propertys da classe TPessoa representam os campos da tabela PESSOA do nosso banco de dados.
E agora vamos criar o DAO – Data Access Object dessa nossa classe, onde iremos chamá-la de PESSOADAO.
É nessa classe que iremos fazer as operações de INSERT, DELETE, UPDATE, para criar um teste unitário para inserir dados no banco, para que possamos validar se os dados que estão sendo inseridos estão corretos.
Mas antes de criar nossa classe DAO, iremos criar a conexão, vamos fazer de forma RAD mesmo, onde irei colocar um FDConnection e um FDQuery.
Não entrei no mérito aqui da configuração desses componentes pois é algo bem simples e sei que muitos de vocês já tem a familiaridade com essas configurações.
E agora vamos criar nossa classe de PESSOADAO.
type TPessoaDAO = class private FPessoa : TPessoa; FQuery : TFDQuery; public constructor Create; destructor Destroy; override; function Entidade : TPessoa; procedure Insert; procedure Update; procedure Delete; procedure BuscaID(ID : string); end; implementation uses System.SysUtils; { TPessoaDAO } procedure TPessoaDAO.BuscaID(ID: string); begin FQuery.Open('select * from pessoa where guuid='+QuotedStr(FPessoa.GUUID)); FQuery.First; FPessoa.GUUID := FQuery.FieldByName('GUUID').AsString; FPessoa.Nome := FQuery.FieldByName('NOME').AsString; FPessoa.Senha := FQuery.FieldByName('SENHA').AsString; FPessoa.Tipo := FQuery.FieldByName('TIPO').AsInteger; FPessoa.Status := FQuery.FieldByName('STATUS').AsInteger; FPessoa.DTCAD := FQuery.FieldByName('DTCAD').AsDateTime; FPessoa.DTALT := FQuery.FieldByName('GUUID').AsDateTime; end; constructor TPessoaDAO.Create; begin FPessoa := TPessoa.Create; if not Assigned(DataModule1) then DataModule1 := TDataModule1.Create(nil); FQuery := DataModule1.FDQuery1; end; procedure TPessoaDAO.Delete; begin FQuery.Open('select * from pessoa where guiid='+QuotedStr(FPessoa.GUUID)); FQuery.Delete; FQuery.ApplyUpdates(0); end; destructor TPessoaDAO.Destroy; begin FPessoa.DisposeOf; inherited; end; function TPessoaDAO.Entidade: TPessoa; begin Result := FPessoa; end; procedure TPessoaDAO.Insert; begin FQuery.Open('select * from pessoa where 1=2'); FQuery.Append; FQuery.FieldByName('GUUID').AsString := FPessoa.GUUID; FQuery.FieldByName('NOME').AsString := FPessoa.Nome; FQuery.FieldByName('SENHA').AsString := FPessoa.Senha; FQuery.FieldByName('TIPO').AsInteger := FPessoa.Tipo; FQuery.FieldByName('STATUS').AsInteger := FPessoa.Status; FQuery.FieldByName('DTCAD').AsDateTime := FPessoa.DTCAD; FQuery.FieldByName('GUUID').AsDateTime := FPessoa.DTALT; FQuery.Post; FQuery.ApplyUpdates(0); end; procedure TPessoaDAO.Update; begin FQuery.Open('select * from pessoa where guuid='+QuotedStr(FPessoa.GUUID)); FQuery.Edit; FQuery.FieldByName('GUUID').AsString := FPessoa.GUUID; FQuery.FieldByName('NOME').AsString := FPessoa.Nome; FQuery.FieldByName('SENHA').AsString := FPessoa.Senha; FQuery.FieldByName('TIPO').AsInteger := FPessoa.Tipo; FQuery.FieldByName('STATUS').AsInteger := FPessoa.Status; FQuery.FieldByName('DTCAD').AsDateTime := FPessoa.DTCAD; FQuery.FieldByName('GUUID').AsDateTime := FPessoa.DTALT; FQuery.Post; FQuery.ApplyUpdates(0); end;
Observe que possuímos duas variáveis onde uma é do tipo TPessoa e a outra do tipo TFDQuery, e vamos pegar essa query lá do nosso datamodule e passamos para o create dessa nossa classe.
E possuímos as operações, por exemplo o BuscarID, nós passamos um ID para esse método, que no caso para esse nosso exemplo é um GUUID, damos um select no banco de dados, posicionamos o cursor na primeira posição, FQuery.First, e preenchemos nossa classe PESSOA com os campos que retorna da nossa query.
Isso tudo ocorre porque nossa classe pessoa já foi criada no create.
Com esse objeto instanciado basta ser preenchido que já conseguimos trabalhar com os dados.
No método DELETE, ele busca uma GUUID especifica que está lá no banco de dados, paga esse registro e da logo em seguida um ApplyUpdate.
Quando chamamos o método Entidade ele retorna só a classe TPessoa, para que possamos ter acesso ao objeto Pessoa.
No insert executamos um truque que é um select que não retorna dados para que ele possa retornar o DataSet vazio, só para que esse dataset possa ser preenchido, fazendo assim posso logo em seguida dar um append e inserir dados nesses campos do dataset.
Fazemos a mesma coisa pro método update.
Com essa nossa classe DAO, já temos todas as operações preparadas para manipulação dos dados do nosso banco de dados.
Assim podemos nos testes unitário validar se um registro foi inserido com sucesso no banco de dados.
Continue…
Trabalhar com testes unitário nos ajuda e reduzir muito os erros ocasionados internamente em nosso sistema, e claro, automatizando esses testes, para que não venhamos ter que a cada implementação ter que realizar testes dentro do código e as vezes esquecendo do famigerado showmessage na aplicação.
Este post é mais um que faz parte de um dos meus treinamentos o treinamento de Testes unitários em Delphi.
O QUE VOCÊ IRÁ APRENDER?
O treinamento de Teste de Software dará a você a oportunidade de melhorar seu desenvolvimento, otimizar o seu tempo e te dar a possibilidade de atender melhor os seus clientes.
Implementar testes unitários em suas aplicações e utilizar todos os seus benefícios irá facilitar muito a sua vida, quando seu cliente disser :
“toda atualização é uma surpresa diferente, algo novo não funciona e o que funcionava para de funcionar, não aguento mais isso”
Você estará preparado para entregar uma solução robusta e eficaz.
Nesse treinamento você irá aprender de forma prática a desenvolver rotinas de testes para evitar erros e aumentar a segurança das suas aplicações.
CLIQUE AQUI E SAIBA MAIS SOBRE O TREINAMENTO TESTES UNITÁRIO EM DELPHI