Teste de unidade para quem não sabe nada de programação

Quando pedimos algum analista de teste para falar de testes de unidade, em 90% dos casos a resposta é automática: “Nível de teste em que o desenvolvedor valida uma unidade”, “Teste de caixa branca”, “Teste de desenvolvedor”, entre outras respostas. Falo isso porque o teste de unidade ainda é teste, sendo assim, para ser um profissional completo, além da teoria temos que buscar a aplicação prática desse teste.

Não estou dizendo para largar os testes de sistema e debruçarem sobre os códigos fonte. Longe disso. Mas digo que temos que saber que os testes de unidade são o melhor momento para se pegar defeitos de software. A fase mais barata depois dos requisitos e análise e também a fase em que inserimos mais defeitos em todo o processo de desenvolvimento de software, a codificação.

Pra quem acompanha o blog deve lembrar de um post que eu fiz a pouco mais de um ano chamado “Uma introdução a TDD com JUnit“. Naquele post falei um pouco sobre como implementar um teste genérico e passar uma collection para ser validada, usando também um pouco do conceito de DDT (Data Driven Testing).

No exemplo em citado acima, ainda precisaríamos conhecer um básico de orientação a objetos e de java, o que em muitos casos nos faz questionar a viabilidade  da participação do testador nesse nível de teste, já que a maioria dos nossos testadores e analistas de teste não possui fluência em alguma linguagem de programação. :(

Imagine se pudessemos fazer testes de unidade usando arquivos do Excel . . .  Quase um sonho. Não mais :)

Hoje estou repetindo aquele post para a plataforma .net, e gostaria de fazer uma afirmação um pouco forte: Qualquer testador, mesmo os que não conheçam nenhuma linha de código fonte em qualquer linguagem, pode elaborar testes de unidade com itens demostrados nesse post. :)

O papel dos nossos arquitetos de teste de software é encontrar maneiras e artifícios de simplificar o processo de testes, inclusive testes de unidade e testes automatizados.  Se nossa mão de obra não possui habilidades em desenvolvimento para elaborar testes de unidade convencionais, codificando os testes, podemos usar alguns dos conceitos do teste de software como o Teste dirigido por Dados para criar mecanismos com interfaces mais amigáveis para esses testes.

Outros blogs já fizeram estímulos a esse tipo de abordagem, como por exemplo quando o Elias Nogueira cita o uso de testes dirigidos por dados com o Selenium no post “Data Driven com Selenium IDE? Sim, é possível!!!“. É uma ótima maneira de mostrar que as certificações em teste de software nos dão um caminho, mas detemos usar a criatividade para implementar soluções técnicas de acordo com a necessidade. No exemplo do Elias, assim como neste, podemos notar que reduzimos o tempo de codificação, de manutenção e até mesmo a complexidade dos testes de forma muito significativa.

Abaixo eu gravei um vídeo demonstrando uma possível solução para esse impasse. Resumindo, através de recursos muito simples e que qualquer desenvolvedor .Net consegue usar, criamos um teste de unidade no formado te um caso de teste, e atribuímos a ele um arquivo do MS Excel de onde o testador pode implementar os testes no formato de entradas e resultados esperados.

No vídeo são explicados alguns conceitos como o TDD e o DDT, além de mostrar passo a passo a criação de uma classe de teste e sua classe de produção.

O vídeo tem pouco mais de 40 minutos, então tome um pouco de café e prepare a pipoca rsrs
(por favor não repare em eventuais gagueiras)
*Alguns hints não são exibidos pois a ferramenta de gravação não possui recursos para capturá-los


Usando TDD e DDT para teste de unidade no Visual Studio 2010 from Camilo Ribeiro on Vimeo.
 

Descrição resumida do processo:

Inicialmente criamos um projeto de desenvolvimento e um projeto de teste. No projeto de teste, escrevemos um caso de teste simples e através dele criamos nosso código de produção, que deve ser testado de forma automática pelo teste de unidade.

Repetimos o processo para cobrir pelo menos um teste de cada requisito, que seria o teste do caminho feliz do desenvolvedor, aquele teste que garante somente que não teremos um defeito blocante ou impeditivo na funcionalidade, mas que não impede defeitos de negócio.

Uma vez que a estrutura esteja criada, podemos reaproveitá-la para através de uma fonte de dados (neste caso uma planilha Excel), estabelecer uma relação de “de/para” entre as variáveis do código e as colunas do Excel.

Dessa forma criamos uma interface muito fácil de usar e muito mais produtiva do que escrever testes de unidade na forma de código executável.

O exemplo aqui foi usando o Excel somente para leitura, mas nada impede o uso de outras fontes de dados como um banco de dados, um arquivo de resource, um arquivo csv ou txt, um serviço na web, entre tantas outras formas de armazenar dados que podemos usar para código fonte de produção.

Da mesma forma, existem formas de realizar essa mesma solução técnicas em quase todas as linguagens de programação, incluindo java, php, c++ e etc. Converse com seu arquiteto e tente inovar reduzindo custo quando o teste é mais barato. A melhor forma de corrigir um defeito é se ele não existir. ;)

Classe de teste de unidade usada no vídeo:

// Namespaces usados
// Used namespaces
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebApplication1;

// Nossa classe de testes
// Our test class
[TestClass]
public class TrianguloTeste
{
// Adaptação realizada para utilizar o Data Source no TestContext
// Adaptation made to use the Data Source in TestContext
private TestContext testContextInstancia;

public TestContext TestContext
{
get {
return testContextInstancia;
}
set {
testContextInstancia = value;
}
}

// Referência usada para especificar forma de acesso do DataSource, localização, metodo, string de conexão e item usado.
// Reference used to specify how to access the DataSource, location, method, and connection string used item.
[DataSource("System.Data.Odbc",
"Dsn=Excel Files;dbq=|DataDirectory|\\testeDadosTriangulo.xlsx;defaultdir=C:;driverid=1046;maxbuffersize=2048;pagetimeout=5",
"Plan1$",
DataAccessMethod.Sequential),
DeploymentItem("TestProject1\\testeDadosTriangulo.xlsx"),
TestMethod]
// Nosso metodo de teste
// Our test method
public void validaTriangulo()
{
// Declaração do objeto que será testado
// Declaration of the object to be tested
Triangulo triangulo = new Triangulo();

// Dados de entrada
// Input data
int lado1 = int.Parse(TestContext.DataRow["lado1"].ToString());
int lado2 = int.Parse(TestContext.DataRow["lado2"].ToString());
int lado3 = int.Parse(TestContext.DataRow["lado3"].ToString());

// Resultado esperado
// Expected result
string resultado = TestContext.DataRow["resultado"].ToString();

// Comparação
// Test
Assert.AreEqual(resultado, triangulo.retornaTipoTriangulo(lado1, lado2, lado3));

}
}

Quem quiser conhecer mais sobre testes de unidade dirigidos a dados no Visual Studio pode consultar este tudorial explicando passo a passo os mesmos procedimentos do vídeo no site do MSDN.

Para quebrar o clima e trazer um pouco de humor fica a frase que deve servir de alerta:
“Unit tests are like contraceptives. Do not use today and take the risk at some time have problems that could have been avoided”

Bons testes :)

Camilo Ribeiro

Test Engineer at Klarna
Desenvolvedor, testador e agilista desde 2005, atualmente trabalhando na Suécia.

13 thoughts on “Teste de unidade para quem não sabe nada de programação

  1. Muito bom o post e o video camilo, nota 10! :D
    Sempre tive um pouco de preguiça do Visual Studio mas ele esta se saindo melhor o esperado (por mim)
    Keep up the good work ;)

  2. Obrigado pelo comentário e pelo elogio Leonardo :D

    Eu era (e ainda sou) muito fã da plataforma de teste da IBM, mas confesso que ultimamente tenho me deixado levar pelo Visual Studio, pois ele simplifica MUITO a nossa vida. Esse vídeo é um pedacinho d que o Visual Studio faz só em teste de unidade.

    Na verdade da pra gerar testes de unidade de forma automática a partir de classes prontas, depois é só mudar para o conceito data-driven através de um Excel, web service, xml ou outros tipos de fontes de dados. Também da pra usar um design pattern chamado Builder, que simplifica o trabalho do desenvolvedor na hora de montar objetos de teste. Então usamos o conceito de data-driven e temos “object-driven unit tests”, que é o que realmente gera ganho de produtividade, já que nem o código de atribuição de valores agente usaria. Mas aí já mais complicado também. . . Precisa de um pouco mais de conhecimento em OOP e DDD. Falo disso mais pra frente, ainda estou estudando ;)

    Fantástica a ferramenta. Microsoft de parabéns!

    Obrigado pelo apoio nas listas também.

    Abraços

  3. Muito bom o vídeo, Camilo!!

    Só um comentários que o meu ‘tique’ de desenvolvedor não deixa passar:
    – Ao invés de retornar o tipo do triangulo como string, recomendo criar um enum e retorna-lo. Assim, a possíbilidade de erro diminui bastante, pois ‘strings mágicas’ deixam de existir.

    Essa técnica é muito boa para testar situações limítrofes, sem precisar ficar criando um método de teste para cada situação!

    A MS está acompanhando bem a evolução do desenvolvimento de software, se integrando a comunidade e criando mais projetos Open Source. Isso vem acrescentando muito!!

    De novo, parabéns pelo vídeo, Camilo!!

  4. Grande Vinícius,

    Muito obrigado pela sua visita e pela sua contribuição.

    Saiba que você que startou a criação deste post e deste vídeo rsrs, por isso fico muito feliz que tenha gostado. Espero que o vídeo possa te ajudar também.

    Sua observação é muito pertinente. Usar um enum é uma ótima aplicação. Olhando como dev eu também não recomendaria o Embedded Resource que eu coloquei no final do vídeo, mas a intenção aqui era realmente passar o básico e evitar sofisticações, já que a maior parte dos leitores ainda é composta pelo “público alvo”, testadores. E como a maior parte do “público alvo” não tem fluência em desenvolvimento (20% apenas no Brasil segundo algumas pesquisas), achei melhor ir bem no básico.

    Vocês mestres do desenvolvimento é que tem criatividade e conhecimento para sofisticar e melhorar isso. :)

    Para quem não sabe o que é um enum: http://www.dotnetperls.com/enum
    Entendendo Embedded Resource: http://www.codeproject.com/KB/dotnet/embeddedresources.aspx

    De qualquer forma fico muito feliz com o seu comentário e sua recomendação.

    Novamente obrigado por enriquecer mais o post!

    Abraços.

  5. Muito bom o conteúdo Camilo!

    Ainda estou vendo o vídeo, mas acho que já dá pra comentar algo sobre o assunto, aliás, o vídeo ficou muito bom, bem didático!

    É legal fazer isso: abstrair o “como testar”. Muitas ferramentas focam justamente nisso, em abstrair para um linguagem/forma mais próxima da pessoa que irá utilizar ela. Porém, isso também tem os seus efeitos colaterais.

    Tive uma conversa na Campus Party desse ano, com o Felipe Knorr, e estava falando justamente sobre uma DSL que estava criando no trabalho, usando o Selenium. A ideia era facilitar a vida do Testador e deixar bem simples a criação dos testes, exemplo:

    login(usuarioX, senhaX)
    mensagemDeveAparecer(mensagemX)

    O Testador não precisaria conhecer nada do Selenium e muito menos de Java. Excelente não é?

    Nem tanto…

    O projeto não teve continuidade, pois surgiram outras demandas. Mas mesmo assim, dá pra prever o efeito colateral, da existência de uma ferramenta que ofereça tanta praticidade.

    A parte boa, é que o que a equipe de Testes iria usar uma API, e se um campo mudar de id por exemplo, eu não precisa mexer na API, e assim, os testes não iriam quebrar após alguma mudança da página web ou do Selenium.

    Os Testadores iriam conseguir automatizar de uma forma muito simples, mas ao mesmo tempo estariam dependentes da ferramenta e não iriam evoluir o seu conhecimento ao longo do tempo.

    E esse é o problema que o Felipe comentou, na hora eu não vi como um grande problema, mas se formos analisar bem, pode virar um grande problema ao longo do tempo. Principalmente, quando essa abstração é de algo, que não é tão complicado assim, como por exemplo: automatizar um teste com o Selenium.

    Resumindo, devemos tomar cuidado ao inserir essas facilidades no nosso dia-a-dia. É questão do que esperamos da nossa equipe de Testadores, se realmente queremos que ela apenas foque nos testes, então sem problemas, agora se queremos que ela não se limite apenas aos conhecimentos de Teste de Software, então é bom incentivar o estudo de linguagens e OO, por exemplo.

  6. Muito obrigado Fabrício.

    Como sempre enriquecendo mais o BugBang com seus comentários.

    Eu acredito que, por um motivo quase óbvio, estamos sempre um passo atrás do desenvolvimento quando falamos de sofisticação e automação. Acredito que em algum momento eles também questionaram a existência de frameworks e até orientação por objetos por exemplo.

    Imagine em 1969, lá no Smalltalk, quando um projetista falava com o desenvolvedor cabeça dura que ele não podia mais mudar aquele código, ele tinha que mudar em outra classe que era pai dessa que ele queria mudar. O cara deve ter achado complicado e pedia todas as noites pra voltar para o Cobol que era muito mais simples. Mas hoje não sai como viviam sem OO.

    Quando abstraímos ganhamos bastante em produtividade, diminuímos muito a complexidade, mas ao mesmo tempo perdemos um pouco de flexibilidade. Também concordo que trabalhar com algo que só sabemos o que tempos que usar para entrar e sair pode ser “perigoso”. Pode limitar a visão do testador, afinal de contas, ele não sabe o que está por trás daquele “casosUC058.xls”.

    A abordagem do post é para ajudar no desenvolvimento de testes de unidade, mas principalmente para demostrar que automação não está distante de todos e que podemos improvisar. Por isso fui tão “xiita” com os dados e coloquei num Excel, mas quando pensamos em testes automatizados, que também da pra usar a mesma abordagem, eu deixaria os dados em algo mais baixo, como um xml ou mesmo um banco de dados de teste e teria duas equipes. Uma de desenvolvimento de testes e outra de abstração, que trabalharia somente com os dados de teste. A equipe de desenvolvimento de testes ficaria por conta de escrever cenários de teste e desenvolvê-los enquanto a equipe de abstração pensaria em casos de teste e nos dados para cobri-los. Enfim, cada caso é um caso. . .

    Com certeza a equipe de desenvolvimento evoluiria muito em função da automação, mas seriam testadores focados nisso, enquanto os demais testadores que ainda não desenvolvem ou não tem interesse nesse tipo de atividade, poderia ser usados para os mesmos testes.

    Outra vantagem é que eu mudaria muito menos meu código fonte quando um determinado cenário de teste muda-se, apenas o próprio cenário. Quando precisar adicionar um novo teste, mudamos apenas o repositório de dados também. Podemos dizer que editaríamos (Numero de casos de teste – 1) vezes menos código fonte com a abordagem orientada a dados.

    De uma forma ou de outra, sabemos que existem vários tipos de testadores. Eu mesmo conheço testadores excelentes, mas que não tem a mínima vontade de evoluir no sentido de desenvolvimento, focando em negócios, gestão de projetos ou outras áreas do conhecimento.

    Concluindo, acho que sim, simplificar demais pode ser oneroso no início e pode estimular a acomodação, mas ao mesmo tempo podemos mostrar como é simples realizar tarefas como essa, de receber dados de uma fonte externa, e estimular o avanço técnico de pessoas que muitas vezes acham que estão longe demais de fazer essas “automações mega complexas”.

    Abraços,

    Camilo

  7. Sim Camilo, aliás, a proposta do post faz todo sentido, e também não quero ser xiita e falar que Testador deve sabe desenvolver, até porque eu trabalhei muito tempo na área de Teste, sem escrever um if que seja (rs).

    O comentário foi mais pra compartilhar os efeitos negativos de tal prática, efeitos esses que bem gerenciados, não se tornam em problemas.

    Uma das diferenças do Desenvolvedor para o Testador, e que faz com que a automação esteja em outro nível, em se tratamento de ferramentas para eles, é que o Desenvolvedor costuma ser preguiçoso (a preguiça boa). Afinal, dificilmente você vai encontrar um desenvolvedor que goste de executar a mesma tarefa “trozentas” vezes.

    Abraços!

  8. Entendi o seu comentário e como sempre é bem positivo:)

    Você mais que ninguém sempre acompanhou discussões em que xiitas se manifestavam sobre esse tipo de assunto rs, é um especialista no assunto.
    E sim, facilitar demais as coisas acaba complicando. Pra tudo “na vida, no universo e tudo mais” existe um equilíbrio. :)

    Obrigado novamente.

    Abraços!

  9. Amigo, gostei muito do tutorial, jah tinha visto mtos exemplos, mas a “preguiça de desenvolvedor” me impediu de “testar os testes”, seu video é show. Valew mesmo, abraços!

  10. Muito bom o vídeo Camilo, parabéns!

    A ferramenta da Microsoft é realmente impressionante, tive oportunidade de participar de um treinamento dessa ferramenta, onde o objetivo era ver como a ferramenta integra toda a parte de teste com a parte de desenvolvimento e realmente fiquei impressionado. Não haviam abordado essa parte de teste unitário, que é ainda tão boa quanto a parte de integração com os testes automáticos e manuais.

    Bem legal, parabéns novamente!

  11. Boa tarde, Camilo

    Sou estagiária de Teste em uma Multinacional, porém trabalho sozinha em uma equipe inteira de desenvolvedores utilizando as ferramentas da Microsoft. Foi solicitado que eu automatizasse todos os testes no Visual Studio, porém estou tendo dificuldades, já que não sou da área de desenvolvimento e aqui ninguém sabe automatizar testes nesta ferramenta. Teria algum Tutorial que eu pudesse seguir?
    Por exemplo, eu até consegui gravar um teste de navegação de sistema, porém os métodos não são gerados automaticamente no Teste, e além disso, só consigo dividir os cenários alterando os métodos na mão um a um, isso está correto ou está faltando conhecimento da minha parte?
    Obrigada

  12. Muito obrigado pelo comentário, fico muito feliz que tenha sido útil.

    Fique a vontade para enviar o seu feedback e sugestões de novos tópicos para o blog.

    Att,
    Camilo

Leave a Reply