Selenium RC: Exécuter des tests dans plusieurs navigateurs automatiquement
-
03-07-2019 - |
Question
J'ai donc commencé à créer des tests unitaires Ruby utilisant Selenium RC pour tester mon application web directement dans le navigateur. J'utilise le Selenum-Client pour ruby. J'ai créé une classe de base pour tous mes autres tests sur le sélénium.
Ceci crée de nombreuses instances de SeleniumDriver et toutes les méthodes manquantes sont appelées sur chaque instance. Cela exécute essentiellement les tests en parallèle.
Comment d'autres personnes ont-elles automatisé cette opération?
Voici mon implémentation:
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
Cela fonctionne, mais si un navigateur échoue, tout le test échoue et il est impossible de savoir sur quel navigateur il a échoué.
La solution
Avez-vous essayé de la grille de sélénium ? Je pense que cela crée un très bon rapport de synthèse qui montre les détails dont vous avez besoin. Je me trompe peut-être, car je ne l'ai pas utilisé pendant un bon bout de temps.
Autres conseils
J'ai fini par modifier le protocole.rb de Selenium pour générer un AssertionFailedError
avec @browser_string
et le message renvoyé à partir de Selenium RC si la réponse n'a pas commencé par "OK". J'ai également modifié la méthode http_post
pour renvoyer l'ensemble du corps de la réponse et le method_missing
pour renvoyer un tableau de valeurs de retour permettant d'émettre des commandes get_X au Selenium RC.
Ajoutez ce code au code de la question pour que vous puissiez voir quelles assertions échouent sur quels navigateurs.
# 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
Avertissement: Ce n'est pas un expert en sélénium.
Voulez-vous simplement savoir quel navigateur a échoué ou voulez-vous exécuter le test sur tous les navigateurs, puis signaler le nombre total d'échecs une fois terminé?
Le premier est assez simple si vous stockez les pilotes par hachage dans votre configuration. (Je suis sûr qu'il existe une façon élégante de faire cela avec Hash.inject, mais je suis paresseux.)
@seleniums = {}
%w(*firefox *iexplore).each do |browser|
puts 'creating browser ' + browser
@seleniums[browser] = Selenium::SeleniumDriver.new("localhost", 4444, browser, "http://localhost:3003", 10000)
end
Modifiez ensuite votre fonction principale pour modifier les exceptions afin d'inclure le nom du pilote utilisé, par exemple:
@seleniums.each do |name, driver|
begin
driver.send method_name, *args
rescue Exception => ex
raise ex.exception(ex.message + " (in #{name})")
end
end
Devrait vous rapprocher.
vous devez traiter chaque test indépendamment. Donc, si un test échoue, il continuera à tester d’autres tests. Découvrez phpunit et sélénium rc