Selenium RC: esegui test in più browser automaticamente
-
03-07-2019 - |
Domanda
Quindi, ho iniziato a creare alcuni test di unità Ruby che utilizzano Selenium RC per testare la mia app Web direttamente nel browser. Sto usando il Selenum-Client per ruby. Ho creato una classe base per tutti i miei altri test al selenio da ereditare.
Questo crea numerose istanze di SeleniumDriver e tutti i metodi mancanti vengono chiamati su ogni istanza. Questo essenzialmente esegue i test in parallelo.
In che modo altre persone hanno automatizzato questo?
Questa è la mia implementazione:
class SeleniumTest < Test::Unit::TestCase
def setup
@seleniums = %w(*firefox *iexplore).map do |browser|
puts 'creating browser ' + browser
Selenium::SeleniumDriver.new("localhost", 4444, browser, "http://localhost:3003", 10000)
end
start
open start_address
end
def teardown
stop
end
#sub-classes should override this if they want to change it
def start_address
"http://localhost:3003/"
end
# Overrides standard "open" method
def open(addr)
method_missing 'open', addr
end
# Overrides standard "type" method
def type(inputLocator, value)
method_missing 'type', inputLocator, value
end
# Overrides standard "select" method
def select(inputLocator, optionLocator)
method_missing 'select', inputLocator, optionLocator
end
def method_missing(method_name, *args)
@seleniums.each do |selenium_driver|
if args.empty?
selenium_driver.send method_name
else
selenium_driver.send method_name, *args
end
end
end
end
Funziona, ma se un browser fallisce, l'intero test fallisce e non c'è modo di sapere su quale browser ha fallito.
Soluzione
Hai provato Selenium Grid ? Penso che crei un rapporto di sintesi piuttosto buono che mostri i dettagli di cui hai bisogno. Potrei sbagliarmi, poiché non l'ho usato per un bel po '.
Altri suggerimenti
Ho finito per modificare il protocollo.rb di Selenium per generare un AssertionFailedError
sia con @browser_string
che con il messaggio restituito da Selenium RC se la risposta non è iniziata con " OK " ;. Ho anche modificato il metodo http_post
per restituire l'intero corpo della risposta e method_missing
per restituire un array di valori di ritorno per l'invio di comandi get_X al Selenium RC.
Aggiungi questo codice al codice nella domanda e dovresti essere in grado di vedere quali affermazioni falliscono su quali browser.
# Overrides a few Driver methods to make assertions return the
# browser string if they fail
module Selenium
module Client
class Driver
def remote_control_command(verb, args=[])
timeout(default_timeout_in_seconds) do
status, response = http_post(http_request_for(verb, args))
raise Test::Unit::AssertionFailedError.new("Browser:#{@browser_string} result:#{response}") if status != 'OK'
return response[3..-1]
end
end
def http_post(data)
http = Net::HTTP.new(@server_host, @server_port)
response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
#return the first 2 characters and the entire response body
[ response.body[0..1], response.body ]
end
end
end
end
#Modify your method_missing to use seleniums.map to return the
#results of all the function calls as an array
class SeleniumTest < Test::Unit::TestCase
def method_missing(method_name, *args)
self.class.seleniums.map do |selenium_driver|
selenium_driver.send(method_name, *args)
end
end
end
Disclaimer: non un esperto di selenio.
Vuoi solo sapere quale browser non è riuscito o vuoi eseguire il test su tutti i browser e quindi segnalare gli errori totali al termine?
Il primo è piuttosto semplice se si memorizzano i driver per hash nella propria configurazione. (Sono sicuro che c'è un modo stravagante per farlo con Hash.inject, ma sono pigro.)
@seleniums = {}
%w(*firefox *iexplore).each do |browser|
puts 'creating browser ' + browser
@seleniums[browser] = Selenium::SeleniumDriver.new("localhost", 4444, browser, "http://localhost:3003", 10000)
end
Quindi cambia la tua funzione principale per modificare le eccezioni per includere il nome del driver utilizzato, qualcosa del tipo:
@seleniums.each do |name, driver|
begin
driver.send method_name, *args
rescue Exception => ex
raise ex.exception(ex.message + " (in #{name})")
end
end
Dovresti avvicinarti.
devi trattare ogni test in modo indipendente. Quindi, se un test fallisce, continuerà a testare altri test. Scopri phpunit e selenium rc