Presenter First Pattern Ideas for Watir Test Framework?
Wednesday, August 20, 2008
I have been reading on Model View Presenter and especially Presenter First pattern. . I was reading it thinking about Watir Test Framework where View is a Layer or Adapter that talks to Watir which talks to the browser. In this way View is ‘dumb’ – just an interface to Browser(and can be treated as Adapter so you can swap IE for FireFox).
Since I am tesing a GUI story I think that my Presenter should be some kind of a Class that’s modeling a UseCase (you can call it Story or Feature). I would model the Presenter as a collection of methods reflecting UseCase Scenario interactions, behaviours and I would keep the Model as rules and data in one class because I would not want to spend a lot of time building a Model, I am testing the Application and most of the time I don’t have a lot of information so I would just grow the Presenter organically, my tests are Exploratory so I ‘discover’ and ‘learn about’ Model as I build tests. I think it would be a waste of time to build Model separately. I just treat it a a ‘dumb’ set of data that I store in hashes. My goal is to create cheap GUI tests built for frequent View changes so all my test logic is in the Presenter that has ‘dumb’ data model and ‘dumb’ View (well, an adapter I would think)
In the paper on Presenter I really liked this quote about why it is not good to go View First route
Starting with the view seems quite logical when following a customer prioritized eature-driven development process. The logic of this approach is seductive: customer stories describe actions taken on the view and results shown in the view, feedback from the customer requires some interface for them to use the application, and the importance of the model (infrastructure) is minimized. Unfortunately view first is an easily made and expensive mistake.
In our experience, the best alternative of the three possibilities is to start with the presenter. By starting with the presenter, and organizing development around it, the application may be built from user stories following test-driven development practices.
Aha. This is the mistake that most Record/Playback Automated Testing tools make. They attach to the View First. Everything is managed by the View. Automated Tests are scripted as actions on the View, coupled to the view. It’s a mess to decipher and modify.
For example: a View First approach using Watir code would be to do this:
ie = Watir::IE.attach :url, /google/ ie.text_field(:name, 'q').set 'Watir' ie.button(:name, 'btnG').click
Tester translates User’s intentions into View First test. What is shown in 3 lines of code?
1 – attach to browser
2 – browser has a text_field named ‘q’, find it and type text ‘watir’ into it
3 – browser has a button named ‘btnG’, find it and click it.
This is eaiser to read than other tools, cleaner API but in this View First the test is expensive to maintain yet so cheap to make. Cheap and fast to script if its intended usage is to thrown it away afterwords. But the expensive part comes with maintenance if those test are to bring value long term or when View changes.(I can revisit this later)
So a Semantic View wrapper can be introduced that is written in the language of Domain (User Domain, Business Domain). This would be mu dumb view adapter. I refer to it as Semantic Test Objects layer (that name just stuck with me) where Test Object is some Area of Interest to the Tester. So for example that same Google test can be expressed as: On Google Home Page set the term ‘Watir’ and click Search or simply : google ‘watir’. I think this is what a user would say, just google it.
How about modeling it this way in simple trivial form:
google 'watir' #implementation can be def google (term) ie.text_field(:name, 'q').set term ie.button(:name, 'btnG').click end
In this example I only have a convenient wrapper on implementation. It does not decouple much but it’s a good step. Buidling futher I could do this:
module GooglePage
def term
@b.text_field(:name, 'q')
end
def search
@b.button(:name, 'btnG')
end
end
class GoogleTest
include GooglePage
def initialize
@term = 'Watir'
@expected = some links or stuff to look for
end
def run
load_page
enter_term
click_search
verify_results
end
end
#execute test
GoogleTest.new.run
Now I think I am building a Presenter First type of Test where I will want to keep the View as a Semantic Layer included as module in my Test. Steps modeling user’s actions as methods. Model View as a member of Test.
This is a half baked idea (or maybe overbaked) but I can see that building GUI tests as UseCase type modeling with delegation to Semantic View Layer quite useful.
So dear readers, any thoughts, I would like to continue this
