Testes do Desenvolvedor: Indo além do Debug
Testes... Esta é uma questão delicada. No fundo todos pensam que sabem a importância dos testes, na prática poucos sabem como testar, quando testar e a real importância dos testes. Neste post vou falar hábitos e conceitos de testes e bem como alguns níveis básicos de testes que um bom desenvolvedor deveria fazer.
Muitos profissionais ainda pensam que testes são tarefa dos testadores e quem sabe, dependendo da empresa tem um cara de SQA envolvido na questão. Testes muitas vezes não são realizados por desenvolvedores e arquitetos, mas em muitos casos deveriam.
Nem sempre é fácil testar, muitas vezes a complexidade de se criar e realizar testes é uma barreira para a utilização desta disciplina tão importante da engenharia. Existem algumas barreiras para o uso de testes ou o uso adequando desta prática no decorrer do post pretendo abordar este assunto também.
Não estou aqui para falar do testes funcional, que as vezes é conhecido como teste de tela, existe muita técnica e práticas para realizar este tipo de testes, mas neste post não vou focar nisto mas sim nos testes do desenvolvedor e os testes que o desenvolvedor pode e deve fazer.
Debugar não é testar?
Não, mesmo. Debugar não é testar. O pior é muito desenvolvedores só usam o debug depois de colocar o código em produção e dar um erro que eles não sabem como corrigir. Já vi muito disso, também é comum ver desenvolvedores que acreditam que debugar é suficiente.
Quando você debuga você não faz isso com o intuito de verificar se a sua unidade de código esta o que, ou se o que você fez é o que o usuário realmente deseja, você até pode repetir o debug mas é complicado seguir ou se lembrar dos passos corretos.
Precisamos de mais, precisamos de testes, quando fala em testes começo falando de testes do desenvolvedor, isto mesmo. O testador ou SQA não pode ser a primeira barreira para achar defeitos e bugs mas sim a última barreira.
O Modelo em V
Este modelo de desenvolvimento de software foca muito em testes. Na pratica do lado esquerdo do V estão as práticas de desenvolvimento e do lado direito as práticas de testes. Com isso você vai testar em diversos momentos evitando aquele velho modelo de um testes em cascata apénas depois da construção.
Desta forma também conseguimos obter os erros, defeitos e bugs mais rapidamente e com isso podemos corrigir mais rápido, deixando assim a aplicação cada vez mais sólida e criando assim uma aplicação mais confiável para o cliente.
Muitas vezes mesmo com uma aplicação em camadas, para poder testar a unidade você irá precisar de mocks. Mocks são objetos que simulam o comportamento de um objeto real. Mocks são utilizados pelos seguintes motivos:
#2 Imagine que seu componente de banco carrega 30mil registros você não precisa de tudo isso para testar, logo se acessar o componente real seu teste vai ficar lento, quanto mais lento o teste mais demorado é a correção.
#3 O isolamento é outra questão importante. Os outros componentes que sua classe de negócio chama podem ter defeitos e isso pode dificultar seu testes, usando mocks você isola seu componente e tem certeza que se existem erros são da sua classe e não das outras do sistema.
#4 Com os mocks você pode desenvolver suas classes de negócio e testar mesmo que as outras classes de negócio do sistema não estejam prontas, você não precisa esperar elas estarem prontas para desenvolver seu código.
Os testes unitários e a criação de mocks tem o seu custo e nem sempre devemos criar testes, em casos muito básicos e simples não vale a pena testar. Você tem que sempre balancear isto e ver o que vale a pena ter teste unitário e o que não vale.
Testes de Regressão
Ter testes unitário é bom por que além do desenvolvedor liberar o código mais redondo ele permite a aplicação de testes de regressão que nada mais é do que rodar os testes unitários de novo. Isso é fundamental por que desta forma você pode modificar o código e tem um mecanismo que lhe da o mínimo de segurança de que as suas mudanças não estragaram o resto da aplicação.
Testes Integrados
Nem só de testes unitários vive o desenvolvedor. Testes unitários são bons mas não são o suficiente. Você vai precisar testar os componentes de forma integrada, ou seja, você testou seu código de forma isolada, agora tem que testar de forma conjunta, neste momento você pode colocar banco de dados, webservices, arquivos e outros sistemas. Este teste pode rodar em uma freqüência menor do que os testes unitários pois este pode demorar bem mais.
Analise de Testes
Agora já fugindo do domínio do desenvolvedor. Falando em um nível mais avançando da implementação do modelo em V e de testes a questão da analise de testes é fundamental. Mais hora menos hora você irá precisar de um analista de testes para trabalhar com isso.
Se você trabalha com Requisitos e casos de uso por exemplo pode criar os casos de testes a partir do requisitos, este é o cenário ideal, mas nem sempre conseguimos isto. Nestes casos a experiência de um analista de testes ajuda a pegar situação perigosas mas não é a solução para tudo.
Dependendo do software, mesmo bem desenvolvido, testar pode não ser tão trivial e você pode precisar criar a sua estratégia de testes através de um plano de testes por exemplo. Dependendo do caso será até necessário a criação de uma arquitetura de testes.
Barreiras para o teste
A primeira barreira é cultural. Nem todas as empresas de tem cultura de testes, algum tem mais tratam esta questão como opcional ainda nos dias de hoje isto ocorre. Quando existem equipes de testes muitas vezes é criando um clima de disputa dos desenvolvedores com os testadores, sempre que vi isso foi em empresas que só tem teste funcional e não tem testes do desenvolvedor.
Se o desenvolvedor cria testes unitário e testes integrados ele começa a ver os testes e os profissionais de testes de outra forma e isso facilita a adoção de outros níveis de testes e melhora a qualidade do produto, processo e do ambiente profissional.
Adicionar testes em sistemas já existentes ou em produção é mais difícil por que muitas vezes o código não é testável. Muitas equipes acabam escolhendo não criar testes por que não tem tempo ou recursos para modificar os códigos para deixa-los testáveis.
Criar Código Testável...
Esta deve ser uma preocupação do desenvolvedor. Dependendo do que o mesmo fizer pode ser mais fácil ou mais difícil ou até quase impossível de testar. As vezes até teríamos retorno em testar um certo ponto do sistema, agora o código pode estar muito pouco testável e isso pode acarretar um esforço tão grande que no final das contas se decide não testar, isto é ruim e só temos a perder com isso.
O ideal é começar des do inicio pensando em testes e criando código testável isso tudo a partir do desenvolvedor. Como disse antes isto nem sempre é possível, eu já passei por essa situação, neste caso você pode adotar uma abordagem incremental ligada a manutenção e o desenvolvimento de coisas novas.
Quando você tem que realizar algum manutenção ou adicionar uma nova funcionalidade no sistema deve aproveitar o momento para criar testes unitário e integrados. Eu já fiz isso , depois de um tempo eu tinha quase todo código com testes e o resultado foi muito bom.
Testar é uma necessidade básica que começa pela fato de que você precisa saber se o sistema funciona e termina no fato de que testar diminui os riscos do projeto e aumenta o retorno para o cliente.
Abraços e até a próxima.
Muitos profissionais ainda pensam que testes são tarefa dos testadores e quem sabe, dependendo da empresa tem um cara de SQA envolvido na questão. Testes muitas vezes não são realizados por desenvolvedores e arquitetos, mas em muitos casos deveriam.
Nem sempre é fácil testar, muitas vezes a complexidade de se criar e realizar testes é uma barreira para a utilização desta disciplina tão importante da engenharia. Existem algumas barreiras para o uso de testes ou o uso adequando desta prática no decorrer do post pretendo abordar este assunto também.
Não estou aqui para falar do testes funcional, que as vezes é conhecido como teste de tela, existe muita técnica e práticas para realizar este tipo de testes, mas neste post não vou focar nisto mas sim nos testes do desenvolvedor e os testes que o desenvolvedor pode e deve fazer.
Debugar não é testar?
Não, mesmo. Debugar não é testar. O pior é muito desenvolvedores só usam o debug depois de colocar o código em produção e dar um erro que eles não sabem como corrigir. Já vi muito disso, também é comum ver desenvolvedores que acreditam que debugar é suficiente.
Quando você debuga você não faz isso com o intuito de verificar se a sua unidade de código esta o que, ou se o que você fez é o que o usuário realmente deseja, você até pode repetir o debug mas é complicado seguir ou se lembrar dos passos corretos.
Precisamos de mais, precisamos de testes, quando fala em testes começo falando de testes do desenvolvedor, isto mesmo. O testador ou SQA não pode ser a primeira barreira para achar defeitos e bugs mas sim a última barreira.
O Modelo em V
Este modelo de desenvolvimento de software foca muito em testes. Na pratica do lado esquerdo do V estão as práticas de desenvolvimento e do lado direito as práticas de testes. Com isso você vai testar em diversos momentos evitando aquele velho modelo de um testes em cascata apénas depois da construção.
Desta forma também conseguimos obter os erros, defeitos e bugs mais rapidamente e com isso podemos corrigir mais rápido, deixando assim a aplicação cada vez mais sólida e criando assim uma aplicação mais confiável para o cliente.
Modelo em V
Este modelo é muito bom e traz um bom retorno ao cliente. Mas no modelo em V vão existir testes que não são do desenvolvedor como o teste de aceitação e os testes de arquitetura por exemplo. Podemos encarar a prova de conceito de arquitetura(proposta pelo RUP) como um nível de teste de arquitetura. Pois bem vamos focar nos testes do desenvolvedor então.
Testes unitários
Também muito conhecidos como testes de unidade. São feitos pelo desenvolvedor. Sim, o desenvolvedor deve criar estes testes. Os testes de unidade devem testar apénas o desenvolvimento do programador naquela construção. Por exemplo, imagine uma aplicação construída em camadas, pode ser o clássico MVC ou qualquer N-Tier. Logo nestes momento não importa testar a tela ou a camada de acesso ao banco. O que mais importa é testar a lógica de negocio que o desenvolvedor fez.
Não estou dizendo que não devemos testar o acesso ao banco e as telas, mas isso sera feito em outro nível de testes. Falarei destes níveis mais a frente neste mesmo post :).
A necessidade dos Mocks...
Testes unitários
Também muito conhecidos como testes de unidade. São feitos pelo desenvolvedor. Sim, o desenvolvedor deve criar estes testes. Os testes de unidade devem testar apénas o desenvolvimento do programador naquela construção. Por exemplo, imagine uma aplicação construída em camadas, pode ser o clássico MVC ou qualquer N-Tier. Logo nestes momento não importa testar a tela ou a camada de acesso ao banco. O que mais importa é testar a lógica de negocio que o desenvolvedor fez.
Não estou dizendo que não devemos testar o acesso ao banco e as telas, mas isso sera feito em outro nível de testes. Falarei destes níveis mais a frente neste mesmo post :).
A necessidade dos Mocks...
Muitas vezes mesmo com uma aplicação em camadas, para poder testar a unidade você irá precisar de mocks. Mocks são objetos que simulam o comportamento de um objeto real. Mocks são utilizados pelos seguintes motivos:
- 1 Possibilitar o teste de unidade
- 2 Performance e velocidade dos testes unitários
- 3 Isolamento dos testes
- 4 possibilita paralelizar o desenvolvimento
#2 Imagine que seu componente de banco carrega 30mil registros você não precisa de tudo isso para testar, logo se acessar o componente real seu teste vai ficar lento, quanto mais lento o teste mais demorado é a correção.
#3 O isolamento é outra questão importante. Os outros componentes que sua classe de negócio chama podem ter defeitos e isso pode dificultar seu testes, usando mocks você isola seu componente e tem certeza que se existem erros são da sua classe e não das outras do sistema.
#4 Com os mocks você pode desenvolver suas classes de negócio e testar mesmo que as outras classes de negócio do sistema não estejam prontas, você não precisa esperar elas estarem prontas para desenvolver seu código.
Os testes unitários e a criação de mocks tem o seu custo e nem sempre devemos criar testes, em casos muito básicos e simples não vale a pena testar. Você tem que sempre balancear isto e ver o que vale a pena ter teste unitário e o que não vale.
Testes de Regressão
Ter testes unitário é bom por que além do desenvolvedor liberar o código mais redondo ele permite a aplicação de testes de regressão que nada mais é do que rodar os testes unitários de novo. Isso é fundamental por que desta forma você pode modificar o código e tem um mecanismo que lhe da o mínimo de segurança de que as suas mudanças não estragaram o resto da aplicação.
Testes Integrados
Nem só de testes unitários vive o desenvolvedor. Testes unitários são bons mas não são o suficiente. Você vai precisar testar os componentes de forma integrada, ou seja, você testou seu código de forma isolada, agora tem que testar de forma conjunta, neste momento você pode colocar banco de dados, webservices, arquivos e outros sistemas. Este teste pode rodar em uma freqüência menor do que os testes unitários pois este pode demorar bem mais.
Analise de Testes
Agora já fugindo do domínio do desenvolvedor. Falando em um nível mais avançando da implementação do modelo em V e de testes a questão da analise de testes é fundamental. Mais hora menos hora você irá precisar de um analista de testes para trabalhar com isso.
Se você trabalha com Requisitos e casos de uso por exemplo pode criar os casos de testes a partir do requisitos, este é o cenário ideal, mas nem sempre conseguimos isto. Nestes casos a experiência de um analista de testes ajuda a pegar situação perigosas mas não é a solução para tudo.
Dependendo do software, mesmo bem desenvolvido, testar pode não ser tão trivial e você pode precisar criar a sua estratégia de testes através de um plano de testes por exemplo. Dependendo do caso será até necessário a criação de uma arquitetura de testes.
Barreiras para o teste
A primeira barreira é cultural. Nem todas as empresas de tem cultura de testes, algum tem mais tratam esta questão como opcional ainda nos dias de hoje isto ocorre. Quando existem equipes de testes muitas vezes é criando um clima de disputa dos desenvolvedores com os testadores, sempre que vi isso foi em empresas que só tem teste funcional e não tem testes do desenvolvedor.
Se o desenvolvedor cria testes unitário e testes integrados ele começa a ver os testes e os profissionais de testes de outra forma e isso facilita a adoção de outros níveis de testes e melhora a qualidade do produto, processo e do ambiente profissional.
Adicionar testes em sistemas já existentes ou em produção é mais difícil por que muitas vezes o código não é testável. Muitas equipes acabam escolhendo não criar testes por que não tem tempo ou recursos para modificar os códigos para deixa-los testáveis.
Criar Código Testável...
Esta deve ser uma preocupação do desenvolvedor. Dependendo do que o mesmo fizer pode ser mais fácil ou mais difícil ou até quase impossível de testar. As vezes até teríamos retorno em testar um certo ponto do sistema, agora o código pode estar muito pouco testável e isso pode acarretar um esforço tão grande que no final das contas se decide não testar, isto é ruim e só temos a perder com isso.
O ideal é começar des do inicio pensando em testes e criando código testável isso tudo a partir do desenvolvedor. Como disse antes isto nem sempre é possível, eu já passei por essa situação, neste caso você pode adotar uma abordagem incremental ligada a manutenção e o desenvolvimento de coisas novas.
Quando você tem que realizar algum manutenção ou adicionar uma nova funcionalidade no sistema deve aproveitar o momento para criar testes unitário e integrados. Eu já fiz isso , depois de um tempo eu tinha quase todo código com testes e o resultado foi muito bom.
Testar é uma necessidade básica que começa pela fato de que você precisa saber se o sistema funciona e termina no fato de que testar diminui os riscos do projeto e aumenta o retorno para o cliente.
Abraços e até a próxima.