Friday, April 5, 2013

WhatTheFrak: Test Indicator in TestComplete breaks my Test Cases!

I am currently working on an assignment where we use TestComplete to run their automated web test cases.

I found something that made me go "What The Frak" last week that I would love to share.

Running the tests locally I was getting the ever so annoying sometimes-it-fail-sometimes-it-just-works behavior on a few test cases. The same scenario every time. Test ran as expected up until a point where it's suppose to click a button, after the click is made the new page is not loaded.

I was looking in the logs and it look like everything was ok. It would locate the correct object to click. Calculate the correct x and y co-ordinates. Move the mouse to the correct position. Fire a click. Looking at the screen shoot that is taken it looks like TestComplete was clicking exactly where it was suppose to click. But still the new page wouldn't load.

I enter the system manually to click the button in different scenarios only half expecting it randomly not to work. But the button worked perfectly every time.

I then realized that it only happened on a few select buttons all located in the upper right corner. So I ran through the tests that sometimes would fail watching the upper right corner like a hawk. And that's when I noticed that the TestComplete Indicator has a pop up text box displaying log information, the pop up changes size depending how much text is in it. We had made some changes to logging and sometime it would get pretty large. Maybe 3 times the width of the Indicator itself.

When I watched it carefully I saw that sometimes the popup text would get big enough to cover some of the buttons in the system that we use in the text.

Not believing it could actually be true I did some tests. After starting a test I immediately paused it.
Then placed a windows with a button half way under the pop up. When I tried to click through the pop up nothing happened. Trying to clicking outside the pop up, of course, worked perfectly.

So what happened to the test where that the Indicator pop up blocked the button and my tests clicked the pop up instead! Which, naturally, didn't load the expected page.
*Sigh*
I know you don't believe me so I added two example pictures below.

Image 1: Hovering over the blocked part of the settings button gives no indication that I have the mouse over it. Clicking does nothing.

Image 2: Hovering over the unblocked part of settings button gives an indication that has a mouse over it. This is happening even if the window is not active. Clicking it opens the menu.


I still have a hard time believing how SmartBear could do this. It feels like such an obvious mistake.

Solution

The solution was to hide the indicator before we clicked and showing it after clicking has been done.
Indicator.hide();
// Do the clicking
Indicator.show();

When we run the tests in our continuous integration environment we hide it permanently. Just to make sure it does not mess with any of our tests in some way.

Now all the tests run smoothly and all clicks go through as expected!
And there was much rejoicing.



Friday, October 26, 2012

Getting Started with node.js on Ubuntu

This is a small getting started guide for getting up and running with node.js on Ubunutu.

Step 0: DON'T install node.js from Ubuntu Software Center.
When I started messing about with node.js the first thing I did was to install node.js from Ubuntu Software Center. But soon I started using it I realised that some of the stuff that my friends where using, like npm ( more on that later ) was missing. I check the version and realised that the version I got from UBC was 0.2.6 while the latest verision was 0.8.12. So i quickly removed it from UBC and headed online.

Step 1: Install from nodejs.org  
Head to http://nodejs.org
Clicking the "Install" link will give you the latest version tar.gz
Extract the content to somewhere good, this example i will use ~/code/
Enter your terminal and go to the folder, cd ~/code/node-v0.8.12
Read through README.md carefully ( lol! )
>./configure
stuff happen
>make
more stuff happen
>sudo make install

Restart your terminal


Step 2: Start Server
Copy the following code to a file called node_js_getting_started.js
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Running node.js\n');
}).listen(1234, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1234/');
Or download the file here node_js_getting_started.js

Now run the command >node node_js_getting_started.js
And you should see
Server running at http://127.0.0.1:1234/

Step 3: Test it
Open a browser and go to http://127.0.0.1:1234/
and now you should see "Running node.js" in your browser.
We got a webserver with node.js up and running! Yay!


Friday, September 28, 2012

Shellshocked! - Powershell basics

This is a basic FAQ, reference table, cheat sheet, dummies guide, whatever you want to call it for Microsoft Powershell.


I started using Powershell regularly recently at my current assignment at a company that does Business Intelligence and only use Windows based systems.  I decided to document my recently acquired knowledge for my own good and I thought that maybe it'll be help to someone else out there. This is by no means a complete reference to Powershell, it's just a collection of the stuff I use the most. And I'll be adding more and more to it as time progresses.
If you spot any errors or can suggest improvements please let me know.

Running Scripts

You might get an error the first time you try to run a powershell script on a new computer, the error you get will look something like this.
File C:\scripts\test.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.
To fix this you need to open Powershell in Administrator mode and run
Set-ExecutionPolicy RemoteSigned
Now it should be possible to run your scripts.

Commands

Create Directory
Let's say we want to create a folder called "Appname" in our Apps folder.
new-item C:\ProgramData\Corp\Apps\Appname -itemtype directory

Wait for input
If you want user input you can use Read-Host
$a = Read-Host "Press enter to End"

Write to Screen
Write-Host "Hello World"

Download file from Internet
Want to download something from the web? No problem. Create a Webclient object and use DownloadFile.
$webclient = New-Object System.Net.WebClient
$url = "http://1.bp.blogspot.com/_OwDmc6qLkkw/TL3V8Xwg_2I/AAAAAAAAA8w/rzC294WegB4/S220/jonas_bw.jpg"
$file = "good_looking_guy.jpg"
$webclient.DownloadFile($url,$file)
>> WebClient at MSDN

Fun Trivia 

When writing this Google's Chrome gave me a typo warning for "Powershell" and suggested "Powers-hell". Coincidence? :)

Friday, April 13, 2012

Running SQL commands on Sybase from Hudson

This post means to describe the several problems i found when trying to run SQL commands on Sybase from Hudson.

Problem 1: Host key verification failed”
Problem: When trying to SSH to the server which holds the Sybase database I got "Host key verification failed" even thought they keys were correct.
Solution: The missing piece of the puzzle was a row in the ~/.ssh/known_hosts file.
By using another user, which uses the same private/public key, I could run a ssh to the sybase server and get a row in that users known_hosts file. Then I just copied that row to
/var/lib/hudson/.ssh/known_hosts and voila everything worked.
Learn more:
http://amath.colorado.edu/computing/unix/sshknownhosts.html

Problem 2: Shell profile not loaded when running one-line ssh
Problem: The script we need to run on the server needed a lot of magic that was set up by the shell profile scripts. When ssh:ing to the server the profiles scripts are run and everything is dandy. But from Jenkins I need to use one-line ssh commands like this.
ssh user@server "isql < lots_of_stuff.sql" But when running one-line ssh the profile is NOT loaded and and I get a lot of errors since the magic is not set up. Solution: Load the profile in the ssh one-liner before running the real command. ssh user@server ". ./.profile; isql < lots_of_stuff.sql"

Problem 3: Incorrect Locale
After solving the two problems above I was sure everything would work fine, but no, of course it didn't.
Instead of the expected SQL response I got:
The context allocation routine failed when it tried to load localization files!!
One or more following problems may caused the failure

Your sybase home directory is /opt/sybase. Check the environment variable SYBASE if it is not the one you want!
Using locale name "POSIX" defined in environment variable LC_ALL
An error occurred when attempting to allocate localization-related structures.
Locale name "POSIX" doesn't exist in your /opt/sybase/locales/locales.dat file

POSIX? It could make a grown man cry :~(
Solution: Adding -v, for verbose, to the ssh command I could quickly see the difference between what Hudson was doing and what happened when running it from my own machine.
Hudson:
...
debug1: Sending environment.
debug1: Sending env LC_ALL = POSIX
debug1: Sending command: . ./.profile; isql < lots_of_stuff.sql


Locally:
...
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: . ./.profile; isql < lots_of_stuff.sql

No locale is sent from my local machine so I tried overriding it before sending the command in Hudson and it worked.
export LC_ALL=;
ssh sybase@inttestsbn.its.sec.intra '. ./.profile;isql < lots_of_stuff.sql'

And it works!

Thursday, January 12, 2012

Ultimate Password Solution using Dropbox and KeePassX

Today I found the ultimate password management solution using Dropbox and KeePassX.

I wanted a secure enough solution that can be used and managed on multiple computers. My old solution was a .txt file in Dropbox with a name that hopefully nobody would look in. But today I migrated the solution to KeePassX using a encrypted database saved as a file in Dropbox.

Another problem I had was that I couldn't download my entire Dropbox account to work since it takes to much space. But nowadays Dropbox for Linux can handle Selective Sync, i.e. only check out selected folders and not everything.

Here is how you can get the same set up step by step.
Written assuming you have a Dropbox account and the folder where you want to keep the password file is already created.

Step 1: Install Dropbox
https://www.dropbox.com/install

Step 2: Check out the folder where you want to save the password database
https://www.dropbox.com/help/175

Step 3: Install KeePassX
Use synaptic package manager or link below.
http://keepass.info/download.html

Step 4: Create new database in KeePassX
Generate new file and save it in your Dropbox folder
Add secure password ( http://www.generate-password.com/ )

Step 5: Add your entries to KeePassX

Step 6: Repeat step 1 - 3 on all your computers.
Instead of creating a new database connect to the file you created in your Dropbox folder.

That's It and now you are in password management heaven!

Enjoy!

Wednesday, December 28, 2011

Classes and Test Jars and Poms Oh My. Building a TestCoverage Test takes them all.

After spending a few days on getting a complicated coverage test working I really feel I should document it.

My setup is that I have 3 maven projects. One parent project and two subprojects, one for functional testing and one for coverage tests. The crux I had with this assignment was that the coverage project needed to be able to read classes and their annotations from it's sister projekt functional to determine what it actually tested.

Overview of the maven project set up
/xmltest
   /xmltest-functional
   /xmltest-coverage


Description
xmltest : This is the parent project, it does nothing in it self.
xmltest-functional : The functional tests
xmltest-coverage : The coverage test what I was building

Creating a Test Jar
First step was to get this working was to set up my xmltest-functional project so it would create a test-jar with all the test classes. For this I used maven-jar-plugin to add a new execution.

In /xmltest/xmltest-functional/pom.xml
<project>
...
  <build>
    <plugins>
    ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.2</version>
        <executions>
          <execution>
            <goals>
              <goal>test-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin> 
      ...


Did it work?
Now, after running mvn clean install, there is a tests.jar created which contain all the test classes in our functional project.
~/.m2/repository/com/companyx/xmltest/xmltest-functional/2.0.0-SNAPSHOT$ ls -l
xmltest-functional-2.0.0-SNAPSHOT.jar
xmltest-functional-2.0.0-SNAPSHOT.pom
xmltest-functional-2.0.0-SNAPSHOT-tests.jar


So?
And now I can use that jar in our coverage project. First we need to add a dependency to the functional project in our pom. We want to use the "tests.jar" so we set classifier and scope to tests and test.

In /xmltest/xmltest-coverage/pom.xml
...
    <dependency>
      <groupId>com.companyx.xmltest</groupId>
      <artifactId>xmltest-functional</artifactId>
      <version>2.0.0-SNAPSHOT</version>
      <classifier>tests</classifier>
      <scope>test</scope>
    </dependency>


Adding the normal dependency
But that is not all, we also need to add the normal dependency so that when in create class objects of what we find we don't get errors.

In /xmltest/xmltest-coverage/pom.xml
...
    <dependency>
      <groupId>com.companyx.xmltest</groupId>
      <artifactId>xmltest-functional</artifactId>
      <version>2.0.0-SNAPSHOT</version>
    </dependency>


Writing the Test
Now, what we need to do is to write the coverage test.

A typical test class

package com.companyx.xmltest.functional;

...

@Path("/image/{id}")
@Test
public class ImageControllerGetTest {


Coverage Test
Now, finally, I can write a test which scans in the classpath for classes with are annotated with @Test, loops through all that have the correct package, checks if they have the @Path annotation and get the annotation.

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Test.class));
      
for (BeanDefinition bd : scanner.findCandidateComponents("com.companyx.xmltest.functional")) {
   
try {
   Class clazz = Class.forName(bd.getBeanClassName());
   if( hasPathAnnotation(clazz) ){
      Annotation annotation = clazz.getAnnotation(Path.class);


And so on and so forth
And you'll just have to imaging that we do the same for the controller classes, puts it all into two lists and compare the lists. But I'm sure you can figure out how to do this :)

Why don't you just filter on Path.class instead of Test.class
I am sure someone would ask this if I actually had any readers.
Good question and the reason we do this is because we want to find test classes which has missed being annotated with @Test. It happens and we want to catch those cases as well.

That's It
I hope you got something out of this, I sure learnt a lot while writing it.
Hope to see you again in the next blog post.

And remeber:

"To error is human, to test is divine"






Maven Ninja Moves

I'll round of with some good commands my Mentor taught me.

mvn versions:display-plugin-updates
Gives you a list of plugs you can update.

mvn versions:display-dependency-updates
Gives you a list of dependencies you can update.

Monday, November 28, 2011

Recovering deleted files from an svn repository

Hi

This posts show how to recover a deleted file in Subversion.
Assuming the file is called "VeryImportantFile.java" and it was deleted by mistake by the sloppy developer John Doe.

1. Get svn log
Assuming the file is to big to work with in the terminal we save the output
>svn log --verbose > svn_log_verbose

2. Open file in text editor
>gedit svn_log_verbose

3. Find the commit that delete it
Ctrl+F "VeryImportantFile.java"

Fixed stuff in the system
------------------------------------------------------------------------
r53308 | john_doe | 2011-11-17 13:15:39 +0100 (Thu, 17 Nov 2011) | 1 line
Changed paths:
M /trunk/xmlapi-test/src/test/java/com/RegularFile.java
A /trunk/xmlapi-test/src/test/java/com/NewFreshFile.java
D /trunk/xmlapi-test/src/test/java/com/VeryImportantFile.java

4. Revert it
You need to use one revision BELOW the one that deleted it.
> svn up -r 53307 src/test/java/com/VeryImportatFile.java
A src/test/java/com/VeryImportantFile.java
Updated to revision 53307.

5. Add to repo
> svn cp -r 53307 src/test/java/com/VeryImportantFile.java svn://svn.project.com/java/trunk/xmlapi-test/src/test/java/com/VeryImportantFile.java
Now you are promted default text editor to enter commit message. Enter message, save file and Exit to commit.
( cp is short for copy )

6. Update Repo
> svn up
U src/test/java/com/VeryImportantFile.java
Updated to revision 53790.

Now the file is reverted and back in repo! Life could not be better!