Mostrar mensagens com a etiqueta Test Tools. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Test Tools. Mostrar todas as mensagens

segunda-feira, 10 de dezembro de 2012

Selenium Tutorial – Part II

Partindo do princípio que que a instalação dos recursos necessários correu bem, vamos começar a desenvolver os testes em Ruby usando o Selenium. Para consultar os detalhes sobre como preparar um ambiente para testar consultar o post anterior aqui.

Operações mais comuns com o selenium

Efetuar a inicialização do driver e navegação para uma página web deve ser efectuado usando o seguinte pedaço de código. A linha um têm como objectivo efetuar a inicialização do webdriver para utilização do Firefox, enquanto por outro lado a linha dois indica-nos para acedermos à página inicial do google.

  1:       driver = Selenium::WebDriver.for :firefox
  2:       driver.get "http://google.com"

Para efetuar a localização os elementos gráficos existem várias opções. Podemos identificar os mesmos por


ID – Podemos usar a localização por ID quando temos uma estrutura html em que o elemento procurado seja semelhante ao exemplo mostrado abaixo.



   1: <button id="buttonid">...</button>

Aqui usaríamos o método find_element de modo a encontrar o elemento procurado do seguinte modo

  1: element = driver.find_element(:id, "buttonid")

A partir daqui o elemento web fica guardado na variável element, para efetuarmos o tipo de operações que desejarmos. Estas operações podem ser clicks, asserts, entre outras. Do mesmo modo estão ainda disponíveis os seguintes modos de localização Classname, Tagname, Name, Link Text ou Partial Link Text, Css e Xpath. As duas últimas referências possuem uma sintaxe própria e mais detalhes sobre essa sintaxe podem ser encontrados aqui para o caso do XPath e aqui para o caso dos CSS selectors. O modo mais rápido de identificar estes valores é usando o utilitário FirePath que nos devolve estas duas expressões de forma automática.


De seguida apresentam-se alguns exemplos de como identificar e efetuar operações sobre as:


Escrever Texto em Caixas de Texto

Quando na página em questão temos um excerto de html, semelhante a que se apresenta em baixo

   1: <form>
   2: First name: <input type="text" name="firstname"><br>
   3: </form>
que tipicamente resulta em algo semelhante
First name:

o que queremos tipicamente fazer é escrever texto na caixa que nos é apresentada. Podemos fazer isto do seguinte modo.

  1: element = driver.find_element(:name, "firstname")
  2: element.set 'Joe'

 


Outra situação bastante comum é clicar em Botões, quando encontramos o seguinte elemento.



   1: <button id="mybutton">Click Me!</button>

o que resulta no seguinte



clicar no botão pode ser feito do seguinte modo

  1: element = driver.find_element(:id, "mybutton")
  2: element.click

 


Muitos mais elementos existem, mas os acima apresentados são os mais comuns. Para o próximo post contínuo a iterar pelos forms existentes.


 


Bom, até à próxima.

sexta-feira, 7 de dezembro de 2012

Selenium Tutorial – Part I

Selenium é uma framework para testes de software que permite a automação de aplicações Web. Este pode ser descarregado a partir da sua página aqui. A ideia deste post é mostrar como montar um ambiente e começar a desenhar testes sobre aplicações Web. Para começar a criar testes automatizados vamos primeiro montar um ambiente de desenvolvimento destes mesmos testes. Começamos por apresentar o conjunto de utilitários usados.

Começemos pelos Browsers, vamos precisar deles para aceder às aplicações Web. Pelo menos serão necessários o Firefox e Chrome.

Para nos ajudar a encontrar as informações das páginas sobre as quais vamos automatizar testes vamos precisar do

Firebug - Firebug é uma ferramenta de desenvolvimento web que facilita o debuging, edição e monitorização de CSS de qualquer site, HTML, DOM, XHR e JavaScript;
FirePath - FirePath é uma extensão para o Firefox que adiciona uma ferramenta de desenvolvimento para inspecionar, e gerar expressões XPath, seletores CSS assim como seletores JQuery (usando o sizzle selector engine).

Além disso vamos precisar do Ruby e de um IDE minimamente decente para trabalhar. Existem várias opções como por exemplo o Eclipse, Aptana e o IntelliJ Community Edition. Qualquer um deles serve, não existindo nenhum ponto que me pareça mais benéfico num deles, em relação aos restantes para o que se pretende fazer.

Depois de termos instalado um IDE vamos precisar do Ruby que pode ser obtido a partir daqui. Depois de instalado acedam à linha de comandos e verifiquem que o mesmo está instalado usando

ruby --version

Deverão obter uma linha com um resultado deste género

ruby 1.9.2p180 (2011-02-18) [i386-mingw32]

Caso tenham problemas com a execução desta instrução experimentam verificar que a pasta dos binários foi adicionada corretamente às variáveis de ambiente. Caso contrário adicionem o caminho ás variáveis de ambiente. Para facilitar podem usar o Rapid Environment Editor que é um interface gráfico que facilita a edição das variáveis de ambientes no Windows substituindo o interface gráfico do Windows.

Após a instalação do ruby vamos instalar as gems necessários para criação de testes com o selenium-webdriver. Para tal executar as seguintes instruções

gem install selenium
gem install selenium-webdriver
gem install test-unit

no final a sua instalação pode ser verificada utilizando o comando gem list. A partir daqui, e se tudo correu bem, basta apenas abrir o IDE e começar a escrever testes. Para deixar aqui apenas um exemplo do aspecto que teria um teste em que verifiquemos por exemplo se o blog Software@test é o primeiro hint quando se pesquisa por “softwareattest” no google. Não se preocupem muito em perceber o código, o seu objectivo e explicação será alvo de posts futuros.



   1: #!/bin/env ruby
   2: # encoding: utf-8
   3:  
   4: require 'rubygems'
   5: require 'selenium-webdriver'
   6: require "test/unit"
   7:  
   8: class Hello < Test::Unit::TestCase
   9:   def blog_first_in_google
  10:     begin
  11:       #Inicialização do driver e definição do browser a usar
  12:       driver = Selenium::WebDriver.for :firefox
  13:       driver.get "http://google.com"
  14:       
  15:       #Identificação da caixa de pesquisa do google e respectiva submissão
  16:       element = driver.find_element :name => "q"
  17:       element.send_keys "softwareattest"
  18:       #Expressão Xpath para o botão "feeling luck" (popup)
  19:       submit = driver.find_element(:xpath, ".//*[@id='gsr']/table/tbody/tr/td[2]/table/tbody/tr[11]/td/div/div/span[2]/span/input")
  20:       submit.click
  21:     
  22:       #verifiação se o resultado era o que esperavamos.
  23:       assert_equal("Software@test", driver.title)
  24:     ensure
  25:       driver.close
  26:       driver.quit
  27:     end
  28:   end
  29: end



Este teste pode ser corrido a partir da linha de comandos do seguinte modo



ruby Hello.rb


Este tutorial foi feito baseando-se no ruby, mas facilmente poderia de ser adaptado a outras linguagens como Java, C#, etc. No caso de Java podem seguir um conjunto de tutoriais bastante pormenorizados para a criação de um ambiente de trabalho. Este tutorial pode ser encontrado aqui. Para melhor compreender o selenium sugiro que deem uma vista de olha na documentação oficial que pode ser encontrada aqui. Outro bom recurso é o livro Selenium Simplified do Alan Richardson.

Bom, até à próxima.

terça-feira, 20 de novembro de 2012

Testes unitários - Praticas & Técnicas

 

Testes unitários são um método de verificação de unidades individuais de código fonte. Uma unidade pode ser considerado uma classe por completo ou apenas uma função ou procedimento.

Os testes unitários devem ser o maior grupo de testes desenvolvido para um produto. O Mike Cohen criou à alguns anos atrás uma estrutura sob a forma de uma pirâmide, do que deve ser a importância dada a cada grupo de testes. A pirâmide é semelhante à que se encontra na imagem abaixo. Podem encontrar mais informação sobre esse assunto nesse artigo.

g3028

A utilização de testes unitários é bastante benéfica para qualquer que seja o produto desenvolvido. De seguida aponto aquilo que eu considero serem os principais benefícios da sua utilização. É apenas uma opinião pessoal e não reflete necessariamente a opinião da comunidade.

Principais benefícios da utilização de testes unitários

  • A abordagem unitária (ou modular) usada por este tipo de testes elimina a dependência de outros módulos externos.
  • Conseguimos testar partes de um projeto sem existir a necessidade de todas as partes estarem concluídas ou disponíveis.
  • A equipa de desenvolvimento consegue identificar e corrigir o problema muito rapidamente, uma vez que o tempo que passou entre o momento de criação e o momento em que foi encontrado o erro é muito pouco.
  • É muito mais fácil obter uma larga cobertura do código testado permitindo assim perceber e distinguir qual o código exercitado e qual o código que nunca foi usado. O que pode acontecer porque ainda não criamos testes que façam uso dessa zona do código ou porque detectamos uma zona morta, isto é, um pedaço de código que independentemente das condições iniciais nunca será atingido.
  • Os custos associados à criação e à execução destes testes são sempre menores quando comparados com os custos de testes funcionais.
  • Permite a fácil e rápida inclusão num sistema de continuos integration.
  • A rápida eliminação dos defeitos de software leva por um lado a melhoria global dos produtos que se está a desenvolver, mas por outro lado garantir que cada módulo funciona corretamente antes de o começarmos a utilizar em conjunto com outros facilita muito o seu processo de integração num produto porque garante que os erros aqui encontrados irão corresponder a problemas de integração e não problemas na construção dos vários módulos.

Muitas das vezes as equipas de trabalho, não querem escrever os testes unitários porque não percebem o que estes são importantes ou porque têm ideias pré-concebidas sobre o assunto. Ideias como “é perda de tempo”, ou “se existirem bugs eles serão apanhados mais à frente” ou ainda “são testes a equipa de testes que os crie” entre muitas outras. De seguida apresentam-se alguns desses principais equívocos e o porque desse ponto de vista estar errado.

Alguns equívocos ou ideias tipicamente erradas acerca de testes de software :

  • Um dos principais equívocos para a não criação de testes unitários é acreditar que os bugs irão ser todos apanhados na fase de testes de integração. Mas quando os erros chegam a esta fase o tempo de resolução é sempre muito mais elevado porque já não identificamos de modo tão exato a localização do problema e temos de andar à procura do mesmo através de várias camadas ou através de vários módulos. Por outro lado é muito mais fácil atingir as diferentes possibilidades de utilização de um método através da sua utilização direta do que tentar fazer o mesmo a partir da utilização destes por outros módulos.
  • Outro grande equívoco para a não criação de testes unitários é a de que os programadores acreditam que irão perder muito tempo. Uma grande parte deles acreditam que são bons programadores e que nunca cometem erros. Mas o desenvolvimento de software é uma operação bastante complexa, e errar é uma condição da natureza humana.
  • Os erros criados são de algum modo triviais ou pouco importantes. Mas colectivamente estes podem resultar num período excessivo de integração resultando por fim numa ultrapassagem dos tempos definidos para a entrega do projeto.
    Percebendo a importância dos mesmos é necessários começar a criá-los. E existem alguns aspectos que quando tidos em conta ajudam a melhorar a qualidade dos testes desenvolvido e por consequência a sua eficácia. Dou apenas alguns exemplos daquilo que me parece importante.

Algumas boas práticas para a criação de Testes Unitários:

  • Garantir que cada teste é independente dos restantes. Um bom modo de despistar este tipo de dependências é correr sempre os testes por uma ordem aleatória. De modo a que independentemente da ordem o resultado de cada teste não pode variar.
  • Cada comportamento deve apenas ser especificado por um único teste de modo a evitar que mudanças no comportamento da aplicação obriguem à alteração de muitos testes.
  • Os vários módulos devem ser testados de forma independente de modo a evitar uma sobreposição entre os testes e o comportamento.
  • Cada teste criado deve ser de fácil leitura de modo a facilitar o trabalho a elementos que continuem o trabalho algum tempo depois. Estes devem ter um nome elucidativo da sua função, e na implementação do mesmo deve ser claro o que é que está a ser testado.
  • Antes de iniciar uma alteração importante garantir que todos os testes unitários estão a passar. De modo a termos a certeza que após as alterações ao software os possíveis problemas existentes foram por nós introduzidos.
  • Garantir que os bugs encontrados durante esta fase são corrigidos antes de iniciarmos a fase seguinte.
  • Criar um ambiente limpo para a execução de cada teste. O resultado do teste anterior não pode influenciar o resultado do teste atual apenas porque de algum modo correu mal ou deixou o ambiente em mau estado. É uma boa prática cada teste ante de executar o “core” da sua atividade colocar o ambiente numa estado conhecido e fiável. Esta situação vai garantir que os resultados obtidos são de confiança.
  • Devem ser utilizados stubs ou mocks de modo a testar de forma mais eficiente. Estes dois termos embora bastante semelhantes e muitas vezes confundidos são diferentes. Uma boa distinção entre ambos pode ser encontrado neste excelente artigo do Martin Fowler (Mocks aren’t Stubs).
  • Devem ser feitas alterações ao código usado nos testes unitários sempre que forem desenvolvidas melhorias no código alvo dos testes.

     

    Uma abordagem adequada para com os testes unitários proporciona uma rápida detecção de erros de software, numa fase em que a sua correção será bastante rápida dado que a implementação ainda está bastante fresca na mente do programador. A eficiência e a qualidade são melhor representados quanto mais cedo no ciclo de desenvolvimento estiverem os testes. Uma boa utilização de estratégias de testes, uma gestão adequada do processo de testes, e um uso adequado de ferramentas de teste ajudam a maximizar o esforço de teste. Todas estas opções ajudam a um processo de desenvolvimento de boa qualidade que beneficiam a empresa e o produto desenvolvido.

Existe um largo conjunto de ferramentas que permitem a rápida criação de testes unitários. Para algumas das linguagens de programação mais conhecidas como o Java e o C# as seguintes utilitários podem ser considerados válidas opções para a criação de testes unitários.

  • TestNG (para ser usado em Java)
  • JUnit (para ser usado em Java)
  • nUnit (para ser usado em .Net)

Por muitas das vezes que tentamos criar testes existem dependências que não estão concluídas, ou partes do software as quais não nos queremos preocupar. Podemos para esses casos criar stubs e mocks para simular esse comportamento. Alguns exemplos de aplicativos desse género são os abaixo indicados:

    Existem muitos mais recursos para além dos aqui referidos, usei apenas aqueles que já usei e que são de algum modo de utilização livre.
A utilização de testes unitários não irá apanhar todos os erros de software existentes no programa. Os testes unitários testam apenas as várias unidades de modo individual. Assim possíveis erros de integração, problemas de desempenho, problemas de usabilidades entre outros tipos de problemas não irão ser apanhados por este tipo de testes. è sempre necessário articular os testes unitários com outras atividades de teste de modo a obtermos uma cobertura adequado do produto desenvolvido.
      Existem muitos recursos na Web que ajudam a tentar compreender como é que criamos e para que servem os testes unitários, mas aqueles que mais me ajudaram a compreender o tema foram os que eu indique abaixo.

    Bibliografia

    http://www.codeproject.com/Articles/5772/Advanced-Unit-Test-Part-V-Unit-Test-Patterns

    http://xunitpatterns.com

    http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/

    http://blog.goyello.com/2011/10/06/three-pillars-of-unit-tests/

    http://www.youtube.com/watch?v=szVYZOvtJks&feature=related

    http://martinfowler.com/articles/mocksArentStubs.html

    http://readwrite.com/2008/08/13/12_unit_testing_tips_for_software_engineers

    Bom, até à próxima.