O desenvolvimento de aplicações web tornou-se extremamente popular nos últimos anos. Garantir o bom funcionamento desses sistemas considerando a grande variedade de browsers existentes, entretanto, pode causar uma grande dor de cabeça (olá, Internet Explorer!). Diversas ferramentas foram criadas para auxiliar nessa tortuosa função e, entre elas, está o Selenium.
Com o Selenium é possível automatizar diferentes tipos de testes necessários para a manutenção do ciclo de vida de um software, tais como testes de aceitação e testes funcionais (ainda nesta redação, veremos como utilizá-lo em conjunto com testes unitários). Além disso, a ferramenta permite a automatização de praticamente qualquer tarefas repetitiva que precisamos realizar na web (exemplos por conta de sua imaginação).
Selenium automates browsers. That’s it! — SeleniumHQ
Podemos utilizar o Selenium através de sua IDE ou por uma client API. De forma geral, os comandos definidos são enviados para o Selenium WebDriver que, os repassa para o browser desejado e, se necessário, retorna os resultados. Aqui, iremos utilizá-lo através da API em Python. Vamos lá!
Preparando o ambiente — setup:
- Antes de continuar certifique-se de ter instalado em seu computador o Python 3, pip e o virtualenv ($ pip install virtualenv). Os passos abaixos são específicos para Linux (usuários Windows podem consultar a documentação aqui).
1. Inicialmente, crie e ative um ambiente virtual:
$ virtualenv -p python3 myenv
$ cd myenv
$ source bin/activate
2. Instale o Selenium com o pip:
$ pip install selenium
3. Baixe o driver do browser em que você deseja executar os testes. Nesse exemplo iremos utilizar o Firefox, outros drivers são listados na tabela abaixo.
$ wget https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz && tar -xvzf geckodriver-v0.24.0-linux64.tar.gz && rm geckodriver-v0.24.0-linux64.tar.gz
4. Adicione o driver a varíavel do sistema PATH ou mova-o para a pasta bin do virtualenv:
$ mv geckodriver bin/
Partiu automatizar!
Vamos fazer um programa bem simples que irá realizar uma busca no Google, printar o link dos primeiros resultados e tirar um screenshot da página. Para tal, crie um arquivo Python qualquer (e.g. gsearch.py) e cole o seguinte trecho de código:
#!/usr/bin/env python from selenium import webdriver from datetime import datetime # cria uma nova sessao no browser browser = webdriver.Firefox() browser.maximize_window() # navega para a home page do Google browser.get(“http://www.google.com/”) # procura pelo elemento referente a searchbox search_field = browser.find_element_by_name(“q”) # envia a string @query para o element e realiza a busca query = “Test Driven Development” search_field.send_keys(query) search_field.submit() # espera até 3 segundos até o resultado ficar pronto browser.implicitly_wait(3) # procura pelos resultados results = browser.find_elements_by_class_name(“r”) # para cada resultado (<div>) procura a ancora (<a>) que contem o link da pagina print(“* {} primeiros resultados para a busca ‘{}’:”.format(len(results), query)) for index, r in enumerate(results): link = r.find_elements_by_tag_name(“a”)[0].get_attribute(“href”) print(“\t{:2d}. {}”.format(index + 1, link)) # tira um print da pagina now = datetime.now().strftime(‘%Y-%m-%d_%H-%M-%S’) browser.save_screenshot(‘search_screenshot-{}.png’.format(now)) # fecha a sessao com o browser browser.quit() |
Para rodar o exemplo utilize o comando $ python gsearch.py
Agora é só usar e abusar da criatividade para automatizar as tarefas do seu dia a dia no browser: procure pelo preço de algum produto em múltiplas lojas simultaneamente ou verifique se saiu um novo episódio da sua série preferida – é com você! 🙂
Dica: usuários Linux podem fazer uso do cron para agendar a execução de scripts!
Hora dos testes!
Com o Selenium é possível reproduzir todo o test suite de um sistema no ambiente real onde a aplicação web está rodando. Existem diferentes tipos de casos de teste que podem ser realizados com o apoio da ferramenta. Nesse exemplo iremos utilizar o Selenium em conjunto com o framework para testes unitários do Python, o unittest. O unittest é inspirado no famoso JUnit e está incluído como um módulo nativo na biblioteca padrão do Python.
Vamos definir dois testes, um teste para validar a abertura do menu ‘Publicações’ no site do PET-SI e outro para verificar se a busca por ‘PET Redação’ retorna algum resultado. Para tal, crie um arquivo (e.g. utest_1.py) e cole o código abaixo:
#!/usr/bin/env python from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By import unittest
class PetPage(unittest.TestCase): def setUp(self): self.browser = webdriver.Firefox() self.browser.implicitly_wait(10) self.browser.get(“http://coral.ufsm.br/pet-si/”)
def test_open_publicacoes_page(self): self.browser.find_element_by_xpath(“//a[text() = ‘Publicações’]”).click() self.assertIn(‘category/posts’, self.browser.current_url)
def test_search(self): self.browser.find_element_by_xpath(“//a[text() = ‘Publicações’]”).click() self.search_field = self.browser.find_element_by_id(“s”) self.search_field.send_keys(“PET Redação”) self.search_field.send_keys(Keys.ENTER) # submit query self.assertTrue(self.is_element_on_page(By.CSS_SELECTOR, ‘div.post’)) # check for results
def tearDown(self): self.browser.quit()
def is_element_on_page(self, how, what): try: self.browser.find_element(by=how, value=what) except: return False return True
if __name__ == ‘__main__’: unittest.main(verbosity=2) |
Rode o programa ($ python utest_1.py) e veja o resultado. Você deve ter percebido que uma nova instância do browser é aberta para cada um dos testes. Nem sempre esse comportamento é desejado (veja a necessidade da redundância nas linhas 15 e 19). Vamos melhorar um pouco nosso código fazendo uso de algumas anotações. Para tal, crie um arquivo (e.g. utest_2.py) com o código conforme segue abaixo:
… @classmethod def setUpClass(inst): inst.browser = webdriver.Firefox() inst.browser.implicitly_wait(10) inst.browser.get(“http://coral.ufsm.br/pet-si/”)
def test_01_open_publicacoes_page(self): self.browser.find_element_by_xpath(“//a[text() = ‘Publicações’]”).click() self.assertIn(‘category/posts’, self.browser.current_url)
def test_02_search(self): # não é necessário navegar para ‘Publicações’ novamente self.search_field = self.browser.find_element_by_id(“s”) self.search_field.send_keys(“PET Redação”) self.search_field.send_keys(Keys.ENTER) # submit query self.assertTrue(self.is_element_on_page(By.CSS_SELECTOR, ‘div.post’)) # check for results
@classmethod def tearDownClass(inst): inst.browser.quit() … |
Rode o código ($ python utest_2.py) e veja o resultado. É importante notar que os testes são executados de acordo com seus nomes (ordenação de strings padrão do Python – alfabeticamente + numericamente), por isso a adição do número do teste (01 e 02) garante a ordem de execução. É claro que isso é apenas uma alternativa, nestes casos seria mais inteligente não criar métodos independentes e sim um único caso de teste.
Por onde continuar?!
O Selenium possui diversas funcionalidades a serem exploradas, nessa redação apenas fizemos um overview geral da ferramenta. Aos interessados, seguem alguns tópicos para prosseguir os estudos na linha de testes automatizados:
- Behavior Driven Development: escreva cenários de testes poderosos e elegantes com o Cucumber (para Python veja o Behave).
- Selendroid: automatização de testes para aplicativos Android (nativos ou híbridos);
- castro: gravação da execução dos testes (muito útil em ambientes em que é necessário apurar a razão da falha de algum caso de teste);
- Robot Framework: Acceptance test-driven development (ATDD) e Robotic process automation (RPA).
REFERÊNCIAS
- SeleniumHQ. Selenium Documentation. (link)
- Python. unittest — Unit testing framework. (link)
- Read the Docs. Selenium with Python. (link)
- TechBeamers. Build A Selenium Python Test Suite From Scratch Using Unittest. (link)
- TechBeamers. Selenium Webdriver – 20 Coding Tips to Improve Quality. (link)
- CherCher Tech. Python Unittest Selenium. (link)
- DevMedia. Dominando o Selenium Web Driver na prática. (link)
- Medium. Top Tutorials To Learn Selenium For Beginners. (link)
- Medium. BDD, Cucumber and Selenium WebDriver based Test Automation Framework in Python. (link)
- IBM. Automated testing with Selenium and Cucumber. (link)
- The Tara Nights. Google Search Using Selenium And Python – Selenium Python Basics. (link)
- Sauce Labs. Selenium Tips: CSS Selectors. (link)
- Sauce Labs. Getting Started with Selenium for Automated Website Testing. (link)