2010-06-24 5 views
4

Je suis en train de tester une application django avec du sélénium, et une de mes pages utilise le jquery ui tabs element. L'un des onglets contient un tableau simple répertoriant certains utilisateurs, et est chargé via ajax. Lorsque vous utilisez l'application, l'onglet fonctionne très bien, mais lors de l'automatisation du test avec du sélénium, l'onglet ne semble pas charger son contenu! J'écris les tests moi-même en python. Au début, j'utilisais la méthode click de sélénium RC, mais comme je l'ai appris d'un test précédent, c'est plutôt bogué quand il s'agit de balises d'ancrage, donc j'ai eu recours à la solution que j'ai utilisée auparavant: wait_for_condition méthode et explicitement appelé l'événement de clic onglet (et même l'événement de chargement!) et néanmoins l'onglet était encore ne fonctionne pas!

Je suis au désespoir ici, la majorité de mes tests dépendent de cette page et près de la moitié d'entre eux sont sur cette table, mais, hélas, il semble que le sélénium vole le javascript! (J'ai d'autres tests dans la classe, et ils fonctionnent très bien, donc rien de bizarre ne se passe au niveau du serveur, ça semble être un problème causé par le sélénium du côté client) Mon code de test est similaire à ceci:Comment tester les jquery ajax avec du sélénium?

class TestMyApp(TransactionTestCase): 
urls = 'myapp.test_urls' 

def setUp(self): 
    self.verificationErrors = [] 
    self.selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/") 
    self.selenium.start() 
    #self.selenium.set_speed(2000) 
    self.selenium.window_maximize() 
def test_users_list(self): 
    """Test that an app's users are correctly listed""" 
    sel = self.selenium 
    users = [] 
    for u in range(settings.FREE_USER_LIMIT/2): 
     users.append(self.app.users.create(name="testUser_%s"%uuid4())) 

    sel.open("/")   
    sel.wait_for_page_to_load("30000") 
    sel.wait_for_condition('selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("select",1);\ 
    selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("load",1);', 
          3000) 
    for user in users: 
     try: self.failUnless(sel.is_text_present(user.name)) 
     except AssertionError, e: self.verificationErrors.append(str(e)) 
     try: self.failUnless(sel.is_text_present(str(user.added.date()))) 
     except AssertionError, e: self.verificationErrors.append(str(e)) 
def tearDown(self): 
    self.selenium.stop() 
    self.assertEqual([], self.verificationErrors) 

Répondre

5

Ceci pourrait être un certain nombre de choses. Il se pourrait que Selenium ait du mal à cliquer sur l'ancre, mais je n'ai pas entendu parler de ce problème et cela semble moins probable. Il semble que la méthode click() renvoie OK, elle ne vous donne pas "element not found", n'est-ce pas? Lorsque vous cliquez sur l'onglet jquery javascript ne fait pas ce qui est attendu. Dans mon expérience, cela revient généralement au même problème - puisque Selenium s'exécute très rapidement, quand javascript rend des parties de la page et effectue le DOM de manière continue parfois quand Selenium va interagir avec des parties dynamiquement générées de la page (par exemple tab), la pièce avec laquelle elle interagit dépend d'une autre pièce qui n'a pas encore été complètement chargée. Il est probable que le chargement complet se fasse en quelques microsecondes, mais le sélénium est trop rapide. Vous le comprenez déjà bien sûr, vous avez la bonne idée avec la condition wait_for à la recherche des onglets à charger. Je suppose que ce n'est probablement pas assez long. Vous devez trouver une évaluation pour faire dire que tout le contenu des onglets de l'interface utilisateur est chargé et rendu. Est-ce que l'API des onglets a des rappels que vous pouvez ajouter pour définir une variable "chargement terminé" ou est-ce qu'elle expose une variable comme ça? Si vous ne savez pas exactement à quel moment les onglets de l'interface utilisateur sont prêts à être cliqués, ce qui peut être difficile, vous pouvez recourir à des pauses pour vous assurer que la partie de la page est prête à être utilisée. vous interagissez avec elle. Je ne vois aucun problème dans le sommeil (2), ou même dans le sommeil (5), etc. dans le code s'il est nécessaire de le faire fonctionner. Une façon de tester que c'est vraiment ce qui se passe est de lancer le scénario dans l'interpréteur interactif (il faut aimer Python, ça ne sert à rien en Java). Collez le code ligne par ligne pour accéder au point de panne, ou commentez l'appel selenium.stop() dans votre méthode de démontage et tout code de test après le point de panne, de sorte qu'il laisse la fenêtre de sélénium ouverte et quitte. Ensuite instancier un objet de sélénium dans le interpretter interactif et pirater la session ouverte:

selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/") 
selenium.sessionId = "0asdd234234023424foo" #Get this from the Se window 

... pour obtenir le contrôle interactif de la fenêtre. Ensuite, vous pouvez voir à propos de faire le selenium.click() ou faire des appels selenium.get_eval('...js...') pour enquêter sur le paysage javascript à ce moment-là. Je suppose que lorsque vous faites cela, le click() fonctionnera bien lorsque vous le saisissez, car au moment où vous avez chargé la session et que vous aurez à taper selenium.click('blah_tab_locator'), les onglets de l'onglet seront tous chargés et prêts à partir. C'est juste que lorsque Python fait les appels, il le fait trop vite pour le navigateur quand il y a ces rendus dynamiques. Si le clic fonctionne correctement lorsque vous le faites manuellement via du sélénium comme celui-ci, alors vous savez qu'il s'agit d'un problème de synchronisation. Trouvez le bon wait_for_condition ou condescendez vers un python sleep(). Sinon, si le clic continue de ne pas fonctionner lorsque vous faites cela, c'est probablement un problème avec le localisateur utilisé.L'onglet UI a un clic ou une moustache ou un focus ou une sorte de gestionnaire d'événement sur une partie de la structure de l'onglet, peut-être il s'agit de trouver la bonne partie de l'onglet à cliquer ou le bon événement à déclencher. Si ce n'est pas le cas, cela pourrait peut-être être une sorte d'interaction étrange entre Selenium et Jquery UI, mais cela me surprendrait et je serais curieux de savoir. Faites un tour avec get_eval() pour voir ce qui se passe dans le javascript si c'est le cas. Cela me semble un problème de synchronisation.

+0

ipython est idéal pour cela, btw. http://ipython.scipy.org/moin/ – Purrell

+1

Nice, j'ai effectivement installé ipython il y a quelques jours et c'est vraiment cool! Donc, j'ai fait ce que vous dites, je l'ai pris étape par étape patiemment et j'ai découvert que c'était, en fait * ma * faute: pour les tests j'utilisais un URLConf personnalisé (mappage des urls en django) et l'appel ajax augmentait -silently- un 404, donc l'élément n'a jamais vraiment apparu! Votre réponse est excellente, et va sûrement m'aider avec des problèmes similaires, merci! – lfborjas

+0

:) Ouais pas de problème du tout, je suis content que cela ait aidé. J'ai été dans la même situation des dizaines (des centaines?) De fois alors je sais ce que c'est. Ce genre de chose peut arriver fréquemment, alors j'essaie vraiment de minimiser le temps de dépannage en faisant très attention, mais le truc de débogage interactif d'ipython fait des miracles et fait gagner du temps quand les caprices inévitables arrivent. J'ai vu des ateliers d'ingénierie qui essayent de faire des suites de test de Se à Java ... ouf, soyez heureux pour Python l'interprète! À la votre! – Purrell

Questions connexes