Showing posts with label pearweb. Show all posts
Showing posts with label pearweb. Show all posts

Sunday, March 30, 2008

PEAR installation process

PEAR needs to think about its usability for newcomers.

Who are our audience?


I would say they fit into several broad categories.

First, the web designer who is learning PHP.
This person isn't used to anything much more than javascript, has lots of basic php language questions, and wants to do possibly nasty things with the language.

Second, the system administrator - this person knows just enough php to know they don't want to know anymore, relies on a range of tools - from cpanel to phpmyadmin.
They are setting up a shared environment, typically. They just want results, and they want them fairly quickly.

Third, the just setting out as a seasoned developer. This person is working in PHP5, and is half a heartbeat away from leaping on the rails-bandwagon. They are looking for frameworks, quick code and things which are visually fun. They are usually working as a full time developer.

Fourth, the ultra seasoned developer. This person is working in PHP5, has a background in Java or other languages, and wants to Do The Right Thing. They are usually working as a full time developer - they use unit tests, design patterns, and are often willing to provide patches.

Probably categories three and four overlap markedly.

Scenarios


Ultra seasoned developer has a specific design problem - database abstraction


The last 3 projects they have worked on have used the mysql extension, ADODB, and others.

They type in 'database abstraction php'; and among the results is PEAR::DB.

The first few links are newbie tutorials, and thus skipped.

When viewing the PEAR::DB homepage, they note it is unmaintained, and MDB2 should be used.

Wanting to know more, they click into the documentation, and read the end user docs.

From here, they see a few samples of code.

Convinced to at least try it out, they then turn to install it.

Newbie has been told to RTFM and learn about PEAR


Using newfound google prowess, the newbie discovers pear. They have been told to go and read the manual about mail(), and want to know how to send attachments.

They land at http://pear.php.net/ and click around a little bit.

They eventually discover the Packages section.

Here, they eventually find a package they want - PEAR::Mail.

They get to the package homepage.

They hit the download button, and are given a .tar.gz - being mostly a windows user, this stumps them.

A system admin at a small web hosting company has had a user complain that fictionalbb doesn't work: it has some error about HTML/QuickForm.php


The system admin pastes the error message into google, and lands on a forum post.

The forum post tells them they need to install HTML_QuickForm, and it's this thing called a PEAR package.

They land on pear.php.net. They give up after a short period, as there doesn't appear to be anything useful.

Instead, they type 'ubuntu html_quickform howto' or 'redhat fictionalbb install' into google.

Somewhere, they locate a forum post, which eventually leads them to the right answer.

How can we make these user stories better?


First, when you land on the front page, there should be a clear direction.

landing-branding

Ask the user what they are trying to accomplish, and direct them to the resources they need.


Second, make the package download page more useful.
download
If you have no idea how to install pear, you are going to end up trying to download.

This page should provide you with more direction, and links to 'installing pear'



Third, when they land on the package documentation page, give them an instant teaser.

documentation

Show the table of contents right there and then, rather than hide it away.

Provide a spot for useful external articles to make the selling process better.

If the user can read and understand right there and then, they'll be happier.

Wednesday, May 23, 2007

UI love for pearweb

What looks better?

Pearweb with dashes

or

Pearweb with solid boxen

#11109: restyle warning css will give pear.php.net the latter.

Mock Database objects, in pearweb

Some things to get you started. pearweb is a pear installable version of the pear website and package management tools.

It would be fair to say it's a little bit... old. However, there are signs of life in the old beast yet, with a slow but sure unit testing suite being built up.

I'm a phpunit junkie, but I haven't used half of the features in it. As betrand points out, there's a lot of complexity under the hood of phpunit.

It's probably for that reason that pearweb have rolled their own very simple unit testing framework. It provides all of your basics; assertTrue, assertFileExists, and what have you. It's called PEAR_PHPTest.

That isn't what I want to talk about, though. I want to talk about the implementation of mock database objects in pearweb, for unit testing purposes.

So: a unit test isn't a unit test if it relies on a database. At work, we usually don't care, and just expect a database to be there. pearweb is a little bit more strict.

So pearweb uses PEAR::DB, and to implement a mock database object, they have created a mock db driver.

To use it is pretty simple, if a little tedious. I'm sure some kind of code generator helper would save heaps of time here.

All you do is:
$mock->addDataQuery("SELECT * FROM categories ORDER BY name",
array(array('id' => 1,
'parent' => null,
'name' => 'test',
'summary' => null,
'description' => 'hi there',
'npackages' => 0,
'pkg_left' => 0,
'pkg_right' => 0,
'cat_left' => 1,
'cat_right' => 2)),
array('id', 'parent', 'name', 'summary', 'description', 'npackages', 'pkg_left',
'pkg_right', 'cat_left', 'cat_right'));


The first parameter is obviously the sql you are executing, the second is an array of result arrays, the third is the columns you expect in the result.

This means you can freeze the exact state of an object in the database, and run unit tests against it, without having to hit the database. Say bye bye to slow tests!


There are methods to simulate updating, inserting, and deleting too.

$sql = "INSERT INTO notes (id,uid,nby,ntime,note) VALUES(%s,%s,'%s','%s','%s')";
$sql = sprintf($sql, $data['id'], $data['uid'], $data['nby'], $data['ntime'], $data['note']);
$mock->addInsertQuery($sql, array(), 1);


So what, you say. That's pretty pointless, you say. Well, not if you expect a sequence of database queries to happen, and happen exactly how you want them to.

For that, we have the queries property of a mock db object.


$db = DB::factory('mock');

$myObject = new MyObject();
$myObject->removeLosers();

$phpunit->assertTrue($db->queries ==
array("SELECT id FROM losers",
"DELETE FROM users");


With a little bit of help from a code generator, there's a definite potential to never be in the dark about what queries were executed again.

Neat, hey. In order to bring some of this goodness to the rest of you, I've logged #11107: Add a PEAR::DB driver for mock objects and #11108: add a PEAR::MDB2 driver for mock objects.

Even if neither of those bugs get implemented, you can always grab the code from CVS