The Developer Day | Staying Curious

Archive for February 2010

Feb/10

27

Expert Python Programming Review

Expert Python Programming BookI’ve always been interested in Python. Python is a dynamic programming language with a very clear and readable syntax, strong introspection, intuitive object orientation and so on. It’s been used in many successful projects such as Trac, Django, Mercurial, YUM. It’s used in companies such as Google or Yahoo. Python has a vast standard library allowing to solve almost any domain problem. From the early beginning Python had a design philosophy behind it which is probably one of the reasons why Python is such a successful programming language now days.

All these and other reasons make Python an interesting and valuable language to learn. I’ve chosen to review Expert Python Programming as my next book. Having used Python for personal projects such as or work related tasks such as continuous integration with BuildBot I hope it will be an interesting read that will help me to improve my understanding of Python.

For those interested Packt Publishing offers a sample chapter of the book.

, , Hide

Feb/10

26

Zend Framework Escaping Entities

Zend Framework has a powerful input filtering component Zend_Filter_Input. It provides an interface to define multiple filters and validators and apply them to a collection of data. By default values returned from Zend_Filter_Input are escaped for safe HTML output. An example of such functionality:

$validators = array(
    'id' => array(
        'digits',
        'allowEmpty' => true,
    ),
    'name' => array(
        'presence' => 'required',
        new Zend_Validate_StringLength(5, 255),
    ),
    'date' => array(
        'presence' => 'required',
        new Zend_Validate_Date('d/m/Y'),
    ),
);
$filters = array(
    '*'  => 'StringTrim',
);
$input = new Zend_Filter_Input($filters, $validators, $data);
if ($input->isValid()) {
    print_r($input->getEscaped());
} else {
    print_r($input->getMessages());
}

The code above validates the $data array by checking that the id key consists only of digits or is empty, that name is present and it’s min length is 5 and max length is 255 and that date is present and it’s format is d/m/Y. The StringTrim validator removes any spaces in front and at the end of all the $data values. If the $data array is valid all escaped values are outputted and if not a generated list of error messages is presented.

Recently I’ve ran into a small problem while using Zend_Input_Filter. According to the best security practices all data coming from the user should be escaped before being outputted to the screen. This also means data coming from a database. This requires to escape every single output statement in every view. In my opinion this adds unwanted verbosity, performance overhead and a possibility to easily miss that something was not escaped in one of the views. That is why if there is a possibility I would prefer to trust the database and not worry about the data incoming from it. It may not be a very good option if data in the database is most often presented in other documents than HTML. Since all values would need to be decoded which defeats the whole purpose. Though this is rarely the case.

By default Zend_Filter_Input escapes values by using the htmlentities function. Which converts all applicable characters to HTML entities. This means that for example Danish language characters Æ Ø Å would be stored as Æ Ø Å Which means that it would take 7 bytes on average to store a single letter that otherwise could be stored using 1 - 3 bytes using UTF-8 encoding support in MySQL. This could also potentially ruin collation sorting.

To overcome this issue a very similar function htmlspecialchars could be used. It escapes only a few certain characters such as > < ” without escaping all international characters. The actual problem with Zend_Filter_Input is that it does not have an escape filter that uses htmlspecialchars. To solve the issue I’ve created a copy of HtmlEntities filter which uses htmlspecialchars function instead.

The filter can then be used like this:

$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setDefaultEscapeFilter(new Company_Product_Filter_HtmlSpecialChars());

Zend_Filter_Input is a great tool to ease form validation and filtering. I would be very interested to hear from you how this problem could be solved.

, , , , , , Hide

Feb/10

23

PHP London Conference 2010

I’m pleased to say that I will be attending the PHP UK conference 2010 in London. Last year I attended PHPNW 2009 which was great and I hope PHP London to be even better. It will be certainly interesting to listen to famous PHP speakers such as Stefan Priebsch, Fabien Potencier author of Symfony. The conference schedule has been announced and these are the talks that I’m going to attend:

  • The lost art of simplicity
  • AntiPHPatterns
  • PHP 5.3 in practice
  • PHPillow & CouchDB & PHP
  • ‘In search of…’ - integrating site search systems
  • PHP on the D-BUS

The keynote talk about lost art of simplicity sounds very promising. Also very eager to see Fabien’s presentation on how PHP 5.3 can be used in practice.

, , , , Hide

Feb/10

20

Zend Framework Database Profiler Reporting

Zend Framework has a powerful Database Profiler component. It is remarkably simple to integrate the database profiler with the Zend Framework front controller with the use of Firefox addons FireBug and FirePHP:

// In your bootstrap file
$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
// Attach the profiler to your db adapter
$db->setProfiler($profiler);

Or just by enabling it in the database configuration:

$db = array(
    'type' => 'pdo_mysql',
    'host' => 'localhost',
    'dbname' => 'dbname',
    'username' => 'username',
    'password' => 'password',
    'profiler' => array(
        'enabled' => true,
        'class' => 'Zend_Db_Profiler_Firebug',
    )
);

Producing nicely formatted results:

Firebug profiler is great tool. But it requires to use Firefox and have FireBug and FirePHP addons installed. Not everyone in your organization may be Firefox users or have these addons installed. Another drawback is that sometimes queries may be quite big and complex. It’s not easy to analyse them in a Firebug window or to copy them to an editor that supports SQL highlighting.

To solve that it is possible to create a custom database profiler reporting mechanism. To output the profiler queries I’ll create a custom Zend Framework action helper:

class Company_Product_Helper_Profiler extends Zend_Controller_Action_Helper_Abstract
{
    protected $_profiler;
    protected $_view;
    protected $_config;
    protected $_db;
    public function __construct(Zend_Config $config, $db)
    {
        $this->_config = $config;
        $this->_db = $db;
    }
    public function init()
    {
        $this->_view = new Zend_View();
        parent::init();
    }
    public function postDispatch()
    {
        $this->_profiler = new Company_Product_Db_Profiler_Report($this->_db1);
        if (!$this->_isProfilerEnabled()) {
            return false;
        }
        $this->outputToScreen();
    }
    protected function _isProfilerEnabled()
    {
        if ($this->_config->environment == 'live') {
            return false;
        }
        if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
            return false;
        }
        $profiler = $this->getRequest()->getParam('profiler');
        if (!empty($profiler)) {
            return true;
        }
        return false;
    }
    protected function outputToScreen()
    {
        $this->_view->headLink()->appendStylesheet('/css/highlight/default.css', 'screen');
        $this->_view->headScript()->appendFile('/js/highlight.pack.js');
        $this->_view->headScript()->appendScript('
            hljs.tabReplace = \'    \';
            hljs.initHighlightingOnLoad();
        ');
        $this->getResponse()->appendBody($this->_profiler);
    }
}

The action helper uses a post dispatch hook. The post dispatch hook is called after the Zend Framework dispatcher dispatches a request. A post dispatch hook is used to ensure that all queries have been run and to integrate the profiler with the Front Controller without changing any of the controller classes.

Action helper profiler checks to see if any profiling information should be outputted. It checks if the current configuration environment is not production to not allow unauthorized people to use the profiler. It also checks if a request is not an AJAX request, since AJAX requests may be returning JSON data structures and any additional output can break the client which sent the request. Profiler can be enabled by adding a URL query parameter ?profiler=1.

To highlight the SQL queries profiler uses a third party JavaScript highlighting library Highlight.js. On page load highlight.js finds all <code> nodes in the DOM structure, detects the programming or markup language type of the content inside them and highlights it.

The profiler action helper also uses another class to format the profiler report. The profiler report class implements an iterator interface and the __toString method allowing to use it in different ways. It could also be used to format profiler output for environments such as terminals which can’t interpret HTML.

class Company_Product_Db_Profiler_Report implements Iterator
{
    protected $_profiler;
    protected $_html = false;
    protected $_position ;
    public function __construct($db, $html = true)
    {
        $this->_profiler = $db->getProfiler();
        $this->_html = $html;
        $this->_position = 0;
        $this->_profiles = $this->_profiler->getQueryProfiles();
    }
    public function setOutputFormatToHtml($value)
    {
        $this->_html = !empty($value);
    }
    public function __toString()
    {
        $out = "";
        if ($this->_html) {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsHtml($key, $query);
            }
        } else {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsText($key, $query);
            }
        }
        return $out;
    }
    protected function _formatProfileAsHtml($key, $query)
    {
        $out = "<pre><code>{$key}. " . wordwrap($query->getQuery(), 150) . "\n\n ({$query->getElapsedSecs()} s.) </code> </pre>";
        return $out;
    }
    protected function _formatProfileAsText($key, $query)
    {
        $out = "$key. {$query->getQuery()} ({$query->getElapsedSecs()} s.)\n\n";
        return $out;
    }
    public function rewind()
    {
        $this->_position = 0;
    }
    public function current()
    {
        if ($this->_html) {
            return $this->_formatProfileAsHtml($this->_position, $this->_profiles[$this->_position]);
        } else {
            return $this->_formatProfileAsText($this->_position, $this->_profiles[$this->_position]);
        }
    }
    public function key()
    {
        return $this->_position;
    }
    public function next()
    {
        ++$this->_position;
    }
    public function valid()
    {
        return isset($this->_profiles[$this->_position]);
    }
}

To make Zend Framework aware of the profiler action helper add the following lines of code to the bootstrap file:

Zend_Controller_Action_HelperBroker::addHelper(
    new Company_Product_Helper_Profiler($config, $databaseConnection)
);

When done the output of the profiler should look something like this:

, , , , , Hide

Feb/10

20

Subversion Self Signed Certificates

When connecting to Subversion repositories using SSL connections the SVN client checks the server certificate if it is not expired, if it’s host description matches the host of the repository and if the authority which signed the certificate is trusted.

If the certificate fails to comply with any of the above rules the SVN client will respond with a message such as this one:

Error validating server certificate for ‘https://hostname:443′:
- The certificate is not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
Certificate information:
- Hostname: hostname
- Valid: from Tue, 16 Feb 2010 16:58:39 GMT until Fri, 14 Feb 2020 16:58:39 GMT
- Issuer: company.com, London, Berkshire, GB
- Fingerprint: d5:4e:d8:12:33:12:a5:f1:18:91:77:40:c4:77:3b:0b:f8:51:71:cd
(R)eject, accept (t)emporarily or accept (p)ermanently?

The certificate can still be accepted permanently manually. It may not be a solution if SVN commands are issued by non interactive processes. For example a PHP script run by apache trying to export a branch from the repository.

Certificates signed by trusted authorities such as Verisign should not have any problems. But self signed certificates will not be recognized by the SVN client which in turn will respond with the response above. Self signed certificates can be be made trusted by the SVN client by using the ssl-authority-files configuration option:

ssl-authority-files = /home/void/.subversion/company.crt

The configuration file named servers which holds this configuration option can be stored in multiple locations on the filesystem. First the Subversion client will try to look for it in the home folder of the user that is executing the SVN command. Users such as apache will most likely not have a home folder. In such cases SVN tries to look for the servers file in the /etc/subversion directory. It may or may not exist depending on the OS distribution flavour. For example it exits on Ubuntu but does not exist on CentOS a flavour of RedHat.

, , , , Hide

Feb/10

18

Starting services in a clean environment

I was working on a small web application that creates Subversion branches and tags. In short it just executes SVN commands on the repository. Whenever a user executes an SVN command the SVN client tries to check user’s local home folder for the .subversion configuration directory. The issue that I was running into was that for some reason apache’s home folder was pointing to our system’s administrator home folder which in turn would result in a permission denied error when apache would try to access the .subversion folder.

It just didn’t make any sense. Turns out if you start a service through /etc/init.d/ it starts that service with environment variables belonging to the user that started the service. In this case our system’s administrator started the service using his own user.

To start services in a clean environment a special utility called service should be used. It usually resides in the /sbin directory. So for example instead of starting apache like this:

$ sudo /etc/init.d/httpd start

It should be started like this:

$ sudo /sbin/service httpd start

Which will result in $HOME environment variable being empty and the SVN client not getting a permission denied error.

, , , , , Hide

I went to see Udi Dahan speaking on Command and Query Responsibility Segregation. The open talk was organised by Skills Matter who support the Open Source community by organizing free events and courses.

Udi Dahan is a world renowned software architect and speaker. Udi is a specialist in SOA and distributed systems. It is a pleasure to listen to Udi speak because of his ability to present ideas clearly and keep others wanting to see what the next slide holds.

Command Query Responsibility Segregation or CQRS is software architecture pattern. The pattern is about separating (Segregating) the read side (Queries) and write side (Commands) of the system.

A simple example would be an application that does event reservations. All read commands would be executed against a reporting database which is stale and can be de-normalized. All calculations needed to display the data have been done before populating the reporting database. All write commands like making an actual reservation or adding a new event is executed against a Domain Model with it’s own database. Domain Model is never used to execute reporting queries. Reporting databases are generated from the write side database after all needed calculations have been performed.

This architectural pattern simplifies the Business Domain Model making it behavior only making it easier to maintain. Another strong advantage of CQRS is system performance. CQRS approach accepts that reporting data can be stale. This enables easier development of highly scalable distributed systems.

, , , , , Hide

Feb/10

18

Domain Model Logic Patterns

A great thing about patterns is that it provides a vocabulary. It allows developers to communicate efficiently. Complex ideas can be described at a high technical level without going into small details. Patterns are like butterflies and come in many colors, sizes and shapes and there’s.. lots of them. As butterflies patterns are grouped into families. One of such families is Domain Logic Patterns described in Martin Fowler’s book Patterns of Enterprise Application Architecture.

It’s one of the fundamental families because virtually every application written is described by any of the three patterns that belong to it. To say it simply there are three major ways how an application can be designed. What is more interesting that each of those patterns can be sorted by the amount of effort required to change the application depending on it’s complexity. Deciding which pattern to choose can be tricky because these patterns depend on various characteristics of the project being developed. The size, the complexity, the lifetime of a project and most importantly the skills of the developers.

Transaction Script

Transaction script organizes business logic by routines where each routine handles a single request from the presentation layer. It is the most common way how software beginners write applications. Required steps to perform a task are identified and expressed using language semantics. Common routines can be broken into subroutines. Transaction Scripts can be organised as classes or as global functions. A single file can contain many Transaction Scripts at once. A lot of developers may think they are proficient OOP users while in reality they write data centric Transactions Scripts wrapping them into classes which could be just as easily replaced with simple procedures.

However Transaction scripts have benefits. It’s a simple procedural model so most developers can understand it, it works well with a simple data access layer using Row Data Gateway or Table Data Gateway.

An example transaction script may be booking a hotel room where a single procedure is responsible for checking the availability of the room, calculating the price and updating the database.

class Hotel
{  
	public function __construct(Data_Access_Gateway $gateway)  
	{  
		$this->_gateway = $gateway;  
	}  
	public function bookRoom($userId, $fromDate, $toDate)  
	{  
		$roomId = $this->_gateway->_getRoomIdBetweenDates($dateFrom, $dateTo);  
		if (!$roomId) {  
			return false;  
		}  
		$days = $this->_getAmountOfDays($fromDate, $toDate);  
		if ($days < = 7) {
			$price = $days * 100;
		} else { 
			$price = $days * 80;
		}
		$data = array(
			'userId' => $userId,  
			'roomId' => $roomId,
			'fromDate' => $fromDate,  
			'toDate' => $toDate,  
			'price' => $price,  
		);  
		$bookingId = $this->_gateway->insert('bookings', $data);  
		return $bookingId;  
	}  
}

Table Module

A Table Module is many ways the middle man between a Transaction Script and a Domain Model. A Table Module tends to organize domain logic with one class per table in the database. While a Transaction Script will have one class Hotel to do reservations a Table Module may have more fine grained classes like Hotel, Booking, Room. Even though these classes may be singular they do not actually represent individual entities and manages whole collections of entities. For example a Booking class would be responsible for mosts actions performed on the bookings database table. Like a Transaction Script a Table Module is a very data centric model approach and usually has a strong connection with the data access layer.

Table Module has a few benefits over a Transaction Script. There’s less duplication, domain logic is more organized and structured around domain entities. It works well with simple data access layers. However, Table Module doesn’t give you full power of objects in organizing complex domain logic. It lacks instance to instance relationships, has weak support for polymorphism.

To show an example of Table Module let’s re-factor the Transaction Script:

class Hotel
{  
	public function __construct(Data_Access_Gateway $gateway, Booking $booking)  
	{  
		$this->_gateway = $gateway;
		$this->_booking = $booking;
	}  
	public function bookRoom($userId, $fromDate, $toDate)  
	{  
		$roomId = $this->_booking->getRoomBetweenDates($fromDate, $toDate);
		if (!$roomId) {  
			return false;  
		}  
		$days = $this->_getAmountOfDays($fromDate, $toDate);  
		if ($days < = 7) {
			$price = $days * 100;
		} else { 
			$price = $days * 80;
		}
		$bookingId = $this->_booking->addBooking($userId, $roomId, $fromDate, $toDate, $price);  
		return $bookingId;  
	}  
}
class Booking
{  
	public function __construct(Data_Access_Gateway $gateway)  
	{  
		$this->_gateway = $gateway;  
	}
	public function getRoomBetweenDates($dateFrom, $dateTo)
	{
		return $this->_gateway->getRoomBetweenDates($dateFrom, $dateTo);
	}
	public function addBooking($userId, $roomId, $fromDate, $toDate, $price)  
	{  
		$data = array(
			'userId' => $userId,  
			'roomId' => $roomId,
			'fromDate' => $fromDate,  
			'toDate' => $toDate,  
			'price' => $price,  
		);  
		$bookingId = $this->_gateway->insert('bookings', $data);  
		return $bookingId;  
	}  
}

Domain Model

Domain Model organizes domain logic into well defined domain entities that contain both behavior and data. Usually each entity class represents a single entity in the data layer. Domain Model creates a hierarchy of inter connected objects that interact with each other by triggering behaviors on each other. Domain Model shines over Transaction Script and Table Module when it comes to handling domain complexity. It enables the full power of object oriented programming and all available design patterns. Even though Domain Model may sound like a silver bullet to all software development problems it is not. Learning to design applications using Domain Model requires a “paradigm shift” to start looking for entities and behaviors instead of looking for routines. The main downside of Domain Model is the way it works with relational databases. To compare I would like to quote Martin Fowler:

In many ways Domain Model treats the relational database like a crazy aunt who’s shut up in an attic and whom nobody wants to talk about.

Domain Model tries to be data layer agnostic. This is what object relational mappers also known as ORM’s as Hibernate try to solve by hiding the data access layer away.

To show an awkwardly simple example of Domain Model let’s re-factor the Table Module approach. To keep the example simple I’ll ignore the data access layer.

class Hotel
{  
	protected $_hotelId;
	protected $_rooms;
	public function bookRoom(User $user, $fromDate, $toDate)  
	{  
		$room = $this->_getRoomBetweenDates($fromDate, $toDate);
		if (is_null($room)) {  
			return false;  
		}  
		$booking = $room->bookRoom(User $user, $fromDate, $toDate);
		return $booking;  
	}
}
class Room
{
	protected $_roomId;
	protected $_bookings = array();
	public function bookRoom(User $user, $fromDate, $toDate)
	{
		$days = $this->_getAmountOfDays($fromDate, $toDate);
		if ($days < = 7) {
			$booking = new Booking($user, new ShortBookingStrategy($user, $days));
		} else { 
			$booking = new Booking($user, new NormalBookingStrategy($user, $days));
		}
		return $booking;
	}
}
class NormalBookingPriceStrategy extends BookingPriceStrategy
{
	public function getPrice()
	{
		$price = $this->_days * 80;
		if ($this->_user->isLoyal()) {
			$price = $price / 2;
		}
		return $price;
	}
}
class ShortBookingPriceStrategy extends BookingPriceStrategy
{  
	public function getPrice()
	{
		return $this->_days * 100;
	}
}

As you can see there is an instant explosion of classes and the data access layer is out of the picture. Responsibility to efficiently load and keep track of loaded entities is left to object mappers like Hibernate.

The End

Everyone of these domain model patterns have their benefits and downsides. It takes experience to be able to decide which approach to take. For those who are new to Domain Model it is advised to have an experienced team member who is able to guide you through it. While Transaction Script or Table Module can seem like a good solution at some point it may not be as effective later on. It is important to recognize when a different domain model approach might work better. It’s been a long ride for me. Through the years I’ve learned a few things about designing software but I still don’t feel very comfortable writing about it. I would love to hear feedback from you how this article and these examples could be improved to enable better understanding between the different modeling approaches.

, , , Hide

Feb/10

12

Spring Persistence with Hibernate Review

Spring persistence with hibernate Just recently I’ve finished reading Spring Persistence with Hibernate. It’s a book about two major Java technologies Hibernate and Spring. Hibernate is a powerful object/relational persistence framework and Spring is a Java application platform that includes an MVC framework. The book is primarily meant for Spring and Hibernate developers but it may also be useful to developers who are interested in object relational mapping and advanced MVC frameworks. The topics covered in the book include object relational mapping, aspect oriented programming, inversion of control, MVC. Even though these topics are advanced the book does not require the reader to understand them beforehand. All examples are written in Java and should be understandable to anyone with a solid development background.

The book is quite lengthy consisting of more than 400 pages in total. First half of the book introduces the reader to the Hibernate persistence framework. It explains how Hibernate works in general and how it is configured. The most important chapters on Hibernate cover mapping to entities and entity collections, describe the life cycle of persistent objects, cascading operations, querying and lazy loading. The other half of the book focuses on topics such as inversion of control, aspect oriented programming also known as AOP, transaction management, Spring MVC framework and testing.

Before reading the book I didn’t have any enterprise experience with Java or it’s technologies. Working as a PHP developer I appreciate the Java community and technologies made available by it. Through many years of being exposed to enterprise application development Java community has developed powerful tools which are a great resource to developers with different development backgrounds such as me. I’ve found the book to be an excellent insight into the object relational mapping world. I’ve enjoyed reading about Spring’s AOP framework which opened my eyes in a few ways how AOP could compliment OOP. Spring IoC container which is used by Spring itself is an amazing piece of software setting new standards for other dependency injection containers out in the wild.

Even though I believe the book is a worthwhile read it can seem to be too detailed at times. For example describing all available bean factories and all other lists of available bells and whistles can seem to be dull or hardly memorable. Maybe it would be better to introduce to the idea that there are multiple factories, describe few most important ones and provide directions as to where it is possible to learn about other types of factories. The book provides many examples which is a great way to grasp the concepts quickly. Provided examples are individual pieces explaining a certain concept. It may have been better to provide examples by trying to build a real life application throughout the entire book. I believe it is a fun way to learn allowing to see how real life development issues can be solved.

I believe it’s every developer’s duty to be familiar with the latest development technologies and to know when to use them. Too many applications are written using improper tools. Object relational mapping technologies are discussed frequently and not everyone is a fan of them. The fact that Hibernate is commonly used by Java developers and .NET developers proves that persistence frameworks have their place and are worthwhile to familiarize with.

, , , , , Hide

Feb/10

5

Benefits of Testing and Types of Testing

Software development produces products as any other industry. It is an interesting issue that products produced by the software development industry are not always as well tested as in other industries. One of the main reasons is due to the fact that in most companies software is manually tested by the same developers who built it.

Developers are not necessarily good testers. Good software developers while sharing some traits are different from good testers.  A good developer may be excellent at software design but won’t notice spelling mistakes. Developers tend to take the testing path that usually works while cutting corners on special cases. It is also known as happy testing.

Most reasons why software is tested manually boil down to:

  • Not knowing how
  • Not having the time
  • Maintaining legacy code

Hardly any of these reasons are valid excuses. Truth be told automated testing is not easy. It is a skill that has to be learned and doesn’t come naturally. It’s a skill that takes years to master. It may seem that automated tests take too much time and at first it will. Due to the same fact that it’s a skill and takes time to master. In some way it is like skiing. Before going down a steep mountain racing the wind one has to learn how to otherwise it’s an unpleasant struggle climbing down with your skis across the shoulder. Automated testing won’t do miracles but when done properly it may increase productivity by 10 - 20%.

There are many types of software testing with their own benefits and downsides. Bellow are the three most important and common types of testing.

Unit Testing

Unit testing is about testing the smallest individual parts of an application. For example instead of testing the whole engine of a car all individual pieces are tested separately as units. All dependencies are replaced with stubs or mocks or fakes. Unit tests are meant to be lightning fast and execute thousands of tests in a few seconds therefore they shouldn’t connect to the database, web services or send emails. Unit tests are most effective when executed very frequently during development to inform the developer of any broken parts allowing to fix the problem immediately without losing line of thought.

Integration Testing

Integration tests ensure that all of the application’s parts work correctly when they are assembled in a simulated production environment. An example of an integration test can be a batch job executing against a database with test data. Integration tests are a lot slower than unit tests and usually work best integrated with a continuous build system. While integration tests are not good at identifying broken parts they are excellent at testing if an overall group of components is correctly wired together and produces the desired outcome.

Acceptance Testing

Acceptance testing also known as functional testing or QA testing involves testing a complete system that is usually identical to the user’s anticipated system. Acceptance tests can be automated or may be carried out by a QA team. In agile software development terms an acceptance test tests a business story. For example a simple story may be “As a manager I am able to list invoices, filter them by name and date and approve or reject them” An acceptance test would test that scenarios mentioned in the story can be done on a completed system. Automated web application development acceptance tests can be carried out by selenium that simulates recorded browser actions or by asserting HTML structures. Acceptance tests shine in proving if the user story scenarios can be completed but are usually not very good at pinpointing the nature of a problem. They tend to be slow and complicated to set up. Even testing a relatively simple back office application would require to set up an up to date test database, provide datasets for every possible scenario, provide a way to test sending out emails and their contents.

Software development testing is a vast topic that deserves more attention from the the ever growing industry. Automated software testing is often times disregarded as boring, time consuming or ineffective. Mainly because of lack of knowledge and skill to make it work for you and not against you.

, , , , Hide

Find it!

Theme Design by devolux.org