2014-10-15 1 views
2

Я только недавно начал создавать тесты Geb/Spock для нашего веб-приложения и, учитывая мои ограниченные знания Geb, Spock и всех вещей Groovy - столкнулись с ошибкой, которая не имеет никакого смысла (учитывая мой опыт Java).Тесты Geb + Spock не могут повторно использовать контент c'tors, сбой с MissingMethodException

Итак, вот модуль в вопрос:

import geb.Module 
import geb.navigator.Navigator 

class Tile extends Module { 

    def currencyPair 

    static content = { 

     amount { 
      $(".currencypair-span", text: containsWord(currencyPair)) 
       .parent().parent() 
       .find(".tile-amount-setup").find("input") }  
    }  
} 

Ничего экстраординарного там.

Вот страница (я не знаю, как это все совмещается, хотя):

import geb.Page 

class TraderApp extends Page { 

    static url = "./" 

    static at = { title == "FOOBARTrader" } 

    static content = { 
     tile { instrument -> module Tile, currencyPair: instrument } 
    } 

} 

Вот тест спецификации:

import geb.spock.GebSpec 

import spock.lang.* 
import org.openqa.selenium.Keys 

class BugSpec extends SbkSpec { 

    final CURPAIR = "FOOBAR" 

    def setupSpec() { 
     accountSelector.dropDown.click() 

     accountSelector.dropDown << Keys.chord(Keys.CONTROL, "a") 
     accountSelector.dropDown << "FxOnly" 
     accountSelector.dropDown << Keys.ENTER 

     waitFor() { accountSelector.dropDown.value() == "FXOnly" } 

     tileLayout("Majors").tab.click() 
    } 

    def "test1"() { 
     given: 
      tile(CURPAIR).amount.click() 

     when: 
      println("foo") 

     then: 
      waitFor {true}    
    } 

    def "test2"() { 
     given: 
      tile(CURPAIR).amount.click() 

     when: println("bar") 

     then: 
      waitFor {true} 
    } 
} 

Теперь проблема в том, что первый тест будет выполняться и проходить, но при выполнении второго теста JVM сообщит об исключении NoSuchMethodException для метода tile().

Как это возможно? Я ценю, что Groovy - динамический язык, но где этот метод исчезает?

Это делает невозможным повторное использование контента в нескольких различных тестах, поскольку содержимое, о котором идет речь, недоступно после выхода из первого теста, который его использует.

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running BugSpec 
Starting ChromeDriver (v2.10.267521) on port 32075 
Only local connections are allowed. 
foo 
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 19.425 sec <<< FAILURE! 
test2(BugSpec) Time elapsed: 0.175 sec <<< ERROR! 
groovy.lang.MissingMethodException: No signature of method: geb.navigator.NonEmptyNavigator.tile() is applicable for argument types: (java.lang.String) values: [FOOBAR] 
Possible solutions: size(), tail(), filter(java.lang.String), find(java.lang.String), is(java.lang.String), take(int) 
     at geb.navigator.NonEmptyNavigator.methodMissing(NonEmptyNavigator.groovy:463) 
     at geb.content.NavigableSupport.methodMissing(NavigableSupport.groovy:123) 
     at geb.Browser.methodMissing(Browser.groovy:194) 
     at geb.spock.GebSpec.methodMissing(GebSpec.groovy:51) 
     at BugSpec.test2(BugSpec.groovy:35) 

Помогите, пожалуйста?

EDIT:

Согласно ответу ERDI, в комплект входит также суперкласс BugSpec:

import geb.spock.GebReportingSpec 

class SbkSpec extends GebReportingSpec { 

    def setupSpec() { 
     def environment = System.getProperty("geb.env"); 

     given: 
      to AuthApp     

     expect: 
      at AuthApp     

     when: 
      def username = browser.getConfig().getRawConfig().get("username") 
      def password = browser.getConfig().getRawConfig().get("password") 

      login.username.value(username) 
      login.password.value(password) 

      login.loginButton.click() 

     then: 
      at TraderApp 
      and: 
       waitFor() { accountSelector.dropDown.value() == "FOOBAR-ACCOUNT" } 
    } 

    def cleanupSpec() { 
     given: 
      at TraderApp 
     then: 
      logout.logoutButton.click() 
    }   
} 
+0

В документах такого метода нет: http://www.gebish.org/manual/current/api/geb/Page.html. Почему вы утверждаете, что он «исчезает»? Вызов метода 'tail' перенаправляется на экземпляр этого интерфейса: http://www.gebish.org/manual/current/api/geb/navigator/Navigator.html через этот класс: http://www.gebish.org /manual/current/api/geb/content/PageContentSupport.html – Opal

+0

Пожалуйста, снова прочитайте вопрос, @Opal. Первый вызов 'tile()' преуспевает и первый тест проходит (обратите внимание на '' foo' ', напечатанный на выходе 'TESTS'), но второй вызов того же метода завершился неудачно, выбрасывая исключение. Как можно вызвать работу, но второй вызов того же метода утверждает, что метод не существует? – Zyxoas

+0

Да, действительно. Интересно. Есть ли шанс воспроизвести? – Opal

ответ

3

При использовании встроенных в базе GebSpec/GebReportingSpec ГЭБА депеш метод пропущенных звонков в page свойство spec's browser. Что-то (не видя больше кода, невозможно сказать, что именно) устанавливает это свойство в экземпляр TraderApp перед первым тестом. Geb воссоздает экземпляр browser между каждым тестом, что означает, что экземпляр страницы сбрасывается до значения по умолчанию, которое является экземпляром Page. Если установить страницу, чтобы быть экземпляром TraderApp тогда tile() метода будет найдено:

def "test2"() { 
    given: 
     page TraderApp 
     tile(CURPAIR).amount.click() 

    when: println("bar") 

    then: 
     waitFor {true} 
} 

Было бы намного легче рассуждать о вещах и помочь, если вы предоставили код для цепи всех суперклассов BugSpec вверх к той, которая распространяется GebSpec/GebReportingSpec. Выглядит так, как будто вы имеете дело с запахом, где тесты настроены так, как их порядок исполнения имеет значение.

+0

Привет, @ Erdi. Большое спасибо за отзывы. Я обновил вопрос, чтобы включить код для суперкласса BugSpec. :-) Кроме того, предлагаемое исправление (добавление строки 'TraderApp'), похоже, не устранило проблему. Надеюсь, дополнительный код поможет. – Zyxoas

+0

Ах, я соврал. Трюк работал отлично! Мне пришлось добавить строку ко всем тестам, а также метод 'setupSpec'' BugSpec'. : -D Я приму свой ответ, но, надеюсь, вы могли бы выяснить, что проблема в суперклассе (запах кода), пожалуйста? – Zyxoas

+2

Я не думаю, что там есть какой-то запах кода. Весь ваш код в 'setupSpec()' s должен фактически находиться в 'setup()' методах. Это связано с тем, что состояние браузера сбрасывается между методами тестирования, и все куки-файлы удаляются из него. Вот почему вы всегда хотите войти в систему и явно перейти на страницы, а не ожидать, что браузер будет в каком-либо конкретном состоянии после предыдущего теста. Некоторые люди считают, что это чрезмерно и пытаются управлять состоянием браузера, но это, по сути, приводит к взаимозависимым и хрупким испытаниям. Я лично считаю, что вы должны начать каждый тест из чистого состояния. – erdi

 Смежные вопросы

  • Нет связанных вопросов^_^