Wednesday, August 27, 2008

Installing PHPUnit, Testing_Selenium, and Selenium RC in Windows Vista

What is PHPUnit?

  • PHPUnit is a testing framework to create and run automated unit tests for your web application.
  • PHPUnit helps test the back-end of your web application by running through certain parts (units) and test them, comparing them with the expected output
What is Selenium?

  • Selenium is a suite of test tools to help test the front-end of your web application. The front -end being the visual aspect, and browser compatibility.
  • Using Selenium you can create automated tests to ensure your product is less prone to errors
While trying to install Selenium, I never found a resource that had a simple install guide with everything I needed. That being said, I hope this can help someone who needs to install everything - and if it doesn't, well at least it will help me if I need to install them on another computer ;)

How to install PEAR, PHPUnit, Testing_Selenium PEAR package, and Selenium RC in Windows Vista:

This post assumes PHP is installed (I used 5.2.5) in C:\php\ (change the directory where applicable).

The first thing you'll need to do is to install PEAR. To do this, Open up your command prompt. You can do this by:
clicking the start button
typing "cmd" (without quotations) in the search field
Click the "cmd.exe" application or Hit ENTER if that's the only one there

In the command prompt, go to your PHP root directory. Mine was located at C:\php\
cd C:\php\

Run the go-pear.bat file with the command prompt. This batch file will install PEAR in C:\php\PEAR\

Next, you'll want to install PHPUnit. To do this, type the following in the command prompt:
pear channel-discover pear.phpunit.de
pear install phpunit/PHPUnit

The first command registers the pear.phpunit.de channel with the local PEAR environment - basically it lets PEAR know where to get PHPUnit from. The second command downloads and installs PHPUnit.

After it installs, you'll be able to find it in C:\php\PEAR\PHPUnit\

Next, you'll want to download the Selenium package using pear. As of this writing, the newest version is 0.4.3. In the command prompt, type:
pear install Testing_Selenium-beta

At this time, if you don't have Java installed, you should install it now: http://www.java.com/en/download/manual.jsp#win
To check if you have java installed, in the Command prompt type "java -version" (you need JRE 1.5 or higher).

After that, you can install Selenium RC. I downloaded the most recent at this time; Version 1.0 beta 1: http://selenium-rc.openqa.org/download.html
Create a new folder called "selenium" somewhere easily accessible by the command prompt.
Inside the folder you downloaded there's a Selenium-server folder (Mine was called "selenium-server-1.0-beta-1"). Move all the files in the Selenium-server folder into the "selenium" folder you created, mentioned above.

In the Command prompt, go to the directory that contains the Selenium server.

To start the server in interactive mode (allows you to control the browser manually), type the following in the command prompt:
java -jar ./selenium/selenium-server.jar -interactive

And finally everything is set up to create and run tests!

To create tests, you can use the Firefox plugin IDE to record actions. Alternatively, you can code them yourself.

If you use the IDE: After you create a new test, export it as PHP to an easy-to access location.
In the command prompt change your directory to the location of your new test.
use the following to run the test using PHPUnit:
phpunit testname.php

Assuming you've done everything correctly, PHPUnit will read the test file and tell your running Selenium RC server to open a browser. From there, it will go through your test and give you a report!

Wednesday, July 16, 2008

Fat Models, Skinny Controllers

What is a fat Model?
  • When I say fat, I'm not talking about the FAT filesystem here - I mean long lines of code, methods, variables, etc. Basically, a fat script would be a big script.

Why should I make fat Models vs skinny Controllers?
  • After developing for awhile, when you look back at your code you'll realize how hard it is to keep track of things. Basically, with a skinny controller (and meaningful function names) you can quickly see what's going on. When you have a controller with 300 lines of code, it can get pretty messy looking (even with proper formatting)...So to solve that problem, simply put many of your functions in your Models instead.

What type of functions should I put in my Model?
  • The type of functions you should put in your model should be anything related to your model, or it's data. Formatting, Retrieving, Searching are just a few examples.

What type of functions should I put in my Controller?
  • Usually, the only functions you should have in your controller are: Index, Add, Edit, View, Delete, and the "before" functions. Almost anything else can go in your model.

When I first started with CakePHP, I put almost everything in my controllers. In reality, the controllers should be extremely tiny - and only contain important business logic. As I worked with CakePHP more, I also learned to start putting more in my Models and less in my Controllers.

To put a function in your Model, you do it the exact same way as putting it in your controller:

function getEventDetails($_id) {
$params = array(
'conditions' => array(
'Event.id' => $_id,
),
);
return $this->find('first', $params);
}
To use the function, inside your controller use the following format:
$this->ModelName->functionName();

Here's an example:

$eventDetails = $this->Event->getEventDetails($_id);
After adding functions to your models, you can also access those functions using Model associations if they're set up correctly:
If you have a User Model and an Event Model that are associated,
you could put this in a method in your Users Controller:

$eventDetails = $this->User->Event->getEventDetails($_id);

Monday, July 14, 2008

CakePHP Plugins

Plugins were a great idea added to CakePHP 1.2 that allows you to create a mini web application inside your main web application. This mini web application you can then distribute to other users, or your other projects, to reduce re-inventing the wheel so much.

Plugins were a great idea, but is not quite something the CakePHP core team really focuses much attention on, and probably never will. Despite that, CakePHP plugins can still be very useful for decreasing code time between projects - as long as you remember the pitfalls associated with them.

Some very important things to remember when working with Plugins:

  • When naming controllers, try to make their names unique (to prevent any ambiguity errors if two controllers have the same name) Usually prefixing any filename with the plugin's name works great (such as calendar_events_controller.php where calendar is the plugin name)
  • Every controller in your plugin must be told where to find its models. Even though you're using the $uses variable, still try to stick with CakePHP's conventions of having 1 model per controller. To tell your controller where your model is, use the following:
    • var $uses = array('PluginName.ModelName');
  • When working with model associations in a plugin, never use the short form (eg. $hasMany = ModelName); always extend it like the following examples(!Notice how className has PluginName.ModelName, where the ModelName before that is by itself!):


var $hasMany = array(
'ModelName' => array(
'className' => 'PluginName.ModelName',
)
);

and

var $belongsTo = array(
'ModelName' => array(
'className' => 'PluginName.ModelName',
),
);

below are two examples taken from two different models:
Special Note: The key in the array doesn't contain the plugin name but the className part does

var $hasMany = array(
'CalendarAttendantsEvent' => array(
'className' => 'Calendar.CalendarAttendantsEvent',
'dependent' => true,
)
);

var $belongsTo = array(
'CalendarAttendant' => array(
'className' => 'Calendar.CalendarAttendant',
'foreignKey' => 'calendar_attendant_id',
),
'CalendarEvent' => array(
'className' => 'Calendar.CalendarEvent',
'foreignKey' => 'calendar_event_id',
),
);


Using the above examples, I haven't had any troubles working with associated models in my plugin, but any other way I've tried wouldn't work properly in some cases (such as accessing a model's function through associations with $this->ModelName->functionName(); )

Also, please see the manual for more information: http://book.cakephp.org/view/114/plugins

Tuesday, June 17, 2008

CakePHP 1.2

CakePHP is a free and open source rapid development framework for PHP that greatly reduces the time required to create and maintain small to large websites. I've only been using it for roughly a month, however, it has proven to be a valuable tool thus far.
For those new to CakePHP and who'd like to take a look at what it's all about, please see the main site at http://cakephp.org/ From the main site, you can download it (the newest stable release as of this post is version 1.2.0.7125) as well as learn the ins and outs of this tasty cake!

But why should you use CakePHP? How does it help?
Well, CakePHP organizes all the files for your web application into 3 different categories - Models, Views, and Controllers (MVC design pattern). Models are much like gateways to your database, Views are the HTML/PHP pages that displays the data, images, or information. The Controllers are where the main functions of your web applications reside.

Let's look at an oversimplified example of the MVC design pattern:
A user wants to post a comment on your blog. She types in her message and clicks on the "Post!" link to post her comment. The data is sent to the Controller, the Controller then sends it to the Model which inserts it into the database. After being inserted, data is sent to the View and you see your "The Post was Saved Successfully!" message.

Why would you want your code separated like this? Because it's a lot easier to maintain. Furthermore, if you have an error you need to fix, you know almost exactly where to look for it. Is it a database error? Check your Model or your database. Is it a template issue? Check your view.

CakePHP also has many built in functions and helpers that help you quickly, easily and (usually) painlessly find information from your database, manage user permissions, use AJAX and even display forms (to name a few).

I would highly recommend viewing the CakePHP manual (aka "The Cookbook") for more information and for a much better explanation of how things work, what you can do, and what you can't. You should also take a look at the Blog tutorial located in the Cookbook for a walk through of many useful functions to easily create a Blog. The cookbook can be found at http://book.cakephp.org/view/7/introduction-to-cakephp.

As I learn more about CakePHP, I'll be posting more blogs about it, what problems I've had with it, and how to get around those problems.

Until then,
Happy Baking!