Example TestLink XMLRPC Clients in Perl

There are not many good examples floating around of Perl clients for TestLink’s XMLRPC API. There are two examples included with the 1.9.3 source, but they are very brief. I wrote two scripts to support a first-blush attempt at automated test running, and while they will get a lot more refinement over time, I thought abstracted versions of them might be beneficial for others trying to write Perl clients (or in any language – they perl samples were so sparse I largely based my script on the python example).

Continue reading

Missing TestLink API Function – getExecutionResults()

I have finally come to terms with the TestLink API and have bashed out an automated test runner written in perl (which I hope to clean up and post in the next few days, there don’t seem to be many (or any) examples of this in the wild).

After getting nightly automated testing running, I wanted a very simple script which would, for each test case in a given test plan, compare the last and the second to last result and print a warning if they were different. Long term I will have better automated reporting, but our test script library is still so new that it’s not really news that a lot of them are failing. What would be news is if a specific test case passed two nights ago but failed last night.

Continue reading

TestLink 1.9.3 API Documentation

I have not been able to find any up-to-date documentation on the TestLink XMLRPC API online. The best I could find was phpdoc output from 1.8.x located at http://www.teamst.org/_tldoc/1.8/phpdoc_api/. The actual content of that page was pretty helpful, just out of date. Today I returned to trying to work with the API and decided to figure out how to generate the same document format for the 1.9.3 code. I’m placing it online in case anyone else had the same issue I did.

Continue reading

UI Improvements for TestLink’s Vertical Step Layout

I have previous posts on several improvements which drastically improved my team’s ability to use TestLink:

As we began really testing in earnest, we found that the “horizontal” test case layout we had been using was limiting in several ways.  First, when the expected results was a collection of logs rather than a text description of behavior, it became a labor to find the relevant bits in the long log lines.  Second, some types of expected results would cause the results cell to take up as much horizontal space as possible, which squashed the “actions” cell.  On more than one occasion I had to copy the actions to a text file so that I could read them in a meaningful manner.

Update 2012-05-08: There is a usable-with-the-patch-command patch available that incorporates all of these changes and more. See the README at the base of the github repo for more details on what’s in that patch.

Fortunately there is also a “vertical” test case layout.  We recently switched to using this and so far it solves our problem.  Unfortunately I had to reimplement all of the items from the links above.  The diffs below are the changes I made to our files to get the desired changes.  Possible items of interest:

  • The diffs below assume that the changes from the previous blog posts have been made.  This affects the line numbers in the diffs, as well as things like the existence of the CSS file and its contents.
  • I never really liked the alternating BG color behind the steps, but it was the best solution in the horizontal view.  In the vertical view I alternated the colors in the empty gutter cells to the left of the action/result rows.  Since there’s no text in those cells, it allowed me to use darker, more contrasting colors.
Index: gui/themes/default/css/custom.css
===================================================================
--- gui/themes/default/css/custom.css   (revision 241)
+++ gui/themes/default/css/custom.css   (revision 242)
@@ -6,6 +6,14 @@
        background-color:       #CCCCCC;
 }

+.row_color_3 {
+       background-color:       #555555;
+}
+
+.row_color_4 {
+       background-color:       #AAAAAA;
+}
+
 div.c_actions, div.c_expected_results {
        font-family: 'Courier New', Courier, monospace;
 }
Index: gui/templates/testcases/inc_steps.tpl
===================================================================
--- gui/templates/testcases/inc_steps.tpl       (revision 241)
+++ gui/templates/testcases/inc_steps.tpl       (revision 242)
@@ -91,14 +91,16 @@
        {/if}
        {foreach from=$steps item=step_info}
        <tr>
-               <th width="25px"><nobr>{$inc_steps_labels.step_number}
+               <th width="25px"><nobr>
                <span class="order_info" style='display:none'>
                <input type="text" name="step_set[{$step_info.id}]" id="step_set_{$step_info.id}"
                       value="{$step_info.step_number}"
                       size="{#STEP_NUMBER_SIZE#}"
                       maxlength="{#STEP_NUMBER_MAXLEN#}">
                {include file="error_icon.tpl" field="step_number"}
-               </span>{$step_info.step_number}</nobr></th>
+               </span><span {if $edit_enabled} style="cursor:pointer;"
+        onclick="launchEditStep({$step_info.id})"{/if}
+               >{$inc_steps_labels.step_number} {$step_info.step_number}</span></nobr></th>
                <th>{$inc_steps_labels.step_actions}</th>
                {if $session['testprojectOptions']->automationEnabled}
                <th>{$inc_steps_labels.execution_type_short_descr}:
@@ -111,10 +113,8 @@
                {/if}
        </tr>
        <tr>
-               <td>&nbsp;</td>
-               <td colspan="2" {if $edit_enabled} style="cursor:pointer;"
-                   onclick="launchEditStep({$step_info.id})"{/if}
-                   style="padding: 0.5em">{$step_info.actions}</td>
+               <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}">&nbsp;</td>
+               <td colspan="2" style="padding: 0.5em"><div>{$step_info.actions}</div></td>
                {if $edit_enabled}
                <td class="clickable_icon">
                        <img style="border:none;cursor: pointer;"
@@ -133,13 +133,13 @@
                {/if}
        </tr>
        <tr>
-               <th style="background: transparent; border: none"></th>
+               <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}"></td>
                <th colspan="2">{$inc_steps_labels.expected_results}</th>
        </tr>
-       <tr {if $edit_enabled} style="cursor:pointer;"
-           onclick="launchEditStep({$step_info.id})"{/if}>
-           <td>&nbsp;</td>
-               <td colspan="2" style="padding: 0.5em 0.5em 2em 0.5em">{$step_info.expected_results}</td>
+       <tr>
+           <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}">&nbsp;</td>
+               <td colspan="2" style="padding: 0.5em 0.5em 2em 0.5em">
+                       <div>{$step_info.expected_results}</div></td>
        </tr>
        {/foreach}
 {/if}
Index: gui/templates/testcases/tcStepEdit.tpl
===================================================================
--- gui/templates/testcases/tcStepEdit.tpl      (revision 241)
+++ gui/templates/testcases/tcStepEdit.tpl      (revision 242)
@@ -223,7 +223,7 @@
   {else} {* Vertical layout *}
                {foreach from=$gui->tcaseSteps item=step_info}
                        <tr id="step_row_{$step_info.step_number}">
-                               <th width="20">{$args_labels.step_number} {$step_info.step_number}</th>
+                               <th width="20"><a href="{$hrefEditStep}{$step_info.id}">{$args_labels.step_number} {$step_info.step_number}</a></th>
                                <th>{$labels.step_actions}</th>
                                {if $session['testprojectOptions']->automationEnabled}
                                        {if $step_info.step_number == $gui->step_number}
@@ -244,24 +244,24 @@
                                {/if}
                        </tr>
                        <tr>
-                               <td>&nbsp;</td>
+                               <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}">&nbsp;</td>
                                {if $step_info.step_number == $gui->step_number}
                                        <td colspan="2">{$steps}</td>
                                {else}
-                                       <td colspan="2"><a href="{$hrefEditStep}{$step_info.id}">{$step_info.actions}</a></td>
+                                       <td colspan="2"><div>{$step_info.actions}</div></td>
                                {/if}
                        </tr>
                        <tr>
-                               <th style="background: transparent; border: none"></th>
+                               <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}"></td>
                                <th colspan="2">{$labels.expected_results}</th>
                        </tr>
                        <tr>
-                               <td>&nbsp;</td>
+                               <td class="{cycle values="row_color_3,row_color_3,row_color_3,row_color_4,row_color_4,row_color_4"}">&nbsp;</td>
                                {if $step_info.step_number == $gui->step_number}
                                        <td colspan="2">{$expected_results}</td>
                                {else}
                                        <td colspan="2" style="padding: 0.5em 0.5em 2em 0.5em">
-                                       <a href="{$hrefEditStep}{$step_info.id}">{$step_info.expected_results}</a></td>
+                                       <div>{$step_info.expected_results}</div></td>
                                {/if}
                        </tr>
                {/foreach}

Setting Default Font in TestLink

When I first set up TestLink, one of my first actions was to figure out how to force FCKEditor to use a monospace font. Much of our testing takes place in terminals using a monospace font, and I thought it would be easier to engage with the expected results if they were also in a monospace font. This was a fairly easy thing to do using the TestLink and FCKEditor docs, but since I haven’t written it down before, here are the steps using a monospace font by default in TestLink using FCKEditor.

Update 2012-05-08: There is a usable-with-the-patch-command patch available that incorporates all of these changes and more. See the README at the base of the github repo for more details on what’s in that patch.

First, create a file called custom_textarea.css. I placed this in the root of my install, which probably wasn’t the best place for it. The contents are a lightly edited copy of body class from gui/themes/default/css/testlink.css:

body {
    background:     #FFF;
    font-family:    'Courier New', 'Trebuchet MS', Arial, Verdana, sans-serif;
    font-size:      small;
    margin:         0px;
    padding:        0px;
}

The “light editing” I did was to push ‘Courier New’ onto the front of the font-family.  I also changed it so that the edit window background would be white instead of grey by changing the background color.

Then I told FCKEditor to use this CSS as the style for the edit boxes by adding the following line to cfg/tl_fckeditor_config.js:

// Set our own custom css (sets white background and mono-space font)
FCKConfig.EditorAreaCSS = FCKConfig.BasePath + '../../../custom_textarea.css';

This did accomplish the task that I had set for myself, which was changing the default font displayed by FCKEditor when editing text.  However, I also assumed that it would, when the text in the editor was saved, cause that saved text to be displayed in a monospace font.  It turns out that this didn’t work though.  I can’t decide if this is a bug in TestLink or not, but these defaults don’t get applied when the text is displayed.

I spent quite a bit of time looking for the correct knob to fix this in the TestLink docs and the FCKEditor docs, and I couldn’t find one.  Font editing works, but you have to explicitly change the font option while editing to make it work.

What I ended up doing was to edit the two Smarty templates used for displaying steps so that each action and step were wrapped in a div I could control, and then changed the style for that div so that the default font was monospaced.  In a way this was actually a better solution than a general FCKEditor knob because it allowed me to just change the default font in action/expected results, and not other text, like Summary, that might look better as a variable-width font.

To achieve this I first added two new classes to gui/themes/default/css/custom.css.  This could have been done with just one class, but I liked the idea of being able to change the style of actions and results independently in the future.

div.c_actions, div.c_expected_results {
    font-family: 'Courier New', Courier, monospace;
}

Then I added the class to inc_steps.tpl and tcStepEdit.tpl.

--- inc_steps.tpl.dist  2011-08-22 21:08:21.000000000 -0500
+++ inc_steps.tpl       2011-09-26 09:42:25.000000000 -0500
@@ -53,10 +53,10 @@
                                size="{#STEP_NUMBER_SIZE#}"
                                maxlength="{#STEP_NUMBER_MAXLEN#}">
                        {include file="error_icon.tpl" field="step_number"}
                        </span>{$step_info.step_number}
                </td>
-               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$step_info.actions}</td>
-               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$step_info.expected_results}</td>
+               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}><div class="c_actions">{$step_info.actions}</div></td>
+               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}><div class="c_expected_results">{$step_info.expected_results}</div></td>
                {if $session['testprojectOptions']->automationEnabled}
                <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$gui->execution_types[$step_info.execution_type]}</td>
                {/if}
--- tcStepEdit.tpl.dist 2011-09-22 10:27:23.000000000 -0500
+++ tcStepEdit.tpl      2011-09-26 09:43:47.000000000 -0500
@@ -211,8 +211,8 @@
        {/if}
       {else}
         <td style="text-align:left;"><a href="{$hrefEditStep}{$step_info.id}">{$step_info.step_number}</a></td>
-               <td ><a href="{$hrefEditStep}{$step_info.id}">{$step_info.actions}</a></td>
-               <td ><a href="{$hrefEditStep}{$step_info.id}">{$step_info.expected_results}</a></td>
+               <td ><a href="{$hrefEditStep}{$step_info.id}"><div class="c_actions">{$step_info.actions}</div></a></td>
+               <td ><a href="{$hrefEditStep}{$step_info.id}"><div class="c_expected_results">{$step_info.expected_results}</div></a></td>
         {if $session['testprojectOptions']->automationEnabled}
                  <td><a href="{$hrefEditStep}{$step_info.id}">{$gui->execution_types[$step_info.execution_type]}</a></td>
                {/if}

These aren’t exactly what my diffs look like since I removed the links from the display text last week, but I believe it will work.

Better Copy/Paste When Editing Test Steps in TestLink

My current biggest peeve with TestLink is how hard TestLink makes it to copy text out of test steps when editing a test case. Both when viewing a case and when editing test case steps via the Test Specification interface, clicking on the text of a test step causes you to start editing the text in that step.

I find this behavior very off-putting. I constantly find myself trying to copy in these views, either to copy repetitive actions from a previous step, or to do a dry-run executing a test case. I finally got mad enough today to spend the time figuring out how to change this behavior.

Update 2012-05-08: There is a usable-with-the-patch-command patch available that incorporates all of these changes and more. See the README at the base of the github repo for more details on what’s in that patch.

There are two Smarty templates that control the layout of these views, both of which live in gui/templates/testcases/. inc_steps.tpl controls the layout when viewing a test case (but not editing steps), and tcStepEdit.tpl controls the layout when editing steps.

After applying these patches, you can copy text out of the Step Action and Expected Results columns. To edit the row as before the patch, click on the row counter (the first cell in the row).

These patches are against TestLink 1.9.3

--- inc_steps.tpl.dist  2011-08-22 21:08:21.000000000 -0500
+++ inc_steps.tpl       2011-09-22 10:08:55.000000000 -0500
@@ -53,10 +53,10 @@
                                size="{#STEP_NUMBER_SIZE#}"
                                maxlength="{#STEP_NUMBER_MAXLEN#}">
                        {include file="error_icon.tpl" field="step_number"}
-                       </span>{$step_info.step_number}
+                       </span><div {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$step_info.step_number}</div>
                </td>
-               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$step_info.actions}</td>
-               <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$step_info.expected_results}</td>
+               <td>{$step_info.actions}</td>
+               <td>{$step_info.expected_results}</td>
                {if $session['testprojectOptions']->automationEnabled}
                <td {if $edit_enabled} style="cursor:pointer;" onclick="launchEditStep({$step_info.id})" {/if}>{$gui->execution_types[$step_info.execution_type]}</td>
                {/if}
--- tcStepEdit.tpl.dist 2011-09-22 10:27:23.000000000 -0500
+++ tcStepEdit.tpl      2011-09-22 10:39:55.000000000 -0500
@@ -211,8 +211,8 @@
        {/if}
       {else}
         <td style="text-align:left;"><a href="{$hrefEditStep}{$step_info.id}">{$step_info.step_number}</a></td>
-               <td ><a href="{$hrefEditStep}{$step_info.id}">{$step_info.actions}</a></td>
-               <td ><a href="{$hrefEditStep}{$step_info.id}">{$step_info.expected_results}</a></td>
+               <td >{$step_info.actions}</td>
+               <td >{$step_info.expected_results}</td>
         {if $session['testprojectOptions']->automationEnabled}
                  <td><a href="{$hrefEditStep}{$step_info.id}">{$gui->execution_types[$step_info.execution_type]}</a></td>
                {/if}

I’ve been writing test cases with this change in place all morning and it is much, much nicer than the default behavior

Alternating Test Step Row Colors in TestLink

Working on implementing TestLink at work for better testing process flow. Very few complaints about the product as a whole – it can feel ponderous at times, but testing is a big problem, and TestLink is the best tool I’ve found for addressing them all.

The only real negative feedback I’ve received so far is regarding the display of steps from individual test cases. By default, the entire table is the same color, and it’s very difficult to visually track which row is which. It seems like such an obvious problem that I assumed I had missed a knob to tweak, but I can’t find anything about it in the docs, the forums, or the bug tracker.

I poked around a bit tonight and the solution turned out to be ridiculously (but pleasingly) simple.

Update 2012-05-08: There is a usable-with-the-patch-command patch available that incorporates all of these changes and more. See the README at the base of the github repo for more details on what’s in that patch.

First, add the following to gui/themes/default/css/custom.css:

.row_color_1 {
    background-color:   #DDDDDD;
}
.row_color_2 {
    background-color:   #CCCCCC;
}

Then, patch the following two files in gui/templates/testcases/ like so (original files were from 1.9.3):

--- inc_steps.tpl.dist  2011-08-22 21:08:21.000000000 -0500
+++ inc_steps.tpl       2011-08-22 21:13:02.000000000 -0500
@@ -45,7 +45,7 @@
        </tr>
        {* BUGID 3376 *}
        {foreach from=$steps item=step_info}
-       <tr id="step_row_{$step_info.step_number}">
+       <tr id="step_row_{$step_info.step_number}" class="{cycle values="row_color_1,row_color_2"}">
                <td style="text-align:left;">
                        <span class="order_info" style='display:none'>
                        <input type="text" name="step_set[{$step_info.id}]" id="step_set_{$step_info.id}"
--- tcStepEdit.tpl.dist 2011-09-22 10:27:23.000000000 -0500
+++ tcStepEdit.tpl      2011-09-22 10:39:55.000000000 -0500
@@ -197,7 +197,7 @@
   {* this means we have steps to display *}
   {if $gui->tcaseSteps != ''}
        {foreach from=$gui->tcaseSteps item=step_info}
-         <tr id="step_row_{$step_info.step_number}">
+         <tr id="step_row_{$step_info.step_number}" class="{cycle values="row_color_1,row_color_2"}">
       {if $step_info.step_number == $gui->step_number}
                    <td style="text-align:left;">{$gui->step_number}</td>
                  <td>{$steps}</td>

Blow away the cached .css files, and voila! Alternating background colors for test steps in TestLink.

Before: After:

I tried to post this as a hint in the TestLink forum but I honestly couldn’t figure out how to register a forum account. I did post a comment on a related bug in their issue tracker, ticket 3583

EDIT 2011-09-22: The original version of this post only included a change to inc_steps.tpl. Added the patch to tcStepsEdit.tpl to apply alternation to the rows in the test case step edit view also.

EDIT 2011-09-26: Updated to include the correct full path to custom.css