In the FitNesse tests I put together in part 1 I used only ColumnFixture tables. One example is BloggerFixtures.GetEntryTitleContent, which takes entry_index as an argument and returns the title and the content of that entry. To use a database analogy, that particular ColumnFixture behaves like a SQL query of the form:
SELECT title, content FROM entries WHERE entry_index=N
In the FitNesse tests I wrote, I used GetEntryTitleContent in a table like this:
!|BloggerFixtures.GetEntryTitleContent|
|entry_index|title?|content?|
|1|Entry #3 Title|Entry #3 Content|
|2|Entry #2 Title|Entry #2 Content|
|3|Entry #1 Title|Entry #1 Content|
We can look at each row in this table as being the result of running the SQL query above, with entry_index set to 1, 2, and 3.
However, we really are interested in verifying ALL entries in the blog at the same time. It would be useful to have a fixture similar to a SQL query such as:
SELECT * FROM entries
This is exactly what a RowFixture achieves: it can be thought of as returning all the "rows" in the "database". In our case, we need to return all the entries in the blog, specifically their index, title, and content, so we need something like:
SELECT entry_index, title, content FROM entries
To achieve this, we need to write a clas derived from RowFixture. Our class needs to define
two methods:
- getTargetClass
- query
Here is the ListAllEntries fixture I wrote:
from fit.RowFixture import RowFixture
import sys
blogger_path = "C:\\eclipse\\workspace\\blogger"
sys.path.append(blogger_path)
import Blogger
class BlogEntry:
_typeDict={
"entry_index": "Int",
"title": "String",
"content": "String",
}
entry_index = 0
title = ""
content = ""
class ListAllEntries(RowFixture):
def getTargetClass(self):
return BlogEntry
def query(self):
blogger = Blogger.get_blog()
num_entries = blogger.get_num_entries()
entry_list = []
for i in range(num_entries):
blog_entry = BlogEntry()
blog_entry.entry_index = i+1
blog_entry.title = blogger.get_nth_entry_title(i+1)
blog_entry.content = blogger.get_nth_entry_content_strip_html(i+1)
entry_list.append(blog_entry)
return entry_list
The class derived from RowFixture is ListAllEntries, which defines the 2 methods I mentioned:
- getTargetClass() returns the class BlogEntry
- query() builds a list of BlogEntry objects by retrieving entry_index, title and content for each entry in the blog and assigning their values to the corresponding variables of BlogEntry
!|BloggerFixtures.ListAllEntries|
|entry_index|title|content|
|1|Entry #4 Title|Entry #4 Content|
|2|Entry #3 Title|Entry #3 Content|
|3|Entry #2 Title|Entry #2 Content|
|4|Entry #1 Title|Entry #1 Content|
The above fragment is from a new test page I created in the BlogMgmtSuite acceptance test suite. You can see the full contents of this page here: PostDelete4EntriesRowFixture.
Using a RowFixture has another big advantage over using a ColumnFixture: a RowFixture will retrieve all the entries in the table and will let you know if you have any extra rows or if you are missing any rows. Here is an example:
Assume the blog has 4 entries. Assume we use a ColumnFixture like this:
!|BloggerFixtures.GetEntryTitleContent|
|entry_index|title?|content?|
|1|Entry #4 Title|Entry #4 Content|
|2|Entry #3 Title|Entry #3 Content|
|3|Entry #2 Title|Entry #2 Content|
In this case, all the rows will be colored green and the test will pass, since the ColumnFixture will retrieve one by one the three entries we specified.
Now assume we use a RowFixture like this:
!|BloggerFixtures.ListAllEntries|
|entry_index|title|content|
|1|Entry #4 Title|Entry #4 Content|
|2|Entry #3 Title|Entry #3 Content|
|3|Entry #2 Title|Entry #2 Content|
In this case, the test will fail, since the RowFixture will retrieve the fourth entry too and will let us know that we missed it in our table. FitNesse will show a fourth row colored in red, with the following text:
|4 surplus|Entry #1 Title|Entry #1 Content|
Conclusions
- a RowFixture is the ideal vehicle to use when you need to verify that all the data you entered into the system under test so far is there -- no more and no less
- using RowFixtures proved to be easy, once I visualized their similarity to SQL "select * from" queries.
No comments:
Post a Comment