To be honest I don't remember where I saw that technique first, but it
is pretty useful.

On 21 April 2010 14:04, Gergely Brautigam <[email protected]> wrote:
> This is totally unrelated but i have to say that this:
>        if (["yes", "true"].contains(stopOnAssert)) {
> that's pretty awesome :D I never saw something like this or never have
> thought about it either. Where did you get this kind of checking?
> Gergely.
>
> 2010/4/21 Jonathan Share <[email protected]>
>>
>> I already have calls to the following method scattered all over the
>> place whenever I expect the page to have changed (also gives me a way
>> of stepping through a test without resorting to a debugger)
>>
>>    protected void assertFormPresent(String elementName) {
>>        def stopOnAssert =
>> System.properties.getProperty("stopOnAssertForm",
>> "false").toLowerCase()
>>        if (["yes", "true"].contains(stopOnAssert)) {
>>            print "Push enter to continue test"
>>            new BufferedReader(new InputStreamReader(System.in),
>> 1).readLine()
>>        }
>>
>>        if (!isElementPresent(elementName)) {
>>            def reportedErrors = getValidationErrors()
>>            if (reportedErrors.isEmpty()) {
>>                fail "Did not find the expected form ${elementName}"
>>            } else {
>>                fail "Did not find the expected form ${elementName},
>> looks like validation of previous form failed ${reportedErrors}"
>>            }
>>        }
>>    }
>>
>> I could make this neater by throwing in a call to this method at the
>> end of the defineUI method, then I know that the class is always ready
>> for use once it is set up.
>>
>> I think I'm also leaning in favour of Solution 2 right now.
>>
>> Regards,
>>
>> Jonathan
>>
>> On 21 April 2010 13:20, Harihara Vinayakaram <[email protected]> wrote:
>> > In case of Solution 2) how will you handle failure cases ? In the sense
>> > that
>> > you reach a different page than the intended page.
>> >
>> > Also I feel Solution 2) is neater than Solution 1)
>> >
>> > Regards
>> > Hari
>> >
>> > On Wed, Apr 21, 2010 at 4:10 PM, Jonathan Share <[email protected]>
>> > wrote:
>> >>
>> >> Hi,
>> >>
>> >> Background: I'm writing tests for an online ordering system. In order
>> >> to perform a booking the user must go through 9 steps, some of these
>> >> steps are optional based upon the search criteria entered. The test
>> >> cases and parameters I need to fill the different stages are defined
>> >> in an excel file. I have now managed to implement the whole process,
>> >> however...
>> >>
>> >> Problem: I have ended up with having all of my ui for the whole
>> >> workflow and methods for interacting with it defined in one huge
>> >> class, with 520 lines in my defineUI() method and a further 1000 lines
>> >> of helper methods for interacting with the ui. I'm thinking of
>> >> breaking this down into one class per step in the workflow to make it
>> >> more manageable, however I'm a little uncertain of how I should handle
>> >> the instantiation of the model for the "next" screen.
>> >>
>> >> Question: Has anyone else implemented test cases of this type? How
>> >> have you managed splitting up of the code and transitioning from
>> >> screen to screen?
>> >>
>> >> As far as I can see at the moment there are two possible architectures
>> >> I can choose from:
>> >>
>> >> Solution 1: Performing an action that causes a transition to another
>> >> page returns the module for the next screen.
>> >>
>> >> class SearchPage extends DslContext {
>> >>  def defineUI() { /*  */ }
>> >>  def searchReturnTrip(Date outboundDate, Date returnDate) {
>> >>    // Fill in search form
>> >>    // click search
>> >>    def searchResultPage = new SearchResultPage()
>> >>    searchResultPage.defineUI()
>> >>    return searchResultPage
>> >>  }
>> >> }
>> >>
>> >> class SearchResultPage extends DslContext {
>> >>  def defineUI() { /*  */ }
>> >>  def chooseFirstResult() { /* */ }
>> >> }
>> >>
>> >> class TestCase {
>> >>  void testMethod() {
>> >>    def currentPage = new SearchPage()
>> >>    currentPage.defineUI()
>> >>    currentPage = currentPage.searchReturnTrip(new Date() + 1, new
>> >> Date() +
>> >> 5)
>> >>    currentPage = currentPage.chooseFirstResult()
>> >>  }
>> >> }
>> >>
>> >> This seems like it will produce cleaner code in my main TestCase class
>> >> however it will get ugly int the *Page classes when handling cases of
>> >> the optional screens as you need to find out which screen you have
>> >> come to in order to determine which *Page class to instantiate.
>> >>
>> >> Solution 2: Always instanciate the expected *Page class in the
>> >> TestCase;
>> >>
>> >> class SearchPage extends DslContext {
>> >>  def defineUI() { /*  */ }
>> >>  def searchReturnTrip(Date outboundDate, Date returnDate) {
>> >>    // Fill in search form
>> >>    // click search
>> >>  }
>> >> }
>> >>
>> >> class SearchResultPage extends DslContext {
>> >>  def defineUI() { /*  */ }
>> >>  def chooseFirstResult() { /* */ }
>> >> }
>> >>
>> >> class TestCase {
>> >>  void testMethod() {
>> >>    def searchPage = new SearchPage()
>> >>    searchPage.defineUI()
>> >>    searchPage.searchReturnTrip(new Date() + 1, new Date() + 5)
>> >>
>> >>    def resultPage = new SearchResultPage()
>> >>    resultPage.defineUI()
>> >>    resultPage.chooseFirstResult()
>> >>  }
>> >> }
>> >>
>> >> This solution leaves the decision of which page should be next to the
>> >> TestCase (where we have enough information to make the decision of
>> >> what comes next) however I feel that littering the code with the
>> >> instantiation of new *Page objects will be less readable than the
>> >> first solution.
>> >>
>> >> Does anyone have any comments/guidance on these options that lie before
>> >> me?
>> >>
>> >> Thanks in advance,
>> >>
>> >> Jonathan
>> >>
>> >> --
>> >> You received this message because you are subscribed to the Google
>> >> Groups
>> >> "tellurium-users" group.
>> >> To post to this group, send email to [email protected].
>> >> To unsubscribe from this group, send email to
>> >> [email protected].
>> >> For more options, visit this group at
>> >> http://groups.google.com/group/tellurium-users?hl=en.
>> >>
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "tellurium-users" group.
>> > To post to this group, send email to [email protected].
>> > To unsubscribe from this group, send email to
>> > [email protected].
>> > For more options, visit this group at
>> > http://groups.google.com/group/tellurium-users?hl=en.
>> >
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "tellurium-users" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/tellurium-users?hl=en.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "tellurium-users" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/tellurium-users?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"tellurium-users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/tellurium-users?hl=en.

Reply via email to