Monday, June 27, 2011

Creating Plugins for Wave Test Manager

A customer recently contacted me describing a problem of how to get notified when a script fails in Wave Test Manager.  In this case their alert system did not work with the default options built in to Wave Test Manager (email, XMPP, etc) and thus they wanted have another way to know when one or more scripts had failed.    Fortunately Wave Test Manager 1.1 offers a very simple way to do this kind of integration based on its Plugin system.   In this post I’ll walk through a very simple example plugin that first saves the details about failures in a file, and then to extend it I’ll show how to make it store failure details in a database.   To do this I'll be assuming a very small amount of familiarity with the concepts of programming languages.  However what we need to do is so simple that if you have any basic experience with any kind of scripting language such as VBA, Javascript, Python or Java then you should be fine.

Wave Test Manager plugins are implemented in a simple scripting language called Groovy.  Although it’s a strange name it is widely known, most especially because it is nearly entirely based on Java, but with a greatly simplified syntax to allow much easier use in scripting environments.   If you don’t know Groovy, don’t worry – the use you need to make of it is quite minimal to achieve a lot and there are plenty of examples that are easy to find for how to do a huge array of tasks.

Step 1 – Locate or Create the Plugins Directory
The first step in creating a Wave Test Manager plugin is to locate your Wave Test Manager data directory.   This depends a bit on which version of Windows you are using, but a sure fire way is to use the shortcut in the Start Menu for the Scripts folder.  This is created by the WTM installer and is handily in exactly the directory we are looking for.  So open this folder using the Start Menu and then navigate one level up in Windows Explorer.   Here you need to create a directory called “plugins”.  Here is how it looks in my test computer:

image

Step 2 – Create a Folder for your Plugin
The folder for your plugin goes inside the plugins folder that you just created above.  You can name it whatever you like – ideally make it match the name or function of your plugin.  Here I’ve called mine “failurelog”:

image


Step 3 – Create a Test Plugin Script
Here you need to use a text editor such as Notepad.   For now the script we make will be extremely simple – we’re going to do nothing more than display a message when Wave Test Manager starts to see if your plugin is working.   Here is what you need to put in your text file:

import javax.swing.JOptionPane
JOptionPane.showMessageDialog(null,
"If you are seeing this then your plugin is working!", 
"Plugin Test", JOptionPane.INFORMATION_MESSAGE);      


This script displays a message box when Wave Test Manager starts up.  Save it as the file “plugin.groovy” inside your plugin folder (in my case, inside the “failurelog” directory).  Then if you restart Wave Test Manager you should see something like this:

image

If this doesn’t work, check your steps above before proceeding!   Make sure you saved your file as “plugin.groovy” and not as “plugin.groovy.txt” (what Notepad will do by default).

Step 4 – Create the Real Script

Here is our first real script below:

   1:  //
   2:  // A WTM plugin that records a log of script failures in a file
   3:  //
   4:  events.connect(scriptRunnerService,"testPlanComplete") { testPlan->
   5:   
   6:     def f = new File("failures.log")
   7:     if(!f.exists())
   8:       f.text = "" 
   9:   
  10:    def date = new Date()
  11:    for(s in testPlan.scripts) {
  12:      if(s.result == "Failures") {  
  13:        f.text += "${date} : script ${s.testPlanScript.scriptFile.name} failed\n"  
  14:      }
  15:    }
  16:  }

Here you can see on line 4 the plugin connecting to events belonging to the scriptRunnerService inside Wave Test Manager to receive notifications when a Test Plan is complete.   On line 6, 7 and 8 it creates a file to store script failures in, initializing it with blank text if it does not already exist (line 8).    Then on line 11 it iterates through the scripts in the Test Plan that completed and checks each one to see if it failed (line 12).  When a script has failed, it appends a line to the the failure log file showing details about the failure.

Step 5 – Add Rows to a Database

Just to cap off the example, we make an extension to the above script to make it record all script failures in a database.   Thanks to Java’s built in database interfaces (JDBC) the script we need works for any database, as long as you add the correct libraries (jar files) and connect string in the code below.  For this simple example we’ll use MySQL.

  1. Firstly, since we are connecting to MySQL you will have to add the MySQL database driver jar file.  Normally you could do that by making a “lib” directory inside your plugin’s directory, but due to the special way in which JDBC drivers are initialized in this case you need to place it in a different directory that already exists.  Look for the webapps/bbq/WEB-INF/lib directory which should already exist and  then download the jar file from the MySQL web site and add it there.
  2. To use this example you’ll need to create a MySQL database and add a failure log table to it.  The failurelog table can be created by executing the following statement:
    create table failure ( id int(9) unsigned auto_increment,  script   varchar(255),  date timestamp, primary key (id) );
  3. Now we make three changes to our script as shown below:  import the Groovy SQL module at the top (line 4), add a connect statement to connect to the database (line 8), and replace the line that appends to the file with a line that instead, inserts into the database (line 16).

   1:  //
   2:  // A WTM plugin that records a log of script failures in a database
   3:  //
   4:  import groovy.sql.Sql
   5:   
   6:  events.connect(scriptRunnerService, "testPlanComplete") { testPlan ->
   7:   
   8:    def sql = Sql.newInstance(
   9:        "jdbc:mysql://localhost:3306/failurelog",  // database
  10:        "root",  // user name
  11:        "",  // password
  12:        "com.mysql.jdbc.Driver")
  13:    def date = new Date()
  14:    for(s in testPlan.scripts) {
  15:      if(s.result == "Failures") {  
  16:        sql.execute("insert into failure values (NULL, ${s.testPlanScript.scriptFile.name}, ${date})")
  17:      }
  18:    }
  19:    sql.close()
  20:  }

Conclusion

As you can see above, Wave Test Manager plugins make it really easy to integrate WTM and Badboy into your organization’s ecosystem.   With just a few lines of code you can do some very powerful things.   As always I’m interested to hear what uses Wave Test Manager users are finding for plugins and, of course, what challenges you are having and what we can do to make plugins better and easier to develop.   And of course, if you think you’ve created something that can be useful for others, drop us a line at support@badboy.com.au and we would love to post it on our Plugins Page.

Wednesday, June 15, 2011

Documenting the Kindness of Strangers!

One of the wonderful things about being a small business making a widely used product like Badboy is the passion and loyalty of users who love the product so much that they put in their own time to contribute to it.   Whether it’s on the forum, blog posts or – in this case – not just one but two separate users who donated versions of the Badboy Documentation in Microsoft Word format for others to use.   In the end I had to choose which version to post on the web site – even though both were extremely professional and high quality and show an amazing level of care and attention to detail.   It is thanks to these two people that you can now find the Badboy Help downloadable in either PDF or Word format.  
I know from the frequent requests how useful it is to have the documentation in a format that is both printable and readable off line.   Thank you to the amazing Badboy users who made this possible!