maanantai 22. lokakuuta 2012

DocumentorBundle for your Symfony2 project's documentation needs

After I acquired some inspiration from Mike Van Riel's talk about phpDocumentor2 at PHPNW12 conference, I decided to make it easier for developers to generate their PHP documentation in Symfony2 projects.

https://github.com/artur-gajewski/DocumentorBundle

Once you add DocumentorBundle to your composer.json file and update the vendors with it, you need to activate the module in the AppKernel.php file by adding the following line to the bundles array:

$bundles[] = new \Aga\DocumentorBundle\DocumentorBundle();

Now you only need to run a command in console:

app/console documentation:create

DocumentorBundle will now generate php documentation in /web/bundles/documentor folder, which you can access with your browser by going to that URI.

The bundle generates documentation only from the the bundles installed under src/ folder. What I like about the phpDocumentor2 is the way it tells you what is missing from your php classes; DocBlocks for class, functions and variables. This way you can run the command and fix the documentation until you have no error messages listed.

I also like how visually pleasant the outcome of the phpDocumentor2 is. It is nicely styles and categorized in click-to-see fashion. You can hide/unhide different variable and function types and also can see all @todo statements across the bundles.

Little ending note about DocumentorBundle, PhpDocumentor2 is required. Once they get phpDocumentor2 installable via Composer, this will be not q requirement as I will make it a dependency for this bundle.

perjantai 19. lokakuuta 2012

The importance of documenting your code

Does it feel like waste of time writing DocBlocks in the code you write? Are you one of those people who believe that code documents itself? These questions seems to be a constant battle among developers and those who favor documenting code.

I have done web development for twelve years now. Along these years, as incredible as it may sound, I have never started a work related project from scratch. Instead, I always managed to get right in the middle of the development where code base was pretty much in a state of working prototype.

One thing that I noticed each and every time I joined a project, was how complex it felt to get familiar with the code base that is not well documented. It's not like I didn't know how to read the code and learn from it, but how much easier it would have been to read a short description of a function, a little more detailed one and then read the usage for each of the variables used in the method. One glance, few seconds and I was on the right track about the function's usage and dependencies.

When we live in a world with globalization as a way of doing business, we must remember that a code our competitors write might end up in our hands at some point. I have seen it many times and I have experienced it first hand how it is trying to debug a spaghetti code with no documentation, either printed or inline.

But the main important fact is, that team members can and will eventually change in a project over time. Documenting code as much as possible is your way to show your professionalism and courtesy toward your fellow co-worker. It also allows new team members to get quickly familiar and comfortable with the project's code. Time is money, who has loose money to spend on pointless code familiarizing when it could be a snap.

Documenting your code is not hard, it's not a rocket science. I encourage you to read up a great tutorial of phpDocumentor by Gregory Beaver:

phpDocumentor Tutorial

I hope this blog post will bring you some thoughts on how you can improve the quality of code you write and how much it affects your co-workers.

Until next time, cheers!

torstai 11. lokakuuta 2012

PHPNW 2012 Conference review

It's been a week since I attended my very first PHP conference in Manchester, UK called PHPNW 2012. I didn't know what to expect and what the hype about this particular conference was all about, so I started my journey to Manchester with an open mind.

I packed my clothes and gear (laptop and iPad) and headed to Helsinki-Vantaa. As I waited for an airplance, I read up The Book by Symfony2. Lately, I've been getting more and more interest toward this framework as it seems to be built ease of use in mind, but also good coding standards, latest technology and very nice templating system called Twig.

Once I arrived at the airport I was picked up by Jenny Wong, one of the organizers of the event. I shared my ride with some other developers and speakers and we headed to her house for a little barbeque party. I got to meet some local developers there as well, and so we spent the evening talking about Symfony2, composer and related things.

On friday, I attended full-day tutorial on Zend Framework 2 held by Rob Allen (@Akrabat) and Evan McCoury (@EvanDotPro). Even though I was already quite familiar with the framework, it was nice to go through it all in little more detail. We had little exercises in between chapters, which was nice activity between slides.

After the tutorial there was an evening Hackathon event, in which attendees got to join different groups working on their project. Before the conference, I was talking to Lineke on IRC about their open source project called ProTalk, so this was a great opportunity to meet them in person and start hacking on their project. The wireless connection in the premises was a complete disaster though, as it took minutes just to load Github page. Luckily there was codebase available on memory stick along with vendor dependancies, so we got to hack the code after all with a little bite of pizza and beer.

Saturday started the official conference portion. There were speeches of different topics each hour lasting for fifty minutes each. I found particular interest in talk about new PHP 5.4 features, state of PHPUnit, Twig templating, and opportunities in open source. It was information packed day and while my brain started to process it all, we spent the rest of the evening at the bar without laptops this time. It was nice to meet even more new developers and share experiences with them.

Sunday was the last day of the conference. First I learned how BBC built their website on responsive layout and then I attended a talk about phpDocumentor2 which creates nice documentation of any project based on the DocBlocks in source code.

The closing of the conference was handled by keynote of Michelangelo van Dam, as he explained how companies could pitch in into the world of open source.

I could not be happier about attending the conference and would love to attend it again next year. The location was great, everything was organized with skilled people, conference contained interesting speakers and extra activity and the one could really feel like a part of a large community.

Inspired with all the experience, I revived this blog and will write here more often now.

keskiviikko 11. tammikuuta 2012

TDD or better known as Test Driven Development

In Test Driven Development, the idea is to create test cases before you create the application code itself. Simple as that, or is it? It seems a lot of people don't get the idea behind TDD and instantly ask how can one create test scripts for a code that doesn't exist yet. Let's go over this process and learn the true power and efficiency you obtain with test driven development method.

So you open your favorite IDE (Zend Studio or Eclipse PDT in my case). You know you want to create a user class so you first define functions for it by writing down the specifications of course. You can the class skeleton, and functions to set and get user's last name.

Now you need to write down a test script for the class. But how exactly and what should you test for? Well, have a look at yours specs. You have a User class and according to your specifications, you have getter and setter for the lastname.

<?php
  class myClassTest extends PHPUnit_Framework_TestCase
  {
    public function testClass()
    {
      $user = new User();

      $this->assertEquals('User',get_class($user));
    }
  }

Now you have the very beginning of your test script. It's doesn't test much yet, but it will do for now. Now if you run this test with PHPUnit, you will get an error due to non-existing class file. So what do you do next? Create the class file itself.

<?php 
  class User
  {
  }

Yes, now we have a class file created and when we run the above test script again, we get a success this time. We tested that the instance of $user is class of User.

Getting the point now? First we write the test scripts based on the specifications and then little by little we add to the class and test on each iteration that all of those tested areas are added to the class and passing the objectives defined.

This method, of course, requires great amount of effort put down on writing down the specifications. This, however, should not come as a surprise to anyone dealing with web development.

But do you really want to know the great thing about this method? Haven't figured it out yet? When you get your class completely written and ready, you already have test cases created for that class!

Tell me how many times you really have time to create test scripts after you have written the classes? Even after 12 years of web development career, I have not seen one developer who writes test scripts with great joy and pleasure. If writing down test cases based on specifications and then writing classes to satisfy those test cases would be a way of development, we would be that one step better developers.

torstai 5. tammikuuta 2012

Don't Repeat Yourself

In movies, have you ever heard of saying "Don't make me repeat myself!"? We all hate saying the same thing to someone again and again, but why is it that we tend to use the same block of code multiple times across our applications?

Today was an interesting day for me, as I got to observe bunch of talented developers speaking about how things are done and what should be concidered while doing it. One thing they discussed was DRY development method, in others words, Don't Repeat Yourself.

In other words, what they were talking about was the usage of copy/paste to generate whatever you are trying to generate. In order to develop maintainable code, one should never copy function from another place to have a certain outcome. The code should be written in such a way, that the information, or a process, is obtained from one single place and used where ever needed. If you need to somehow refactor this certain process, it is an easy task due to the fact that logic behind it needs to be refactored only in one place.

I have seen, and yes, used myself the bad habit of copying something from another place in order to get something accomplished fast. Later on, I noticed it wasn't the smartest way of approaching the problem, thus generating more refactoring to be done whenever time allows.

I knew how this problem exists but I never knew it has a term... until today.

keskiviikko 21. joulukuuta 2011

How to use Phing to run PHPUnit scripts and generate HTML reports

Phing is a really neat application build and deployment tool that you can also use to run PHPUnit tests. What is so nice about it is the simplicity of the build script and the possibility to obtain nicely formatted HTML report of the test scripts.

You can manually generate HTML report with PHPUnit by using an extra switch to generate the results in XML format, like so:

$ phpunit --log-junit report.xml MyApplication

MyApplication is the directory where all the test scripts reside and report.xml is the output report file in XML file. Now it is up to you to either manually parse the XML file and generate HTML report based on it or you can use XSLT to transform the XML to nice HTML web report.

As I said before, why invent the wheel again when you can let Phing do this for you automatically. Before we build our first build file for Phing, we need to install the Phing itself in case you haven't done so yet. I take it you already have PEAR installed so all we have to do is enter the following:

$ sudo pear channel-discover pear.phing.info
$ sudo pear install phing/phing

After Phing has been installed successfully, all you have to do is enter 'phing' in the command line. This will bring you 'Buildfile: build.xml does not exist!' error message because Phing tries to open build.xml in the directory where Phing is called in. So off we go create our build.xml file to run our PHPUnit scripts.

So we are in a directory that contains a subdirectory called MyApplication. This directory has all the test scripts. Create a file called build.xml and copy/paste the following into it:

<project name="MyApplication" default="build">
  <property name="package" value="MyApplication" override="true" />
  <target name="clean">
    <delete dir="build"/>
  </target>
  <target name="prepare">
    <mkdir dir="build/logs"/>
  </target>
  <target name="phpunit">
    <phpunit printsummary="true" haltonfailure="false">
      <formatter todir="build/logs" type="xml"/>
      <batchtest>
        <fileset dir=".">
          <include name="MyApplication/*Test.php"/>
        </fileset>
      </batchtest>
      <formatter type="xml" todir="report" outfile="logfile.xml"/>
   </phpunit>
   <phpunitreport infile="report/logfile.xml"
                  styledir="/usr/share/php/data/phing/etc"
                  format="frames"
                  todir="report"/>
  </target>
  <target name="build" depends="clean,prepare,phpunit"/>
</project>

If everything goes well, Phing will scan for *Test.php files in the MyApplication directory and run their tests. After the test run, an HTML report package is created into subdirectory called report.

Depending on your environment, you might have to edit the styledir="/usr/share/php/data/phing/etc" portion of the above script to reflect the path where the XSL files for the phing reside.

To make the most use of the HTML report page, set the Phing script to create it within your server's web folder so that you can access it with your browser. Now you can schedule a daily or hourly test run and you will have updated report of your deployed application's test run whenever you need one.

tiistai 20. joulukuuta 2011

Running Selenium tests on PHPUnit

Lately I have been dealing a lot with PHPUnit testing of variety of applications. Main focus has always been on testing the backend classes for applications, but lately I have learned the importance of testing also functional aspect of a web page.

For years I have generated functional test scripts with Firefox's add-on called Selenium IDE, which allows you to record page clicks and text inputs and then run the recording as many times as you wish.

Now, to make full potential of Selenium, one should really take advantage of running Selenium test scripts in PHPUnit to combine both backend testing as well as functional testing. First you need to install Selenium RC server which is used to launch a web browser of your choice and do the things you recorded.

Requirements:

- PHP (obviously)
- PHPUnit
- PHPUnit_Selenium (an extension for PHPUnit)
- Selenium RC server
- Internet browser (Firefox/Chrome/Internet Explorer)

Let's start off with installing PHPUnit from PEAR if you have not done so yet.

$ sudo pear upgrade pear
$ sudo pear channel-discover pear.phpunit.de
$ sudo pear channel-discover components.ez.no
$ sudo pear channel-discover pear.symfony-project.com
$ sudo pear install --alldeps phpunit/PHPUnit

Now we need to make sure we install also the Selenium extension to PHPUnit.

$ sudo pear install --force phpunit/PHPUnit_Selenium

In the above command line, we used --force switch to ignore a possible error message about Curl not being installed.  Selenium extension requires that Curl is installed so make sure it is.

Now that we have installed all required PHP classes and extensions, it is time to move on to the Selenium RC server which we connect to each time we run Selenium tests in PHPUnit.

First, browse to http://code.google.com/p/selenium/downloads/list click on selenium-server-standlone-2.*.jar (at the time of writing) link, and then copy the url of the selenium-server-standlone-2.*.jar file.

Next, open up a terminal window and type:

$ sudo su
$ mkdir /usr/lib/selenium/
$ cd /usr/lib/selenium/
$ wget url-you-copied-above
$ mkdir -p /var/log/selenium/
$ chmod a+w /var/log/selenium/

Next, take this attachment, and save it as /etc/init.d/selenium

Now edit the file, and change the filename of the standalone server file (currently selenium-server-standalone-2.0a5.jar) to the name of the server file you downloaded above.

Finally, make the script executable:

$ chmod 755 /etc/init.d/selenium

To start Selenium RC server:

$ /etc/init.d/selenium start

Finally, add the script so that it starts automatically when the server does:

$ update-rc.d selenium defaults
Congratulations, you have now done all the preliminary configurations to get the testing environment up and running.