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.

Reply via email to