2016-04-20 10 views
1

Ich arbeite an einer Website und versuche, es mit Selenium und jUnit zu testen. Ich bekomme trotz meiner Bemühungen Rennbedingungen zwischen dem Test und der Seite. Das Frontend der Site ist HTML und jQuery. Das Backend (über AJAX) ist PHP.Unvorhersehbares Verhalten mit Selenium und jUnit

Die Website

Ich habe zwei gewünschte Texteingabefelder (Jahr und Alter), sowie einige andere, die ich nicht in den Tests zu ändern, die Probleme geben. Sobald beide Texteingaben nicht leer sind, erfolgt ein AJAX-Aufruf an das Backend. Dies wird 0+ Ergebnisse zurückgeben. Wenn 0 Ergebnisse zurückgegeben werden, erhält ein Ergebnisdiv auf dem Bildschirm einen Text, der besagt, dass keine Ergebnisse vorhanden sind. Wenn> 0 Ergebnisse zurückgegeben werden, wird eine Tabelle in das Ergebnis-Div geschrieben, das die Ergebnisse anzeigt.

Ich möchte nicht, dass die Website z. Vor dem AJAX-Aufruf wird der 4-stellige Wert des Jahres eingegeben, da es sich um eine alte Geschichte handeln könnte (ja, wirklich). Sobald beide nicht leer sind, sollte der Anruf getätigt werden. Wenn Sie langsam eingeben, bedeutet dies, dass z. 2015 wird Aufrufe für Jahr = 2, Jahr = 20, Jahr = 201 und Jahr = 2015 auslösen. (Dies ist OK.)

Der Test

Ich bin mit Seitenobjekte - eine für die Eingänge und einen für den Ausgang. Zu Beginn des Tests warte ich auf eine Eingabeaufforderung auf dem Bildschirm (bitte geben Sie einige Daten ein), da diese von JavaScript generiert wird, das den Status der Eingabefelder überprüft - damit ich weiß, dass die Seite geladen wurde und JavaScript hat Lauf.

Das Warten auf eine Eingabeaufforderung erfolgt unmittelbar nachdem das Seitenobjekt für die Ausgabe erstellt wurde. Dies ist die entsprechende Methode in dem Seitenobjekt:

// Wait until the prompt/help text is displayed. Assumes that the prompt text always contains the word "Please" 
public void waitForText() { 
    wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("resultContainer"), "Please")); 
} 

Das Verfahren zum Einstellen des Jahres ist

public void setYear(String year){ 

    WebElement yearField = driver.findElement(By.id(yearInputId)); 

    if (yearField == null) { 
     // This should never happen 
     Assert.fail("Can't find year input field using id " + yearInputId); 
    } else { 
     yearField.sendKeys(new String [] {year}); 
     driver.findElement(By.id(ageInputId)).click(); // click somewhere else 
    } 
} 

und es gibt eine entsprechenden für das Alter.

Ich habe eine Reihe von Methoden, die auf Dinge warten, die das Problem nicht zu verhindern scheinen (unten). Diese Dinge tun, wie warten auf die aktuellen Ergebniswerte verschieden sein können, aus einer früheren Schnappschuss davon, warten Sie auf eine bestimmte Anzahl von Ergebnissen zurückgegeben werden usw.

schaffe ich einen Treiber für Chrome wie folgt:

import org.openqa.selenium.chrome.ChromeDriver; 
// ... 
     case CHROME: { 
      System.setProperty("webdriver.chrome.driver", "C:\\path\\chromedriver.exe"); 
      result = new ChromeDriver(); 
      break; 
     } 

Das Problem

einen Teil der Zeit, arbeiten die Dinge in Ordnung. Manchmal werden beide Eingaben vom Test mit sinnvollen Werten gefüllt, aber die Meldung "Es gibt 0 Ergebnisse" wird angezeigt. Manchmal bleibt der Test während des Einfüllens der Eingaben hängen. Es scheint in Ordnung zu sein, wenn ich mit Firefox teste, aber Chrome schlägt oft fehl.

Die Tatsache, dass es unvorhersehbares Verhalten gibt, deutet darauf hin, dass ich nicht alle Dinge kontrolliere, die ich brauche (und/oder meine Versuche, Dinge zu kontrollieren, sind falsch). Ich kann nicht sehen, dass ich irgendetwas besonders Seltsames mache, also muss jemand diese Art von Problemen schon einmal getroffen haben.

Gibt es ein Browserproblem, das ich nicht anspreche? Gibt es etwas, das ich beim Einstellen der Werte falsch mache? Gibt es etwas, das ich in meiner Testchoreographie falsch mache?

Antwort

1

Wenn Sie mit der Eingabe beginnen, wird das Skript möglicherweise noch geladen oder es liegt ein ausstehender Ajax-Aufruf vor, wenn Sie mit dem nächsten Feld oder der nächsten Validierung beginnen. Sie könnten versuchen, die Anrufe mit einem niedrigen Niveau Skript zu synchronisieren:

const String JS_WAIT_NO_AJAX = 
    "var callback = arguments[0]; (function fn(){ " + 
    " if(window.$ && window.$.active == 0) " + 
    "  return callback(); " + 
    " setTimeout(fn, 60); " + 
    "})();"; 

JavascriptExecutor js = (JavascriptExecutor)driver; 
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS); 

js.executeAsyncScript(JS_WAIT_NO_AJAX); 
driver.findElement(By.Id("...")).sendKeys("..."); 

js.executeAsyncScript(JS_WAIT_NO_AJAX); 
driver.findElement(By.Id("...")).click(); 
+0

Wie oft die Art und Weise, das eigentliche Problem war etwas anderes (wenn der AJAX-Aufruf das Datum an das hinteren Ende früh gesendet, das führen könnte Abfragen mit einer Datumszeichenfolge von zB '16 -01-01 ', die ich nicht auf' 0016-01-01 'aufgefüllt habe, um zu vermeiden, dass MySQL' 2016-01-01 'ist. Danke dafür - sehr nützlich. –

Verwandte Themen