Saving Your Automatic Web Page Test Result

Objective

In the previous example, it was shown that we can built functional tests for our web code making sure it comply with the needed functionality or that it continues to work as expected after our modifications.

The next step is to permanently store the result  as proof that it was checked properly and that it is ready for acceptance tests from our clients.

Ruby Interface with a Database

In this example the result is stored in RTH database (Requirements and Testing Hub) -an open source system-. We’ll use a file (RTH_Verify.rb) that was posted in the original RTH forum page and unfortunatelly no longer available. There are four steps, first the initialization of the odbc interface,  creation of a test suite record and update that a test as beeing run, notification of the completed test and close of the connection.

First Part (RTH_Verify.rb)

[This code is from the original developers of RTH]
In this class they initialize the odbc interface to MySQL rth database in a initialize call.
For your instalation you will have to change: yourserver, rth (or your database), yourdbuser, yourdbpassword.

Class Verify
require 'dbi'
def initialize(projectID, testID, testSetID, testName,
 testDir, action, expectedResult, actualResult)
 @projectID = projectID
 @testID = testID
 @testSetID = testSetID
 @testName = testName
 @testDir = testDir
 @action = action
 @expectedResult = expectedResult
 @actualResult = actualResult
 @uniqueRunID = "0"

 #The connection string in your odbc string is:
  #connectionString = '{DSN=rth;DRIVER=MySQL;SERVER=yourserver;DATABASE=rth;UID=yourdbuser;PWD=yourdbpassword;PORT=3306;}'
  @dbh = DBI.connect("dbi:ODBC:rth","yourdbuser","yourdbpassword")
 end

The Second Part (RTH_Verify.rb)
It’s about setting variables: time, sql INSERT string (you can check the file for the complete syntax), sql UPDATE string for the status record. And excecuting the initial notifications of a test being run.

def testStarted
 projid = @projectID.to_s
 tsid = @testSetID.to_s
 tid = @testID.to_s
 tName = @testName.to_s
 tDir = @testDir.to_s
 timeStarted = DateTime.now
 @uniqueRunID = "S"+Time.now.tv_sec.to_s

 # First SQL
 sql = "INSERT INTO ..."  + "VALUES(...)"
 q = @dbh.prepare(sql)
 q.execute

 # Second SQL
 sql = "UPDATE testset_testsuite_assoc SET ... WHERE ..."
 q = @dbh.prepare(sql) 
 q.execute
end

The Thirdh Part (RTH_Verify.rb)
Is the notificaction that the test was compleated, in our watir code it means it was succesfull.

def testCompleted
tsid = @testSetID.to_s
ttid = @testID.to_s
timeFinished = DateTime.now
date=timeFinished.strftime("%Y")+"-"+timeFinished.strftime("%m")+ "-"+timeFinished.strftime("%d")+ " "
date=date+timeFinished.strftime("%H")+ ":"+timeFinished.strftime("%M")+":"+ timeFinished.strftime("%S")
# First SQL
sql = "UPDATE testsuiteresults SET ... WHERE ...";
q = @dbh.prepare(sql)
q.execute # Second SQL
sql="UPDATE testset_testsuite_assoc SET ... WHERE ..."
q = @dbh.prepare(sql)
q.execute
end

Fourth Part (RTH_Verify.rb)
And finally the end of the code to close and disconnect.

 def close
  @dbh.disconnect
 end
end

How It Is Used

This is how I use this code in my tests. You can see that the only change to our code is the requirement for dbi and the RTH_Verify.rb file

# Test with DB result stored
require 'watir'
require 'test/unit' 
require 'dbi' 
require 'RTH_Verify.rb'

class TC_recorded < Test::Unit::TestCase
 def test_toDB
  ie = Watir::IE.new
  ie.wait
 ie.bring_to_front
 ie.wait

Then the actual test is excecuted. I choose only to record a successfull test, so at the end the rutines are called.

  #Here goes the test
  ie.close

  #Variables
  testDir = Dir.getwd
  testName = File.basename(testDir)
  # This are RTH specific
  projectID = 2
  testID     = 4
  stepNum  = 1
  testSetID = 33

  db = Verify.new(projectID, testID, testSetID, testName, testDir, "", "", "")
  db.testStarted
  db.writeVerification(stepNum,
   "Test identification string","Detail test description string","Success Message String",
   "Pass","Module test string", "N/A", "N/A",  "#")
  db.testCompleted
  db.close
 end
end

If it the test terminates normally, the test is successfull, and the database has been modified so the ‘results page’ on the RTH system wi’ll show that an automated test exist and user or QA confirmation is needed to change status to ‘signed’.

You can modify this file for your particular system or try RTH which I recommend.

Advertisements

Automatic Web Page Testing

What Is It For

Automatic testing for me, above all, means: ‘peace of mind’. After you do development work or code maintenance of a web page, you easily can verify that things works as expected, which is a wonderfull experience.

I only do functional testing, time constraints prevent me from doing TDD or achieve ample test code coverage. Functional testing means that in a short time I can warranty  the software works as it did before or that the new functionality is acomplished.

What Does This Post Is About

This article describes how to automatically generate user interactions like filling text, number fields, textboxes, selecting values and clicking on elements in MS IE (Microsoft Internet Explorer browser*) and logging in a file the result, confirming that the app complies with expected results or where it fails.

The main focus is on web pages using the dojo toolkit framework 1.5.

* These tools are reported to work with firefox and safari, check watir installation. If You are using linux check this blog. [Edit: or check this for firefox and chrome]

What Do You Need

Follow the install procedures and you’ll get a text editor associated with the extension .rb, a command line interpreter to run your ruby programs and tools to browse your web page objects.

The Ruby Script

First we declare required files

# Aug 2010: Demo for testing dojo.toolkit #includes 
require 'watir'
require 'test/unit'

Now our Ruby program can drive the internet browser and test elements in our web page.

So, we define a test class and open a browser window, bring it to the front and wait for it to be ready. Notice that the browser will be instantiated into a ie named variable

class TC_recorded < Test::Unit::TestCase
 def test_webpage
  ie = Watir::IE.new
  ie.bring_to_front
  ie.wait

In this example will show how to open a real web page, log in, typing user, password and click en the login button:

  ie.goto("https://sourceforge.net/account/login.php")
  ie.wait
  ie.form( :name, "login_userpw").text_field( :name, "form_loginname").set("youruser")
  ie.form( :name, "login_userpw").text_field( :name, "form_pw").set("yourpassword")
  ie.form( :name, "login_userpw").submit
  ie.wait
  ie.bring_to_front

or if you use only unique name identifiers, you could use a shorter notation:

  ie.text_field( :name, "form_loginname").set("youruser")
  ie.text_field( :name, "form_pw").set("yourpassword")

This code will log you into sourceforge. The login form looks something like this:
Login screen
The HTML for that form -cleaned- is something like:

<form action="https://sourceforge.net..login.php" method="post" name="login_userpw">
 <div>Enter your account info:</div>
 <div>Username:<input maxlength="15" name="form_loginname" type="text"></div>
  <div>Password:<input maxlength="32" name="form_pw" type="password" /></div>
 <input name="login" type="submit" value="Log in" />
</form>

Look at the name attribute and the type of field, you filled the first two and clicked the third with Ruby.

The best way to see the code is to install firefox add-in firebug and use the context menu (right mouse button over the page object) and select inspect element.


We’ll see what happens with the HTML after the dojo.toolkit renders its elements that are called widgets. Our test form looks like this (is a modified version from the file that you downloaded  ./digit/tests/form/Form.html):

Now, to fill this page with the test data we use the code:

 #date into text field
ie.text_field( :name, "foo.bar.baz.quux").set("28/08/2010")
 #select first option of combobox, tow values: display and option value
ie.text_field( :name, "plop.combo").set("one")
ie.text_field( :hidden, "plop.combo").set("one")
 #set first checkbox
ie.text_field( :id, "c2b").click
 #set radio to first option
ie.text_field( :name, "r2").click
 #select first option of multiselect.
 #first we clear all, then select only the first
ie.select_list( :name, "ms1").clearSelection
ie.select_list( :name, "ms1").select("Tennessee")
#and click de submit button
ie.button( :name, "bgetval").click
ie.wait

Explanation:

  • Fill date field with text ’28/08/2010′ that is day, month, year
  • The combo needs two fields: the original one that you declared on your html and a second one used by dojo as value. This has the same named as your field but is of type hidden.
  • The check box and the radio are referenced as your fields but are of type text in the final rendered page. The event to use is click
  • The last one is a selection and is handled as a normal select_list
  • The button could be triggered by a submit or a click

Now the result should be checked as it could be a full page postback or an ajax panel call. This is the code to test if the result shown is as expected.

  sleep 0.4
  assert(ie.contains_text("text expected"),"ERROR: check test #1, form fill")
 end
end

So well wait a little and then test for text that should be in the answer. It could be a valid answer or the warning of an error. If the text is found the script continues until the end is reached and a sumary like this one is shown.

Loaded suite test_webpage
Started
Finished in 0.355 seconds.
1 tests, 1 assertions, 0 failures, 0 errors

If not, then the test is halted and the text ERROR… is send to the console output.

Final note: If you want to test a tree widget, you will have to look for the text in each branch and click it. In this example we use the <span> text:

ie.span(:text, "branch option").click

Thats it!. The test of two web pages in a few lines.

Here you can find the Ruby code demo_watir_test_rb.

Batch File
In windows I prefer a file I can start with two clicks, this is the content of that file:

del test_result_web_page.txt
Ruby demo_watir_test.rb > test_result_web_page.txt
PAUSE Check test result on file: test_result_web_page.txt

References
Watir documentation here
Watir matrix reference for page elements here
Watir HTML reference here
Watir reference or actions here