2014-04-14 15 views
7

Java/Selenium kullanarak bir JavaScript API'sı test ediyorum.Selenium, JavaScript'in tamamlanması için beklemiyor mu?

Ben

JavaScript tarafında
executor.executeScript("setName('Hello');"); 
// Thread.sleep(2000); 
String output = (String)executor.executeScript("return getName()"); 
assertEquals(output, "Hello"); 

, bu bir zaman uyumsuz fonksiyonudur, Java tarafında bu komutlarla bu biraz zaman alacak ve değişken ayarlamak gerekiyordu.

function setName(msg) { 
    // simulate async call 
    setName(function(){name = msg;},1000); 
} 

Bu zaman uyumsuz fonksiyon assertEquals() yürütüldüğünde Java, bir sonraki satıra geçmeden önce tamamlamak için beklemek gerekir.

Java tarafında Thread.sleep() kullanmadan bunu gerçekleştirmenin herhangi bir yolu var mı?

Teşekkür

cevap

2

Selenium'dan, belirli bir koşul doğru olana kadar beklemesini kolayca isteyebilirsiniz; Tam olarak ne de bir alternatif olacaktır:

Ancak
new FluentWait<JavascriptExecutor>(executor) { 
    protected RuntimeException timeoutException(
     String message, Throwable lastException) { 
    Assert.fail("name was never set"); 
    } 
}.withTimeout(10, SECONDS) 
.until(new Predicate<JavascriptExecutor>() { 
    public boolean apply(JavascriptExecutor e) { 
    return (Boolean)executor.executeScript("return ('Hello' === getName());"); 
    } 
}); 

, o zaman temelde sadece kodlu tam olarak ne test ediyoruz, ve sizin setName aramadan önce name ayarlanmış olması halinde bunun dezavantajı, size cenneti' t tamamlanması için setName bekledi. Benim test kütüphanesinde

, bende bu var (gerçek zaman uyumsuz yerini setTimeout şim çağrıları): Ben de benzer şeyler için geçmişte yaptık bir şey şudur geri kalanında

window._junit_testid_ = '*none*'; 
window._junit_async_calls_ = {}; 
function _setJunitTestid_(testId) { 
    window._junit_testid_ = testId; 
} 
function _setTimeout_(cont, timeout) { 
    var callId = Math.random().toString(36).substr(2); 
    var testId = window._junit_testid_; 
    window._junit_async_calls_[testId] |= {}; 
    window._junit_async_calls_[testId][callId] = 1; 
    window.setTimeout(function(){ 
    cont(); 
    delete(window._junit_async_calls_[testId][callId]); 
    }, timeout); 
} 
function _isTestDone_(testId) { 
    if (window._junit_async_calls_[testId]) { 
    var thing = window._junit_async_calls_[testId]; 
    for (var prop in thing) { 
     if (thing.hasOwnProperty(prop)) return false; 
    } 
    delete(window._junit_async_calls_[testId]); 
    } 
    return true; 
} 

benim Kütüphane, daha sonra olacak bir şey ayarlamaya ihtiyaç duyduğumda, window.setTimeout yerine _setTimeout_ kullanıyorum. gerekirse waitForTest birden çok kez çağırabilir

// First, this routine is in a library somewhere 
public void waitForTest(JavascriptExecutor executor, String testId) { 
    new FluentWait<JavascriptExecutor>(executor) { 
    protected RuntimeException timeoutException(
     String message, Throwable lastException) { 
     Assert.fail(testId + " did not finish async calls"); 
    } 
    }.withTimeout(10, SECONDS) 
    .until(new Predicate<JavascriptExecutor>() { 
    public boolean apply(JavascriptExecutor e) { 
     return (Boolean)executor.executeScript(
      "_isTestDone_('" + testId + "');"); 
    } 
    }); 
} 

// Inside an actual test: 
@Test public void serverPingTest() { 
    // Do stuff to grab my WebDriver instance 
    // Do this before any interaction with the app 
    driver.executeScript("_setJunitTestid_('MainAppTest.serverPingTest');"); 
    // Do other stuff including things that fire off what would be async calls 
    // but now call stuff in my testing library instead. 
    // ... 
    // Now I need to wait for all the async stuff to finish: 
    waitForTest(driver, "MainAppTest.serverPingTest"); 
    // Now query stuff about the app, assert things if needed 
} 

Not, tüm zaman uyumsuz işlemler bitene kadar duraklatmak için bu testi gereken herhangi süresi: Sonra, benim selenyum testinde, ben böyle bir şey yapmak.

0

Ben selenyum yapar şüpheliyim. Sadece sayfanın tamamen yüklenmesini bekler, ancak bitirilecek bir betik değildir. Sonuç beklemek için kendi 'test adımınızı' tanımlamak isteyebilirsiniz (ve sayfa içeriklerini/betik durumunu sürekli olarak gözden geçirin), ancak testlerinizde erkeklerin komut dosyasında hata yapmaması için makul bir zaman ayarlaması yaptığınızdan emin olun.

İlgili konular