Wednesday, July 18, 2012

Test Driven Development - Recording I

Sometime back, I was working on the development of a service (as part of my work). It was actually a rewrite involving conversion of a legacy EJB based service into simple POJO based service exposed to the external world through Spring remoting. As I had been practicing TDD (and leaning towards behavior driven tests) for sometime, I decided to use the same technique for this work as well. I decided it would be good to record some of my thoughts or opinions about what I was doing and that is why this write up. Though the rewrite use case is the not the typical use case for TDD (which is developing on green field), where it is considered to come out in all its glory, I still felt there are some good points which came out this exercise. Here are a few of my observations of doing TDD with behavior based testing:
  • Let us take a scenario where the Object under test is interacting with third party code. When we do behavior based testing in this scenario, we need to get to know more details of the implementation of the third party code. I did not like it much and started feeling the behavior based testing is making me do this thing, which felt wrong. But later on, I realized that behavior based testing is actually bringing out the fact that the third party code is actually not designed properly and hence the reason for my strife. So this gives me a chance to fix that piece of code. Now, this is nice if I have control on the 3rd party source code. If I have no control on the 3rd party source code then I probably have to move away from behavior based testing to avoid brittle tests.
  • In the pursuit of truly isolating the method under test, I try to mock out all other significant method calls whether external calls or internal methods calls (thanks to mockito's spy). In order to do that I have to increase the visibility of these methods from private to default (package level). I actually don't like doing this. The only saving grace is that the visibility is increased to package level only which still means that it is only visible within its part/sub system of the application.
  • As I write these behavior based tests, I find them very very close to the implementation. So I know that if I have to change the implementation I have to change the tests as well. I am not sure whether this is a completely bad thing. Giving that test is supposed to drive the development, this might be something which is expected (want to think more about this).
  • I realized that as I keep developing through TDD and behavior based tests, I tend to make methods much more granular and cohesive. The methods tend to be small and focused on a single task. This made it easy to test them by mocking other things out. This is a very pleasant outcome of TDD for me.
  • One thing I observed during the process of development is that it is important to have a good set of integration tests. This allows me to catch wrong assumptions I have made during writing of unit tests. Unit tests because of their nature are very focused and hence suffer from shortsightedness. Integration tests help me to overcome this problem.
  • When I am trying new stuff during implementation (say a new technique of persistence etc.) I find it worthwhile to write a integration test immediately after writing a unit test (and the implementation as they go together). This allows me to check out whether the technique is working fine. This idea is just taking the concept of iterative development to a micro level.
As I continue with development, I feel the need to go back and read some of the state vs behavior driven tests related articles. The starting point probably can be 'Mocks Aren't Stubs' article be Martin Fowler. But this time I have decided to read more of them (or may be a book) to get a better idea. Some day I will share what I learn from that.

Tuesday, July 3, 2012

Setting up a nginx virtual host on ubuntu


I had heard of nginx as a very good web server from the perspective of performance. So I decided to try it out for one of my learning endeavors.

Installation

Installation of nginx on my ubuntu was a breeze. nginx is available as part of the ubuntu distribution from canonical. So I could just search the Ubuntu Software Center and install it on my machine. Once installed, starting and stopping the nginx server is simple. Just open the terminal, and use the following commands
  • sudo nginx (starts the server)
  • sudo nginx -s quit (stops the server)
  • sudo nginx -h (provides basic usage help)
One thing to notice is that you have to execute these commands with super user privileges (sudo).

Setting up the virtual host

Being able to run the nginx server is all good. But for me to use it, I needed a virtual host where I can put my development site's content.
Using the readily available and trusted resource, I reached a link which talked about this. After reading the same and some experimentation, I was able to set the virtual host. Below is a brief description of the steps which I followed:

Folder Structure
Once nginx is setup, you find the following folder where definitions of the virtual hosts are kept:
 
/etc/nginx/
The folder structure is as depicted below:

The important folders for our discussion are 'sites-available' and 'sites-enabled'. For all sites which are to be hosted by nginx inside the current machine, an entry needs to be made inside the 'sites-available' folder.  A file needs to be created which holds the configuration and the name of file is the domain name. For example I can create a file - 'ex.nacnez.com' which represents the domain name using which the virtual host can be accessed. The contents of the configuration file are as follows (remember this is just the basic stuff - more configuration is possible but for setting up the virtual host this is good enough):

server {
listen   80;
server_name example.nacnez.com;
access_log  /home/your/docroot/basepath/ex.nacnez.com/log/access.log;
error_log  /home/your/docroot/basepath/ex.nacnez.com/log/error.log;
location / {
root   /home/your/docroot/basepath/ex.nacnez.com/public/;
index  index.html;
}
}
Here ''/home/your/docroot/basepath" means the base path under which you want to store your site and its document root folders.

Setting up the actual document root

The contents of your site is generally placed under its document root folder.

If you look at the configuration above you can understand where the document root of your site is placed. Under the 'public' folder is where your index file ('index.html' as per the above configuration and which could contain any html content) and other website artifacts go. Anybody accessing your web server through the above domain (of course there is more work to be done for that) is taken to this folder. The log folder is used to store logs like 'access' and 'error' logs. There are couple of other folders ('private' and 'backup') but they are not used for simple setups (and I don't even know how they are going to be used - may be something for a future post).

Enabling the virtual host

Though the configuration file has been created inside the "sites-available" folder, the nginx server still does not serve the pages of this site yet. For enabling this, one needs to create a soft link to the config file inside the "sites-enabled" folder.
sudo ln -s /etc/nginx/sites-available/ex.nacnez.com /etc/nginx/sites-enabled/ex.nacnez.com
This enables the site on nginx. Once you restart nginx ideally this site should be available.

Setting up the hosts file

The last important step is to ensure that the hostname is configured in the DNS server to point to your machine. Since I was using it just for my local development, I went ahead and configured my "/etc/hosts" file.

127.0.0.1  ex.nacnez.com

Once this is done, we are all set. If you crank up the browser and type in the domain name you must get the content of your index page.

This was my first encounter with nginx. This was enough for me for my current use of nginx. Hopefully I will get pushed to learn more on nginx and that should be fun.