Friday, February 20, 2009

HTML Report for Test automation using Selenium and Ruby

I had to start test automation for my project using any open source tool. After a series of analysis and comparison, we decided to go with Selenium(Selenium RC) and Ruby... (...selection of 'Ruby' is due to the obvious reasons that, I am more familiar in Ruby ;) ).

As usual, the first thing that hit when we start automation with an open source tool, is the kind of result/report tool provides after test run. And Selenium RC (with Ruby script), didn't generate any test result/report by default. And I will have to go with Rspec reporting. But instead of digging much into Rspec, I have written an HTML logger class (using the default logger class of 'Watir' as a base).

As I have not used Rspec reporting before, I can neither suggest you which is better nor do a comparison... But this solved my purpose, and I just thought of sharing what I do...

Okay enough with story... Here I am with the HTML logger class : "Logger_class.rb", written in Ruby for generating result/report of automation testing. This can be used to generate test result for 'Selenium' with Ruby (yea.., of course this would works for 'Watir' as well).

###----------------------------------------###
# --- HTML Logger Class --- #
# Purpose:
# To log the test results of automated tests into an HTML report
#-----------------------------------------#

class HTMLLogger

def initialize(test_result_path)
time = Time.now.strftime('%m_%d_%Y_%H_%M')
@logfile = File.new(File.join(test_result_path, "/Test_Result_#{time}.html"), "w")
@logfile.puts "<html>"
@logfile.puts " <title>Logon2 Automation Test Results</title>"
@logfile.puts " <head><style type='text/css'>"
@logfile.puts " body{margin: 4; padding: 0;}"
@logfile.puts " h2{font-family:Verdana, Arial, Helvetica, sans-serif; font-size:16px; font-weight:bold; color:#333333}"
@logfile.puts " p{font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; color:#333333}"
@logfile.puts " .tr_summary{border-width: 1px; border-style: solid; border-color: #163B69; background-color: #163B69; color: white; font-size: 12px; font-family: Verdana; text-decoration: none; font-weight: bold; }"
@logfile.puts " th {border-width: 1px; border-style: solid; border-color: #163B69; background-color: #163B69; color: white; font-size: 12px; font-family: Verdana; text-decoration: none; font-weight: bold; }"
@logfile.puts " .tr_pass {border-width: 1px; border-style: solid; border-color: #163B69; color: #666666; font-size: 11px; font-family: Verdana; text-decoration: none; font-weight: normal; }"
@logfile.puts " .tr_fail {background-color:#FFFF99; border-width: 1px; border-style: solid; border-color: #163B69; color: #FF0000; font-size: 11px; font-family: Verdana; text-decoration: none; font-weight:bold; }"
@logfile.puts " </style></head>"
@logfile.puts " <body>"
@logfile.puts " </table><h2>Test suite results</h2>"
@logfile.puts " <table id='suiteTable' border='1' cellpadding='1' cellspacing='0' width='100%'>"
@logfile.puts " <th>Sl.No</th><th>TC.ID</th><th>Test Case Name</th><th>Result</th><th>Screen Shot</th><th>Comments</th>"
$tc_sl_no = 0

end

def log_result(tc_id, name, test_status, screen, notes)
$tc_sl_no = $tc_sl_no+1
if test_status == "Pass"
@logfile.puts "<tr class='tr_pass'>"
@logfile.puts "<td>#{$tc_sl_no}</td>"
@logfile.puts "<td>#{tc_id}</td>"
@logfile.puts "<td>#{name}</td>"
@logfile.puts "<td>#{test_status}</td>"
@logfile.puts "<td>#{screen}</td>"
@logfile.puts "<td>#{notes}</td>"
else
@logfile.puts "<tr class='tr_fail'>"
@logfile.puts "<td>#{$tc_sl_no}</td>"
@logfile.puts "<td>#{tc_id}</td>"
@logfile.puts "<td>#{name}</td>"
@logfile.puts "<td>#{test_status}</td>"
@logfile.puts "<td>#{screen}</td>"
@logfile.puts "<td>#{notes}</td>"
end

end

def end_log(tc_total, tc_executed, tc_pass, tc_fail, tc_notrun)
@logfile.puts "</table>"
@logfile.puts "<table>"
@logfile.puts " <h2>Test Summary</h2>"
@logfile.puts " <table id='summary' border='0' cellpadding='1' cellspacing='2' width='25%'>"
@logfile.puts " <tr class='tr_summary'><td><strong>Total No. of Test Cases in Suite</strong></td><td>#{tc_total}</td></tr>"
@logfile.puts " <tr><td></td><td></td><td></td></tr>"
@logfile.puts " <tr class='tr_summary'><td><strong>Number of Test Cases Executed</strong></td><td>#{tc_executed}</td></tr>"
@logfile.puts " <tr><td></td><td></td><td></td></tr>"
@logfile.puts " <tr class='tr_summary'><td><strong>Number of Test Cases Passed</strong></td><td>#{tc_pass}</td></tr>"
@logfile.puts " <tr><td></td><td></td><td></td></tr>"
@logfile.puts " <tr class='tr_summary'><td><strong>Number of Test Cases Failed</strong></td><td>#{tc_fail}</td></tr>"
@logfile.puts " <tr><td></td><td></td><td></td></tr>"
@logfile.puts " <tr class='tr_summary'><td><strong>Number of Test Cases Not Run</strong></td><td>#{tc_notrun}</td></tr>"
@logfile.puts" </table>"
@logfile.puts"<p> </p></body>"
@logfile.puts"</html>>"
@logfile.close

end

end
###----------------------------------------###

How to Use:

1. Download the file "Logger_class.rb" from the link given below in Sample Script section (or)
Copy the Logger_class script from above and save as .rb file("Logger_class.rb").

2. Paste the "Logger_class.rb" somewhere into your test script directory.

3. Require this "Logger_class.rb" in your suit file and initialize/create a HTML result file for your test. All this could be done, just adding two lines of code in your main test script rb file (refer the sample test script in the link).

require "{your directory path}/Logger_class' #Example : require 'C:/Test scripts/Logger_class'
$logger = HTMLLogger.new(File.expand_path(File.dirname(__FILE__))) #filePrefix_name


4. Function call to log the result at the end of each test script. Add the below command at the end of each test case script.
$logger.log_result($tc_id, $tc_name, $tc_status, screenshot_name, actual_result)
NOTE : If you are using setup-teardown, you can add this part in your tear down method.

5. Function call to add test summary to your html logger. Add the below line at the end of your main test script file or as a last test in your suit.
$logger.end_log($tc_total, tc_executed, $tc_pass, $tc_fail, $tc_notrun)

Sample Selenium Script:

Logger class can be downloaded from : http://docs.google.com/Doc?id=d7wdxgx_9dzpjrddn

A Sample test script, which uses logger class for report generation can be found here : http://docs.google.com/Doc?id=d7wdxgx_10f9ktx9gk

NOTE : Both files are saved as txt files, download and save with .rb extension

Sample Result:

And here, you can find a sample HTML result generated...

http://docs.google.com/Doc?id=d7wdxgx_8r2twnfmb

See if it helps you..!

All the best..!