QTP: Datatables and some interesting observations.
I’ve been working in Datatables a lot lately since my manual
testers prefer this format for sharing information with me. It provides a very
convienient tool (installed on everyone’s machine), and provides great
formatting. Personally, I hate sending a spreadsheet to do a database’s job,
but it seems if I say the word “database”, some people are intimidated. What’s
often funny about this is that these same people refer to the sheet as an “Excel
database”. I apologize if I sound arrogant. I’m not arrogant; I am just very
specific and detail-oriented. Arguably, it’s what makes me good at what I do,
if good I am.
That all said, let me also say I am not a fan of datatables.
Datatables are difficult to navigate and the object model is terribly
unintuitive. If you want to remain very simple, it seems to work very well.
However, it just isn’t capable of being a granular in its control as it should
be. But, hey, it’s a fast way to apply data to a test built as a one-off or
some limited use test case.
So, I usually build tests for manual testers from Excel. I
have a component-based structure built (in progress) that allows me to
basically assemble tests from a calling script (“driver”) that uses reusable
actions in other tests (“components”), where the data and the validation
process are abstracted from the components to keep them as generic as possible.
I can usually wire up whatever I want in a short period of time, assuming I’ve
the components finished. Of course, in a web environment, I am never done
completely.
However, I’ve noticed something interesting with datatables:
the cursors on datatables don’t carry over from action to action. For example,
let us assume I have 2 actions, Action1 and Action2, where the former calls the
reusable latter. Action2 has a datasheet with data in it (we could also import
the data dynamically as I mention above, but for purposes of this example, it’s
not necessary). In Action 1, I have the following the code:
DataTable.GetSheet("Action2").SetCurrentRow(2) ‘Sets
the row
Msgbox DataTable.GetSheet("Action2").GetCurrentRow
‘Returns 2, the value I just set
msgbox DataTable.Value("Value1",
"Action2") ‘Returns Row 2 data
Then, I call Action2
RunAction "Action2", oneIteration
Which contains:
msgbox
DataTable.GetSheet("Action2").GetCurrentRow ‘Returns 1, Not 2
msgbox
DataTable.Value("Value1", "Action2") ‘Returns Row 1 data, Not
2
At this point, I was pretty sure the cursor is maintained
for each datatable. But then, I tried adding two more lines to the above code:
Msgbox DataTable.GetSheet("Action2").GetCurrentRow
‘Returns 1, not 2!
Msgbox DataTable.Value("Value1",
"Action2") ‘Returns Row 1 data!
What does this mean? Basically, it means that the component
(Action2) doesn’t recognize the cursor as controlled by the driver (Action1).
So, does this mean that the driver and component have their own cursor? So, my
interest is really piqued. I tried one more test; I added a third row to my
imported sheet, and the following to the Component action:
Datatable.GetSheet("Action2").SetCurrentRow(3)
Msgbox
DataTable.GetSheet("Action2").GetCurrentRow
Msgbox
DataTable.Value("Value1", "Action2")
Then, I added this to the driver:
Msgbox
DataTable.GetSheet("Action2").GetCurrentRow ‘Returns 3!
Msgbox
DataTable.Value("Value1", "Action2") ‘Returns Row 3 data!
So, what does this mean? It suggests that the driver’s
cursor is usurped by the component. I wondered what would happen if I passed
this down to another calling action beyond the component. I added a third
action, Action3, that only contained the following code:
Datatable.GetSheet("Action2").SetCurrentRow(4)
Msgbox
DataTable.GetSheet("Action2").GetCurrentRow
Msgbox
DataTable.Value("Value1", "Action2")
I also added a couple more line to the component, Action2,
at the very end, to see what would happen to the cursor set in Action2 prior to
the call to Action3:
RunAction "Action3", oneIteration
Msgbox
DataTable.GetSheet("Action2").GetCurrentRow
Msgbox
DataTable.Value("Value1", "Action2")
Guess what? Action2’s new code returned a GetCurrentRow and
RowValue of 1. Ok, that’s still looking strange. So, I added another action
called by Action3 called Action4 with code almost identical to Action3. When
the focus returned to Action3, something strange happened: Action4’s value of
current row was persisted in Action 3. However, as soon as we passed out of
Action3 and back up into 2, the value once again became 1.
posted @ Thursday, March 16, 2006 1:14 PM