Archive

Author Archive

Live reload with gruntjs

March 17, 2015 Leave a comment

Create a folder with any name you want (eg. “grunt-reload”) and create a file named “package.json” with the following contents:

{
  "name": "grunt-reload",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-express": "~1.2.1",
    "grunt-open": "~0.2.3",
    "matchdep": "~0.3.0"
  }
}

Run npm to install dependencies:

npm install

Create a file gruntfile.js with the following contents. Pay attention to change the base folder of the server to match the folder where you are creating the files fot this tutorial.
Also note that I’m specifying Firefox as the browser.

module.exports = function(grunt) {
// Load Grunt tasks declared in the package.json file
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

// Configure Grunt
grunt.initConfig({

// Grunt express - our webserver
// https://github.com/blai/grunt-express
express: {
    all: {
        options: {
            bases: ['C:/Users/lestivalet/Downloads/grunt-reload'],
            port: 8080,
            hostname: "0.0.0.0",
            livereload: true
        }
    }
},

// grunt-watch will monitor the projects files
// https://github.com/gruntjs/grunt-contrib-watch
watch: {
    all: {
            files: '**/*.html',
            options: {
                livereload: true
        }
    }
},

// grunt-open will open your browser at the project's URL
// https://www.npmjs.org/package/grunt-open
open: {
    all: {
        path: 'http://localhost:8080/index.html',
        app: "firefox"
    }
}
});

// Creates the `server` task
grunt.registerTask('server', [
    'express',
    'open',
    'watch'
    ]);
};        

Create an html file (call it index.html) with the following boilerplate code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Grunt!</title>
</head>
<body>
    Hello Grunt!
</body>
</html>        

Start the server with the following command:

grunt server

After running the command you’ll notice that Firefox will open automatically the index.html file.

Keep the browser window opened and make same changes in the index.html file. After saving it should automatically be reloaded by the browser.

Categories: Uncategorized Tags: ,

Part 4: Trac Installation

September 27, 2012 Leave a comment

Trac

Download Trac from http://trac.edgewall.org and XMLRPC plugin for Trac from http://trac-hacks.org/wiki/XmlRpcPlugin. Transfer them to your virtual server.

scp Trac-0.12.2.tar.gz xmlrpcplugin-r10897.zip root@10.200.242.97:/tmp

Now go to your temporary folder in the virtual server and move Trac tarball to /usr/local and extract it

cd /tmp
mv Trac-0.12.2.tar.gz /usr/local
cd /usr/local
tar zxvf Trac-0.12.2.tar.gz
cd Trac-0.12.2

Create a subversion repository for Trac

svnadmin create /services/svn/repositories/trac

Install Trac using the following commands:

python ./setup.py install
mkdir -p /services/trac/projects
trac-admin /services/trac/projects/googleadvsearch initenv
      Project Name: GoogleAdvancedSearch
      Database Connection: : sqlite:db/trac.db]
chown -R www-data.www-data /services/trac/
find /services/trac/ -type d|xargs chmod g+sw
htpasswd -cm /services/trac/projects/googleadvsearch/.htpasswd admin
trac-admin /services/trac/projects/googleadvsearch/
      Trac admin console is displayed. Type the following:
Trac [/services/trac/projects/googleadvsearch]> permission add admin TRAC_ADMIN
Trac [/services/trac/projects/googleadvsearch]> quit

Test Trac installation:

tracd --port 8000 /services/trac/projects/googleadvsearch

Open a web browser and point it to your virtual server in port 8000 (http://10.200.242.97:8000). Remember to change to your IP. You should see the following screens:

Create /etc/apache2/trac.conf file with the following content:

<Location>
    SetHandler mod_python
    PythonInterpreter main_interpreter
    PythonHandler trac.web.modpython_frontend
    PythonOption PYTHON_EGG_CACHE /tmp/python_egg_cache
    PythonOption TracUriRoot /trac
    PythonOption TracEnvParentDir /services/trac/projects/
    AuthType Basic
    AuthName "trac-googleadvsearch"
    AuthUserFile /services/trac/projects/googleadvsearch/.htpasswd
    Require valid-user
</Location>

Open /etc/apache2/apache2.conf file and add it at the end:


Include /etc/apache2/trac.conf

XMLRPC Plugin

Go back to temporary folder, extract plugin zipped file and install it using the following commands:

cd /tmp
unzip xmlrpcplugin-r10897.zip
cd xmlrpcplugin/trunk
python setup.py bdist_egg
cp dist/*.egg /services/trac/projects/googleadvsearch/plugins/

Now edit /services/trac/projects/googleadvsearch/conf/trac.ini file and it in the end the following:

[components]
tracrpc.* = enabled

Restart apache:

apachectl restart

Open a web browser again and point it to Trac in the virtual server http://10.200.242.97/trac (change IP)

Log in using admin/admin (or other user/password you chose in previous steps)

Choose GoogleAdvSearch project:

Click in Admin

Select Permissions

In “Grant Permission” section add information below and click Add button:

  • Subject: anonymous
  • Action: XML_RPC

Categories: Tutorial

Part 5: TestLink-Trac Integration

September 27, 2012 Leave a comment

TestLink-Trac Integration

To make the integration work you need to change some files:

Edit /var/www/testlink/cfg/trac.cfg.php file:

/** Trac Project Root */
define('BUG_TRACK_DB_HOST', 'http://172.16.9.137/trac/');
define('BUG_TRACK_XMLRPC_HOST', 'http://admin:admin@172.16.9.137');

/** @var array Mapping TL test project name vs trac project url */
$g_interface_bugs_project_name_mapping = array(
     'Expresso' => 'expresso',
);

Edit /var/www/testlink/custom_config.inc.php file:

<?php
     $g_interface_bugs = 'TRAC';
?>

Edit /var/www/testlink/lib/bugtracking/int_trac.php file and replace:

$this->xmlrpcClient = new IXR_Client($this->dbHost . '/xmlrpc');

by

$this->xmlrpcClient = new IXR_Client(BUG_TRACK_XMLRPC_HOST);

Edit /var/www/testlink/third_party/xml-rpc/class-IXR.php file and add lines marked with “–>”:

function query() {
    $args = func_get_args();
    $method = array_shift($args);
    $request = new IXR_Request($method, $args);
    $length = $request->getLength();
    $xml = $request->getXml();
    $r = "\r\n";
-->    $credentials = "";
-->    if ($this->user != "") {
-->        $credentials = base64_encode($this->user . ":" . $this->pass);
-->    }
    $request = "POST {$this->path} HTTP/1.0$r";
    $request .= "Host: {$this->server}$r";
-->    if ($credentials != "") {
-->        $request .= "Authorization: Basic {$credentials}$r";
-->    }

    function IXR_Client($server, $path = false, $port = 80, $timeout = false) {
        if (!$path) {
            // Assume we have been given a URL instead
            $bits = parse_url($server);
            $this->server = $bits['host'];
            $this->port = isset($bits['port']) ? $bits['port'] : 80;
-->            $this->user = isset($bits['user']) ? $bits['user'] : '';
-->            $this->pass = isset($bits['pass']) ? $bits['pass'] : '';
Categories: Tutorial

Part 1: Preparing a virtual server using VirtualBox

September 27, 2012 1 comment

Pre Requisites

  • Download and install VirtualBox – I have a Ubuntu 12.04 but the instructions here apply to any operation system, including Windows or OS X or Solaris
  • Download Debian CD 1 image. At time of writting this tutorial, Debian is in 6.0.5 version

Instructions

Let’s prepare VirtualBox to install a Debian virtual server. It’s an easy task, just follow instructions below. The very first time you open VirtualBox, we have no virtual machine configured yet. To create one, click on New button.

VirtualBox will open an wizard. We just need to follow wizard’s steps as below.

Here is the wizard’s first window. It’s a welcome screen with Next, Back, Cancel buttons. Click on Next button.

Let’s define a name for our server. I’ll be using “TestServer”. This name is used just to identify the virtual machine in VirtualBox. It’ not the host name. Virtual machine’s host name will be defined when installing Debian.

Choose “Linux” in “Operating System” combo box and  “Debian” (32 bits version) in “Version” combo box. I haven’t tested 64 bit version although VirtualBox has support for it. Feel free to try 64 bit version, I think the instructions below will also work for it.

Now let’s set the memory size. Wizard’s recommendation is 384 MB. We will be using 512 MB, I think it will be enough to run a base system with Gnome interface. You should have at least 2GB RAM in the host machine to avoid  system laziness. The best set up would be 4GB. 25% of the memory will be dedicated to the virtual server.

We need a virtual hard drive. Since this is the first time we are creating a virtual machine, let’s check “Start-up Disk” and select “Create new hard disk”. We can have multiple hard drives in a virtual machine, put for simplicity let’s create just one.

Choose “VDI (VirtualBox Disk image)” type.

Now choose “Dynamically allocated” insted of “Fixed size”. Dynamically allocated advantage is that we don’t need to worry about  har drive size as we add new software to our virtual server. Hard drive size will grow as needed. The limit will be free space in the hard drive’s host machine.

In the next screen, in Location field, wizard already fills with default path to store virtual hard drives. VirtualBox created a “VirtualBox VMs” folder inside your /home. In this folder it creates a subfolder whose name is the virtual machine name we created in the first step – in this case is “TestServer”. VirtualBox will create and store virtual server’s hard drive VDI file inside of it. In my machine setup it created the virtual hard drive in /home/luiz/VirtualBox VMs/TestServer/TestServer.vdi

Virtual hard drive default size is 8GB. In our case, since we have created a dynamically allocated virtual hard disk, it doesn’t matter, so let’s keep the default and not worry about it.

Now a summary is shown with all options we chose in the previous screen. Confirm that everything is OK and then click on Create button to create a virtual hard drive for our machine.

The last screen is another summary with all information we provided in all previous screens. If everything is OK click on Create button to create the virtual machine.

Going back to VirtualBox main screen we can see “TestServer” virtual box listed at left. At right we have TestServer’s configurations like memory, boot sequence, video memory, storage information. Scroll down to see all of them. After being created virtual machine status is “Powered Off”. To boot it just click on  “Start” green button.

Since we still don’t have any operational system instaled in the virtual server, after clicking on “Start”, a new wizard (First Run Wizard) window is shown:

This is just another welcome screen with some information about the steps needed to install an operational system in the virtual server. Click on Next button to go to the next wizard window.

Let’ select an operation system media. We will be using ISO image that we have downloaded from Debian’s site. Just browse for debian-6.0.5-i386-CD-1.iso file. Please note that we just need to download the first CD.

A summary screen is shown. Click on Start button to boot our virtual server.

In the next part we will be installing Debian. See ya.

Categories: Tutorial

Part 3: Testlink installation

September 27, 2012 Leave a comment

About Testlink

TestLink is a web based Test Management and execution system. The tool includes test specification, planning, reporting, requirements tracking and collaborate with well-known bug trackers like Mantis, Trac and Bugzilla.

TestLink enables easily to create and manage Test cases as well as organize them into Test plans. These Test plans allow team members to execute Test cases and track test results dynamically, generate reports, trace software requirements, prioritize and assign tasks.

TestLink benefits:

  • Open source so no costs
  • Easy to use with multiple projects
  • Central respository for all test cases
  • Central repository for test execution results
  • Report generation

Installation

If you downloaded the file in the host machine then you must copy testlink installation file to virtual server temporary folder. You can skip this step if you downloaded the file directly in the virtual server.

scp testlink-1.9.4.tar.gz root@10.1.1.2:/tmp

Now in virtual server as root go to temporary folder, extract installation file and move it to apache folder:

mv testlink-ga-testlink-code testlink
mv testlink /var/www
chmod 777 -R /var/www/testlink/

Open a web browser in the host machine and access TestLink using the following URL: http://10.1.1.2/testlink (remember to change to your IP). Select “New Installation”. If you want to install using virtual machine open a web browser and point to http://localhost/testlink.

UPDATE: For version 1.9.4 I had to create some additional folders. Otherwise the installation process will not start:

mkdir -p /var/testlink/logs
mkdir -p /var/testlink/upload_area
chown -R www-data.www-data /var/testlink

The install process is divided in 5 steps:

  1. Acceptance of License – Read and accept license by checking “I agree to the terms set out in this license.”
    TestLink install page 1

    TestLink install page 1

    TestLink install page 2

    TestLink install page 2

  2. Verification of System and configuration requirements – The installer checks your system to make sure all requirements are satisfied for installing TestLink. If your server is missing needed software for installation please install it. If you have been following this tutorial series it should be ok and no other action would be necessary at this point. When “Your system is prepared for TestLink configuration (no fatal problem found).” message is shown, click on “Continue”.

    TestLink install page 3

    TestLink install page 3

  3. Definition of DB access – We have installed PostgreSQL in our server so let’s use it. TestLink also supports MySQL. Type ‘testlinkdb’ for database name field.

    TestLink install page 4

    TestLink install page 4

  4. Create DB, testlink DB user, structures and default data & create configuration file. – Fill in with postgres user and password (remember in last tutorial we changed the password to ‘postgres’). Enter with the non root user you created during Debian installation  for testlink DB login and choose a password.

    TestLink install page 4

    TestLink install page 4

  5. Verify the procedure result and continue to TestLink login – Verify if the install procedure was finished with success.

    TestLink install page 5

    TestLink install page 5

Enabling XMLRPC

XMLRPC is disabled in the default installation. We need to enable it to allow automated tests to run. To do that open /var/www/testlink/config.inc.php file and change the following variables:

$tlCfg->api->enabled = TRUE;
$tlCfg->exec_cfg->enable_test_automation = ENABLED;

Restart apache:

apachectl restart
Categories: Tutorial

Part 6: Jenkins installation

September 27, 2012 Leave a comment

Jenkins Installation

We need to download maven from http://maven.apache.org and jenkins from http://jenkins-ci.org. You can download it directly from the virtual server (easy option). If you downloaded them in the host machine then you need to follow step below:

Transfer downloaded files to the virtual server, you can open a terminal in the host machine and use the ‘scp’ command:

scp apache-maven-3.0.3-bin.tar.gz jenkins.war root@10.200.242.97:/tmp

Make sure you have ‘scp’ available in your system and do not forget to change the IP. The ‘scp’ command copy files and directories securely between remote hosts without starting an FTP session or logging into the remote systems explicitly through SSH. So also make sure you have configured correctly your server following the instructions provided in the tutorial.

Now go to the virtual machine. You can use the virtual machine directly in the VirtualBox window or if you prefer, you can open a SSH session from the host machine. Either way is fine. If you want to do ssh you can use the following command:

ssh -l root 10.200.242.97

Remember to change the IP according to your set-up.

Our files are in virtual server’s temporary folder. You can choose any local to install them but I prefer to put them in /usr/local/jenkins. Create jenkins folder and move the files to it and extract only apache maven file.

cd /usr/local
mkdir jenkins
cd jenkins
mv /tmp/jenkins.war .
mv /tmp/apache-maven-3.0.4-bin.tar.gz .
tar zxvf apache-maven-3.0.4-bin.tar.gz

Start jenkins with root user. You can also start with the non root user we created during Debian’s installation.

java -jar jenkins.war

Wait a little bit until you see “INFO: Jenkins is fully up and running”. Now open a browser in the host and enter the following URL: http://10.200.242.97:8080. Always remember to change the IP or put localhost if your using hte virtual machine. Jenkins should be running in port 8080 and the main screen should be displayed:

We need to configure Jenkins. Click on “Manage Jenkins” links in the left.

To install Testlink plug in click on “Manage Plugins”

Change to Available tab to list all jenkins plugins available to install. Locate TestLink Plugin and check it. Scroll to the end of page and hit “Install” button.

Jenkins will automatically download and install the plugin for you. Wait until it finishes the operation. Make sure you have checked “Restart Jenkins when installation is complete and no jobs are running” to automatically restart.

If this does not work you can stop Jenkins manually and start it again:

java -jar jenkins.war

Going back to “Manage Jenkins” screen, click on “Configure System”.

Click on “Add Maven” button, put “Maven 3.0.4” in the name text box and uncheck “Install automatically” check box. A new field is displayed. Put “/usr/local/jenkins/apache-maven-3.0.4” in MAVEN_HOME. You can also try the automatically install option but for some reason when I did it didn’t work.

In the same page, click on “Add” button under TestLink section.

We need to fill Name, URL and Developer Key fields. In the name you can put anything. I put “TestLink 1.9.4”. URL field is pre populated with a default path. Make sure the path to xmlrpc.php file is correct. Keep “localhost” because we are running Jenkins and TestLink in the same server.

Now for the Developer Key field we need to first log in TestLink. Open a new browser window and enter TestLink URL. If you are executing from the host machine you can enter http://10.200.242.97/testlink. Remember to change IP. If you executing virtual machine: http://localhost/testlink

In the main TestLink screen go to “My Settings” link. In “API interface” section click on “Generate a new key” button.

You will now see a Personal API access key generated.

Copy the value and go back to Jenkins configuration screen and paste it to Developer Key field.

Click on save button. Jenkins is ready!

Part 2: Debian installation and configuration

September 27, 2012 1 comment

Installation

Now we are ready to install Debian in our virtual server. When booting our virtual server fo the first time, Debian ISO image is loaded and you should now see the installar menu screen. Choose “Install”. This is the text mode based installation process. I prefer this option because it’s faster.

Time to choose a language to be used during installation procedure. I’ll be using English here, all screenshots will be based in this language.

Now choose your location. This is step is important because it will determine your local time. I’m in Brazil, so I chose Other, South America, then Brazil. Tell me where you are!

Because there is no locale define for my country-language combination, the screen below is shown. I choose “United States – en_US.UTF-8”. Depending on your locale you may not see this screen.

My keyboard layout is “Brazilian (ABNT2 layout)”. This setting can be changed after install procedure. If you choose the wrong layout you may experience some weird behaviour of your keyboard like changed keys, missing accents and so forth.

Now we need to configure virtual server’s network. We need a server name. Mine is “autoserver”. Can be whatever you want.

The domain can also be anything you want. Mine is “estivalet.org”.

Set root password.

Repeat root password.

We need to create an additonal user besides the root. Choose a name (please note that this is optional).

Choose a login for the non-root. Mine is “robot”. Again choose any name you like.

Set a password for “robot” user.

Verify password for “robot” user.

In the clock configuration, look for your time zone. Mine is “Sao Paulo”.

In partition disk section we will be using the entire disk option “Guided – use entire disk”.

Since we have created only one virtual disk choose it.

To make it simple choose “All files in one partition (recommended for new users)”. We don’t need to create separated partitions. Maybe for a real server the administrator could create additional partitions.

No additional settings here. Choose “Finish partitioning and write changes to disk” to finish disk set up.

Choose “Yes” to confirm. Please note that the install procedure automatically creates a “swap” partition. Don’t need to worry about it.

Debian install CD is detected by the installer and we don’t need any other source to perform the installation so choose “No” option.

The installer may need to download additional packages from Internet. It asks if we want to use a mirror to download them faster. Keep default option “Yes”

Next you will be prompted to select a mirror. Choose the nearst to you. The screens below are shown.

Say “No” to the package survey.

Next step is to choose what software will be installed in our virtual server. Choose “Graphical desktop environment”, “Web server” and “Standard system utilities”. This will install Apache 2 and a graphical user interface. We need a GUI because our automated testes need to open a web browser window, so make sure this option is selected.

Wait until the install procedure is finished, it may take some time to dowload additional packages.

Choose “Yes” to save boot loader (GRUB) in MBR. We will only have Debian in this server so this is the best option.

Finish! Click in “Continue” and wait for the reboot.

GRUB loaded. Keep the first option selected.

After the boot wait for the login screen. You should log in using the non root you created in the install procedure. Root user does not have permission to run the graphical user interface.

Server Configuration

Stop Debian VM if it’s running before continuing this step. Now before starting up the VM again I usually create an additional network interface because NAT is the default adapter and so the guest VM won’t be acessible from the host machine. To create an additional network adapter go to network section in virtualbox.

Network

The virtual machine may be fully integrated into the network and you may have access between all virtual machine and the host if you do a little bit more. Create the following script and set it to run at boot time in the host machine or call it beafore starting the virtual sever. This script will also enable NAT so the guest machine can have full access to Internet. You may need to install additional packages to your host machine. “tunctl” and “brctl” applications are used in the script. So make sure you have this tools before running the script.

#!/bin/sh
# set PATH for the case we are called via sudo or su root

PATH=/sbin:/usr/bin:/bin:/usr/bin

# create a tap
tunctl -t tap1 -u <user>
ip link set up dev tap1

# create the bridge
brctl addbr br0
brctl addif br0 tap1

# set the IP address and routing
ip link set up dev br0
ip addr add 10.1.1.1/24 dev br0
ip route add 10.1.1.0/24 dev br0

# set up NAT
INTIF="br0"
EXTIF="eth0"
echo 1 > /proc/sys/net/ipv4/ip_forward

# clear existing iptable rules, set a default policy
iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F

# set forwarding and nat rules
iptables -A FORWARD -i $EXTIF -o $INTIF -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT
iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

And add the script below also for running at boot time to your guest operation system in our virtual server just installed (Debian):

ip link set up dev eth0
ip addr add 10.1.1.2/24 dev eth0
ip route add default via 10.1.1.1 dev eth0

You can add the commands above to your /etc/rc.local script.

Now shut down guest machine and then open VirtualBox. In the network configuration section for the VM disable all network interfaces. Enable only the first one and put it in Bridge mode and connected to “tap1” interface that we have created before.

Add new packages

Having the guest machine accesible from the host machine, the next step is add additional software. Basically, we need to add some packages that were not included in Debian’s default installation procedure. We need to install PHP, PostgreSQL, Subversion, Java SDK and other required libraries for our next steps. So perform the following command to install using root user:

Edit /etc/apt/sources.list and add the following line:

deb http://ftp.de.debian.org/debian unstable main non-free contrib

Comment the cdrom putting a # before the line:

#deb cdrom:[Debian GNU/Linux 6.0.3 _Squeeze_ – Official i386 CD Binary-1 20111008-13:01]/ squeeze main

Open a terminal and run as root user apt-get update two times in order to update package list and the commands below to install additional packages.

su
<type root password>
apt-get update
apt-get update
<del>apt-get install perl -o APT::Immediate-Configure=0</del>
apt-get install openssh-server unzip php5 postgresql php5-pgsql php5-gd php5-ldap slapd subversion libapache2-svn python-genshi python-setuptools python-subversion python-psycopg2 libapache2-mod-python libapache2-mod-wsgi openjdk-6-jdk

We need to change default postgresql password (I will change it to ‘postgres’). In the terminal as root type the following:

passwd postgres
su postgres
psql
alter user postgres password 'postgres';
\q
exit

Subversion

Subversion will be needed in the future so let’s create a folder to hold the repository:

mkdir -p /services/svn/repositories
svnadmin create /services/svn/repositories
chown -R www-data.www-data /services/svn/repositories
find /services/svn/repositories/ -type d|xargs chmod g+sw

Create /etc/apache2/subversion.conf file and add the following:

<Location /svn>
    DAV svn
    SVNPath /services/svn/repositories
    AuthType Basic
    AuthName "Subversion repository"
    AuthUserFile /services/svn/repositories/conf/svn-auth-file
    Require valid-user
</Location>

Open /etc/apache2/apache2.conf and add the line below at the end of the file:

Include /etc/apache2/subversion.conf

Since we will be using svn with an apache server, and an apache basic authentication method. We need to create a password file with the htpasswd binary provided with a standard apache installation. The {user-name} is the user you created during Debian installation.

htpasswd -cmd /services/svn/repositories/conf/svn-auth-file {user-name}

Restart apache:

apache2ctl restart

Your server is now ready to install our testing software. Read on next tutorial step.

Categories: Tutorial

Part 9: Creating a Test Project in TestLink

September 27, 2012 Leave a comment

Creating a Test Project

The first time you log in in TestLink after the installation it will open a window to create the first Test Project. Enter the information below and do not forget to check all enhanced features. When you are done just hit Create button.

The screen below is shown after the test project creation.

Click on the “Project” link in the toolbar to get back to main screen.

Creating custom field

We need to define a custom field. This field will be used in the future with the TestLink plugin for Jenkins. When creating a test case we need to define the java class responsible for automating it. So click on “Define custom field” in the “Test Project” box.

Just hit “Create” button in order to create a new custom field. Fill in with the values as the screen shot below and hit “Add” button.

The screen below is displayed after a new custom field is created.

Now go back to TestLink main screen by clicking again in “Project” link located in the link bar. Now we need to assign the custom field just created to the project. Choose “Assign custom field” link to perform this action. The screen below is displayed. Check the field just created and hit “Assign” button.

The screen below is displayed after clicking on “Assign” button:

Creating Test Cases

OK, now we need to create our test cases for our requirements. To do that click on “Test Specification” link in the link bar. The screen below will be displayed. Note that in the left side we have a tree-like structure. All suites and test cases will be accessible from this tree. The root of the tree is already created by TestLink and it is automatically named with the same name of the Test Project and you are not allowed to change it. To create a test suite select the tree root “Google test project example”. In the right panel a new frame is displayed. Now hit “Create” under Test Suite Operations.

The screen below is displayed to create a test suite. Enter a name for the suite and click on “Create Test Suite” button.

After creating the test suite, the right panel will be automatically refreshed and now the suite will be displayed in the tree just below the root node. We can now create our test cases under the suite just created. Select the suite just created. The right panel will be refreshed and the screen below is displayed. Click on “Create” button under “Test Case Operations”. Please note that I said the Create button for Test Case and not the Create button for Test Suite.

Now enter a name for the test case. I have chosen the same name described in the requirements but you can adopt any other pattern.

You can fill other fields, but they are all optional and we will not be using the information in this tutorial. So still in the test case creation page, scroll down and new fields are displayed. Note that the custom field we created before is now being shown. Change the execution type to “Automated” and in the “Java automation class” put the full qualified name of the java class responsible for the test execution. Then hit “Create” button.

The left panel will refresh again and the test case just created will be listed in the tree. Select it in the tree. The right panel is refreshed and the screen below is displayed. Hit “Create step” button. Note that this step is optional for the automation. If the java code is well documented, there’s no need to document the steps in TestLink although it’s a good practice.

The screen below show the documented steps for the test case.

Now create other 2 test cases following the same steps above. Your tree should be like the screen shot below:

Summary

Just make sure you have your tests created as stated below. Please note that the most important part for us is the java automation class field. All other fields can have different names like the suite or test case. We need to keep exactly the same java class name we created in the previous tutorial.

Test suite: Advanced Search

  • Test case 1: Search all words of a string
    • java automation class: testing.cases.AdvancedSearchTestCase#advancedSearchTestCase
  • Test case 2: Do a unit conversion
    • java automation class: testing.cases.UnitConversionTestCase#unitConversionTestCase
  • Test case 3: Perform an arithmetic operation
    • java automation class: testing.cases.ArithmeticOperationTestCase#arithmeticOperationTestCase

Since we may have multiples tests in the same Java class we need to specify which method we want to run.

Creating a Test Plan

Next step is to create a test plan for adding the test cases just created. Go back to Testlink’s main screen and click on “Test Plan Management” in “Test Plan” box at the left.

Click on Create button to create a new test plan.

After creating the plan the screen below is shown.

Now click on “Project” link to get back to TestLink main screen. In the main screen click on “Add / Remove Test Cases” under “Test Plan contents” box.

Click on “Advanced Search” test suite in the left. The right panel will refresh and list all 3 test cases we have previously created. Select all of them to add to the test plan and click on “Add selected” button.

You should see a screen with all test cases marked in yellow.

We are done with Testlink for. Go to next part of the tutorial.

Part 7: Setting up development environment

September 27, 2012 Leave a comment

Preparing development environment

You can set the development environment in the same virtual machine we created for our server although this is not a good practice. Instead you should create your development enviroment in the host machine or even in a different machine.

I’ll be using Eclipse IDE to edit and run the automated test cases. I strongly recommed to use Eclipse because all screens are based in this tool, so if you use Netbeans or another  tool, you should adapt the instructions below.

We will be using the following software within Eclipse:

  • Maven – is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
  • TestNG – is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use. It is designed to cover all categories of tests:  unit, functional, end-to-end, integration, etc…
  • Selenium 2.0 (Webdriver) – test automation framework for web-based applications. One of Selenium’s key features is the support for executing one’s tests on multiple browser platforms.

After launching Eclipse you should see the following screen:

We will be using the following Eclipse plugins:

Plugin installation is done from menu Help -> Install New Software… If you need any help to install plugins please check Eclipse documentation.

After all plugins above are installed, we need to add an additional package in Ubuntu to allow java-subversion integration to work in Eclipse. Open a terminal and type the following command:

sudo apt-get install libsvn-java

After the installation open eclipse.ini and add the following line after "-vmargs"

-Djava.library.path=/usr/lib/jni

Restart eclipse.

Let’s create an empty Maven project. For this go to File->New->Other. Select under Maven the “Maven Project” option:

In the next screen make sure “Create a simple project (skip archetype selection)” and “Use default workspace location” options are checked.

In the configuration screen fill in the options as the screen below.

Group Id: org.testing

Artifact Id: GoogleWebdriverTest

Version: 0.0.1-SNAPSHOT

Packaging: jar

Keep other fields empty.

Click on finish button. You should now see the following screen with GoogleWebdriverTest project just created.

Now open pom.xml and replace all contents with the code below:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.testing</groupId>
<artifactId>GoogleWebdriverTest</artifactId>
<version>0.0.1-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>scripts/testcases.xml</suiteXmlFile>
</suiteXmlFiles>
<testFailureIgnore>true</testFailureIgnore>

<properties>
<property>
<name>usedefaultlisteners</name>
<value>true</value>
</property>
<property>
<name>listener</name>
<value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>
</property>
</properties>

<workingDirectory>target/</workingDirectory>
</configuration>
</plugin>
</plugins>

</build>

<dependencies>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.25.0</version>
<type>pom</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.5.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.uncommons</groupId>
<artifactId>reportng</artifactId>
<version>1.1.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>

<dependency>
<groupId>com.google.code.guice</groupId>
<artifactId>guice</artifactId>
<version>1.0</version>
</dependency>

<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>

</dependencies>

</project>

A quick explanation about pom.xml file. We are going to use some maven plugins:

  • The Compiler Plugin is used to compile the sources of your project. The default compiler is javac and is used to compile Java sources.
  • The Surefire Plugin is used during the test phase of the build lifecycle to execute the unit tests of an application. It generates reports in 2 different file formats: plain text files and XML files. By default, these files are generated at ${basedir}/target/surefire-reports.

About Maven dependencies: Selenium Maven artifacts can be found directly in the central Maven repository here: http://repo1.maven.org/maven2/org/seleniumhq/selenium/ and TestNG (http://testng.org/doc/maven.html) dependency is also found in the central Maven repository.

To find out what is the latest version of each dependency or plugin you can look at http://mvnrepository.com.

After saving the pom.xml, maven should automatically download all dependencies needed to compile and execute automated test cases using Webdriver and TestNG. You can see the downloaded dependencies in Eclipse in Package Explorer under “Maven Dependencies” item. You can also see the JAR files in your file system. In Linux maven usually stores its files under a hidden folder called “.m2” in user’s home folder.

Firefox

In current version of Debian, Firefox is not installed. I prefer to work with Firefox. You may also try Chrome. To install Firefox in Debian you need to follow steps below. If your host operational system already have Firefox installed you may skip this section.

Edit your /etc/apt/sources.list and add to the end:

http://packages.linuxmint.com debian import

Remove Iceweasel Debian’s default browser and install Firefox

apt-get remove iceweasel
apt-get update
apt-get install firefox
apt-get install firefox-l10n-en-gb

Firefox Plugins

As a suggestion,install the following plugins to your Firefox browser. They will help a lot while developing automated test cases. More details about them in the next tutorial.

We are now ready to start programming automated tests. Let’s move on to the next part.

Categories: Tutorial

Part 8: Developing automated test cases using Page Objects pattern

September 27, 2012 1 comment

Overview

A zipped file with all source code developed in this part is available here.

Requirement Specification

Let’s work on the following requirement (user story):

Feature: Google Advanced Search
As a casual internet user
I want to find some information about Page Objects Design Pattern, do a quick conversion and perform an arithmetic operation
So that I can be knowledgeable being

Scenario: Search for Page Objects Design Pattern
Given I am on the Google Advanced Search Page
When I search for “Page Objects Design Pattern”
Then I should see at least 1,000,000 results

Scenario: Do a unit conversion
Given I am on the Google Advanced Search Page
When I convert 10 cm to inches
Then I should see the conversion result
“10 centimeters = 3.93700787 inches”

Scenario: Perform an arithmetic operation
Given I am on the Google Advanced Search Page
When I add 10 to 20 multiplied by 30
Then I should see the operation result
“100 + (200 * 300) = 60100”

Page Objects Pattern

Separate specification from implementation. This is the main goal of the page object design pattern.

Within your web application’s UI there are areas that your automated tests interact with. A Page Object simply models these as objects within the test code. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place – in the class that represents the page being tested and not the test itself.

Here are some guidelines to create a page object:

  • The public methods represent the services that the page offers
  • Try not to expose the internals of the page
  • Generally don’t make assertions – they should be in your automated test code
  • Methods return other PageObjects
  • Need not represent an entire page
  • Different results for the same action are modelled as different methods – you will probably need a method for successful path and another one for unsuccessful path (example: one method to represent a log in action with right credentials an another one to represent a log in with wrong password).

Simple Test

In this first test we are not going to use the Page Object design pattern. You will create a single class just to make sure your development environment is correclty set up. Go to Eclipse and create a class named “TestClass” under src/test/java folder with the following content. Use the same maven project we created in the previous part of this tutorial.

package testing.cases;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Test;

public class TestClass {

    private WebDriver driver;

    @Test
    public void test() {
       driver = new FirefoxDriver();
       driver.get("http://www.google.com/advanced_search");
       driver.findElement(By.name("as_q")).sendKeys("100 + (200 * 300)");
       driver.findElement(By.xpath("//input[@value='Advanced Search']")).click();
       Assert.assertTrue(driver.getPageSource().contains("60100"));
       driver.quit();
    }
}

The code is pretty straightforward. The class has only one method named “test()”. Any name is acceptable, you don’t need to call it test. The important part is the annotation @Test. Annotating your method with @Test you are adding it to your test. This annotation has lots of parameters, you can check all of them in TestNG documentation page.

First thing is create a new driver object. In this case we will be using Firefox so make sure you have it installed in your system. Next we ask the driver to open Google’s advanced search page. After that we as the driver to find the element which name is “as_q”. This is the name of the field we will be using to search. When it finds it will write inside the field – in this case a text box – the string “100 + (200 * 300)”.

Now to click in the advanced search button we need to find it. Since it has no name and no id we need to use a xpath formula to find it. This is why I suggested you to install some firefox plugins to help you identify the page elements that your tests will interact with.

After clicking in the button, the result page will be displayed and we will be looking for the text “60100” that is the result of the searched expression. If it’s present then the test ran with success, otherwise it will fail.

To run this test class from Eclipse, just right click on it, select Run As->TestNG test.

After running you should the following output in Console window:

And the following in TestNG tab:

Now that everything is running fine we can move on and refactor the example above using the page object design pattern.

Coding Page Objects for our Example

First let’s create a base BasePage object. All pages in our example should extend it. The idea is to have a base object where common actions to all pages are kept centralized. In this case, we have just one method isTextPresent() responsible for searching a text in a page. Of course you can create several other methods according to your needs.

package testing.pages;

import org.openqa.selenium.WebDriver;

public class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }

    public boolean isTextPresent(String text) {
        return driver.getPageSource().contains(text);
    }
}

In the first example we did not use page object pattern. Here is a better version using the pattern. Note that we have created fields in GoogleAdvancedSearchPage class to represent form elements the test will interact. We have one field for the search text box and another one for the search button. We could have all other form elements from the Advanced Google Search Page represented in this class but for our example is enough.

package testing.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class GoogleAdvancedSearchPage extends BasePage {

	@FindBy(name = "as_q")
	private WebElement searchTextBox;

	@FindBy(xpath = "//input[@value='Advanced Search']")
	private WebElement searchButton;

	public GoogleAdvancedSearchPage(WebDriver driver) {
		super(driver);
	}

	public void setSearchTextBox(String searchTextBox) {
		this.searchTextBox.clear();
		this.searchTextBox.sendKeys(searchTextBox);
	}

	public GoogleSearchResultsPage search() {
		this.searchButton.click();
		return PageFactory.initElements(driver, GoogleSearchResultsPage.class);
	}

}

Below we have the code for the search result page. It has no method besides the constructor. We will be using the parent Page class method to search a text in the page.

package testing.pages;

import org.openqa.selenium.WebDriver;

public class GoogleSearchResultsPage extends BasePage {

     public GoogleSearchResultsPage(WebDriver driver) {
         super(driver);
     }
}

Coding Tests using Page Objects

As we did for the pages, a good practice is to also create a base test class that will hold all common test methods. The class below implements beforeTest and afterTest methods. The first one is responsible for opening Firefox and going to the url supplied in the parameter. The former one will close Firefox. Note that these methods are common to all tests. In this case for every test method a Firefox instance will be opened and at the end it will be closed. A better aproach would keep a Firefox instance for multiple tests (called test suites). To do this just change the annotation from @BeforeTest to @BeforeSuite but you will also have to make some changes in the xml and in your automated test cases code to make it work right.

package testing.cases;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;

public class BaseTestCase {

	protected static WebDriver driver;

	@Parameters( { "url" })
	@BeforeTest
	public void beforeTest(String url) {
		driver = new FirefoxDriver();
		driver.get(url);
	}

	@AfterTest
	public void afterTest() {
		driver.quit();
	}

}

The first test will enter a string to search in the advanced google search page. The PageFactory.initElements() method is used to create an instance of GoogleAdvancedSearchPage class. Then we enter the text to search and click on seach button. At the end we have an assert clause. It is a good practice the end a test method with an assertion. We are just validating the the page title is correct.

package testing.cases;

import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import testing.pages.GoogleAdvancedSearchPage;

public class AdvancedSearchTestCase extends BaseTestCase {

	@Parameters( { "searchString" })
	@Test
	public void advancedSearchTestCase(String searchString) {
		GoogleAdvancedSearchPage ghp = PageFactory.initElements(driver,
				GoogleAdvancedSearchPage.class);
		ghp.setSearchTextBox(searchString);
		ghp.search();

		Assert.assertEquals(driver.getTitle(), searchString
				+ " - Google Search");
	}
}

The code for arithmetic test is pretty much the same of the advanced search. The difference is that now we are receiving an addional parameter with the expected result after the search. The test will make an assertion to guarantee that the expected result was found in the result page.

package testing.cases;

import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import testing.pages.GoogleAdvancedSearchPage;
import testing.pages.GoogleSearchResultsPage;

public class ArithmeticOperationTestCase extends BaseTestCase {

	@Parameters( { "searchString", "expectedResult" })
	@Test
	public void arithmeticOperationTestCase(String searchString,
			String expectedResult) {
		GoogleAdvancedSearchPage ghp = PageFactory.initElements(driver,
				GoogleAdvancedSearchPage.class);
		ghp.setSearchTextBox(searchString);

		GoogleSearchResultsPage gsrp = ghp.search();
		Assert.assertTrue(gsrp.isTextPresent(expectedResult));
	}
}

The test for unit conversion is exactly the same as the arithmetic test. We keep in different classes because they are different requirements and is important because they will be displyed in the report as different tests. You could try to improve this and make a single class but it’s important to know which class implements the test for the requirement.

package testing.cases;

import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import testing.pages.GoogleAdvancedSearchPage;
import testing.pages.GoogleSearchResultsPage;

public class UnitConversionTestCase extends BaseTestCase {

	@Parameters( { "searchString", "expectedResult" })
	@Test
	public void unitConversionTestCase(String searchString,
			String expectedResult) {
		GoogleAdvancedSearchPage ghp = PageFactory.initElements(driver,
				GoogleAdvancedSearchPage.class);
		ghp.setSearchTextBox(searchString);

		GoogleSearchResultsPage gsrp = ghp.search();
		Assert.assertTrue(gsrp.isTextPresent(expectedResult));
	}
}

So you may be asking, ok but where are those parameters which classes above receive. They are in the testcases.xml file. This file holds all automated tests to be run. See the first one. We have the test name and the required parameters to make it run. In this case we need the URL and the search string. The class implementing the test is also declared. For the unit and arithmetic tests we have an additional parameter expectedResult used in the assertion to make sure the test pass.

Create a folder named “scripts” in the root of your test project (this folder is optional it’s just for organization purposes, you may have one folder per requirement or any other structure you want). Inside this folder create testcases.xml file with the following content:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Test Cases">
<test name="Search for Page Objects Design Pattern">
<parameter name="url" value="http://www.google.com/advanced_search" />
<parameter name="searchString" value="Page Object design pattern" />
<classes>
<class name="testing.cases.AdvancedSearchTestCase">
<methods>
<include name="advancedSearchTestCase"/>
</methods>
</class>
</classes>
</test>

<test name="Do a unit conversion">
<parameter name="url" value="http://www.google.com/advanced_search" />
<parameter name="searchString" value="10 cm in inches" />
<parameter name="expectedResult" value="3.93701" />
<classes>
<class name="testing.cases.UnitConversionTestCase">
<methods>
<include name="unitConversionTestCase" />
</methods>
</class>
</classes>
</test>

<test name="Perform an arithmetic operation">
<parameter name="url" value="http://www.google.com/advanced_search" />
<parameter name="searchString" value="100 + (200 * 300)" />
<parameter name="expectedResult" value="60100" />
<classes>
<class name="testing.cases.ArithmeticOperationTestCase">
<methods>
<include name="arithmeticOperationTestCase"/>
</methods>
</class>
</classes>
</test>

</suite>

Running all Tests

Right click on testcases.xml file and select Run As->TestNG Suite

You should see the following result after running the test suite:

Adding Code to Subversion

We need to add our code to a source code management tool. We have installed subversion in our virtual server so let’s use it. Jenkins will download the code from repository to execute the tests (see tutorial).

Right click in the name of the project and choose Team->Share Project

Choose SVN option (make sure you have installed Subversion plugin for Eclipse):

Select the option to create a new repository location:

Since our subversion is running through Apache we will be acessing the repository via http. So fill in with virtual machine IP as below. Make sure the path is the same you have created in the server.

Keep default “Use project name as folder name” option checked and click next.

The next screen allows you to enter an optional comment for the commit.

Now Apache will request user/password you have configured in the previous tutorial when creating the subversion repository.

Back to Eclipse workbench click on Commit all Outgoing Changes button to put all project files under version control.

You can enter a comment for the commit here:

Note the console window. It shows the progress of adding files to the repository. At the end you should see a revision number corresponding to the commit operation.

Switch to package explorer and note that all files are now under version control.

We should now ready for next tutorial part!

Categories: Tutorial