Function Documentation

WordPress Function Documentation Progress

The Automated Testing Methods

There are quite a few testing techniques and ways to implement test cases for an automated test system. A few that should be implemented for WordPress are listed, but there are others and with better details on other web sites. I’m not the authority on unit testing and I don’t pretend to be. However, what I do know is detailed below and take my word with a grain of salt. I will say that the details are in general what can be applied when coding test cases.

  1. Unit Testing

    Unit testing is quite what it says, you are testing a single unit or component of the library. This can be function or method. This method usually makes use of mock objects for classes to correctly test the behavior of an individual unit.

    This method has the advantage of allowing for testing code coverage and finding out just how accurate your tests are.

  2. Regression Testing

    I would argue that this is the easiest of the methods, since all you are doing is checking the current behavior and writing tests to make sure that the current behavior continues in later versions.

    You’re not actually getting down into the source code and making sure that all of the branches are covered and that the correct results are covered. You are also not always checking that incorrect data has a fallback in place to prevent failures.

  3. Functional Testing

    Functional Testing is a step up from unit testing, where you are testing a component within the software environment. This is more how the Automattic Automated Testing suite is set up. It does not allow you to test the code coverage, because since the entire software environment is running it will skew the code coverage results.

    The primary difference between unit testing and functional testing is that with unit testing, every test in unit testing is self contained and does not interfere with the other tests. With functional tests, you have to be careful, because the tests are not contained and will affect other areas. Other than that, it would be easy to switch from unit testing to functional testing and back again.

  4. Acceptance Testing

    Users do this already, but this method is more about automating the process of what users do. It doesn’t completely replace user testing, but it does complement it. It reduces the tedious tasks of inserting content and does that and returns the results. For known problems, it is very useful in order to prevent presentational regressions.

    It is also quite frankly, in my humble opinion, one of the most difficult to accomplish for browser based acceptance testing. Selenium is very helpful, but setting that up has been difficult for me. If you can get it set up then PHPUnit can talk to it and it would be as easy as writing any unit or functional test.

Advertisements

January 19, 2008 Posted by | Quality Assurance Series | , , , , | 2 Comments

Protected: Talk Draft

This content is password protected. To view it please enter your password below:

January 18, 2008 Posted by | WordPress | Enter your password to view comments.

What is Quality Assurance?

Quality Assurance is ensuring the quality of a product. It is an ongoing process that never ends, or at least not during the life of the product. Quality Assurance in open source is a more open process and anyone can help.

It involves testing, documentation, and automated testing. Testing is the most important factor, but documentation is equally important. Actually, Software Quality Assurance is a paradigm that involves a great deal more, but for the purpose of this discussion, I’m going to limit this to just the above three.

What it means to the User

When you commit to Software Quality Assurance, you are telling the customer and user that you have a policy in place that will hopefully prevent a majority of preventable bugs from occurring before the product is released. In the likely event that a bug is found, there is a policy in place that ensures that it will be fixed and prevented (in most cases) from occurring again in the future.

It also says that there is detailed documentation for both the users and developers which extensively covers the topics that both groups will want to know. Extensively covers the known areas and areas that have been questioned about in previous versions. Covers the more difficult areas better and with more details than “simpler” topics that users and developers should not have any problems with.

Solving Issues

Users, testers, and developers all help with the process. The user can make a request for a new feature that will improve the product or report a problem in the product. The testers will usually beta test and test versions of the product before it is released reporting any issues that come up. Developers will take the reports and create patches that fix the issues for the next version.

Developers will also write test cases that check whether the problem is fixed and if the problem reoccurs in a later version. If the problem does reoccur then the problem is immediately known and can be rechecked until the regression is corrected. If the regression was intentional, then documentation would have to be updated and other developers updated on the change.

Writing Documentation

Writing documentation should be concise, tutorial type explanations in language that an user and/or a developer will understand. For open source, I would just recommend writing something as close as possible to this style as you can get and cut the extraneous details (ex, I don’t want to know about how you used it in your project and the history, unless it further explains the purpose of the function, sometimes it is useful, other times it is not).

Not everyone is a professional writer (myself included), but there are enough people who are that if you give them enough information, they can edit it to where it is better. I write with the assumption that someone is going to look at what I wrote and point out mistakes and hopefully, instead of cussing me, will actually move to fix the mistakes. On Wikis, this is very simple process, on this post however, they would have to send it to be me personally or export it to their blog or wiki.

Testing Software

You are testing that the software works (well, yes you are for those who are disagreeable), you are trying to test whether the software breaks. Therefore it makes more sense to input invalid data to see if what is expected happens or not. Developers (indeterminate amount, I have this problem, so I only speak of myself and the general stereotype of developers with testing their software) have a habit of only using valid data.

You only know that the software works if you enter something invalid and it didn’t break on that input. If it breaks on invalid input, then there should be a check in place that either automatically the problem or informs the user of their mistake. There is also automated testing, which automates the lower level testing and higher level testing which automates some of what users do.

January 18, 2008 Posted by | Quality Assurance Series | , , | Leave a comment

Roadmap of WP-Includes Inline Documentation

A followup to the earlier post on unfinished functions to write how I’m going to document the files based off of the information in that post.

Finished Files

These files have been finished since the last post. There are only 18 more files to complete before the entire wp-includes folder is documented!

  1. l10n.php
  2. pluggable.php
  3. kses.php
  4. locale.php

Must Finish Before WordPress 2.5

I want to get these done as soon as possible and at least before WordPress 2.5 is released. Not sure if any of these files will be done in any particular order as listed. Probably just whatever falls in this list and that I feel like documenting.

  1. user.php (9 functions left)
  2. comment.php (Already started: 20 functions left)
  3. cron.php (also need a post on how to use it. 13 functions left)
  4. category.php (15 functions left)
  5. script-loader.php
  6. feed.php
  7. wpdb.php (10 functions left. File has incomplete new methods which require documentation.)

Must Finish Before WordPress 2.6

If I can’t get finish these before WordPress 2.5, then I hope to get them in before WordPress 2.6. Probably doing a lot of work during the Summer. It will be cutting the work close to the deadline for getting these in to WordPress 2.6, if I wait until last half of May.

  1. category-template.php
  2. capabilities.php
  3. query.php
  4. post-template.php
  5. link-template.php
  6. post.php (not everything perhaps, but a lot more finished, it is already started)

Must Finish Before WordPress 2.7

These will probably be finished either before WordPress 2.6 or during the time that the WordPress wp-admin/includes files are started to be documented. These are long files with a lot of documented functions and elements. They will take many hours to document each, so they’ll most likely be worked on over the course of an entire version.

There aren’t that many files and hopefully the functions when they are finished will be committed. In that way, at least some of the work will benefit users while the work is continued. It is the way that the taxonomy.php file was handled and it took quite a while to document that file (not because of time but because of motivation).

  1. formatting.php
  2. functions.php
  3. general-template.php
  4. post.php
  5. theme.php
  6. widgets.php
  7. classes.php

After the wp-includes folder is finished with complete inline documentation, it will be time to work on wp-admin/includes/, and perhaps the rest of the wp-admin folder for as many inline documentation worthy items as possible. After that, it will be time to help with the effort to write test cases for the WordPress library to ensure quality.

As an Aside

I hope to continue the Developer Manual work for as long as possible leading up to WordPress 2.5 and beyond to WordPress 2.6. Eventually, at some point I’m going to have to write some User Manual posts to eventually add to the codex. After that, I’ll have to package everything up and post the full contents of those posts to the codex for everyone else to edit and enjoy.

At my current rate, I should have a lot of content before WordPress 2.5 is completed. I should note that I don’t feel obligated to post every day and since I have school now, if I can’t write enough posts on the weekends, there will be times when I won’t have enough posts to last until the next weekend. Usually, I just drain all of the information from my head until I have nothing left.

Until next time, I hope you enjoy reading the rest of my posts!

January 17, 2008 Posted by | WordPress | , | 1 Comment

Writing Plugins: Don’t Place All Methods in One Object

Objects should only contain a single purpose, but most plugins I’ve seen pack every method in a single object. This opposed to splitting the methods out into better logical objects which contain that purpose and allow reuse across multiple projects. I would like to instead propose a better way to write objects, which don’t violate the advantages and purpose of objects. Packing everything in the same object did cause problems prior to WordPress 2.3.

I believe the reason that plugin authors have for placing all of the methods in the same object is:

  1. To keep the plugin contained for the user.
  2. That it is easier to access all of the methods and properties.
  3. Place all data and methods in a single namespace.

Objects are supposed to solve the question of reuse. It should seem reasonable that if plugins were decoupled objects, then it would be possible to easily create that same plugin for another PHP application. That is probably not the intention of the plugin author, but it could be another user’s or mine.

A solution for plugins which do this, is to inherit the object and override the methods and data you need to change. I did this with a recent plugin, which allows me to upgrade the plugin’s code without having to make the same changes over and over again.

The general rule I keep is when I’m building a class is either to plan out what methods each one it going to have and what properties and finally how each will interact with the other. If you must jump in and code without planning then once you reached a point where you are adding methods and properties that fall outside the scope of the original functionality then stop and ask, “How can I refactor this?”

For me, it is a constant question I ask about my code, because unless you’ve been coding objects for most of your life, there can always be improvements made. Decoupling your code also has the advantage of allowing you to reuse, which is key with objects and functions, in another plugin or project.

Most plugins that I’ve seen are coupled and can not easily be refactored without an almost complete rewrite of the core systems. If this is the case, then good luck and I wish you the best for your plugin.

Better Standard

I personally don’t use classes for my plugins. However, if I were to use objects, I would do it in this matter.

I would have a single class for the activation, deactivation, and init hooks.

class MyPlugin_Core
{
    function activation_hook()
    {
        // Do activation stuff
    }

    function deactivation_hook() {  }

    function init_hook() {
        $objMyPlugin = new MyPlugin_DoesSomething();

        // Do stuff with MyPlugin_DoesSomething
    }
}

register_activation_hook( __FILE__, array('MyPlugin_Core', 'activation_hook') );
register_deactivation_hook( __FILE__, array('MyPlugin_Core', 'deactivation_hook') );

add_action( __FILE__, array('MyPlugin_Core', 'init_hook') );

More of how you should structure your plugins in a later post.

Updated: An object is an object and a singleton is an object which only returns one reference to itself. With objects, you can create any number, but the Singleton pattern restricts creation to only one. Thanks to Jamie Talbot for the correction!

January 16, 2008 Posted by | Writing Plugins Series | , , | 5 Comments

Getting Involved with Quality Assurance

WordPress is a community effort and it takes everyone in the community to make WordPress the best it needs to be. Getting involved is as easy as using WordPress and reporting when defects show up. It can get up to creating patches for WordPress Trac defects or enhancements. Everyone can do something and people are doing great things for WordPress every day.

Testing WordPress Trunk

If you use just the versions of WordPress that are released, some bugs that you find could have already been fixed on trunk and just awaiting the next release. If you want to really test WordPress, you must first check out the Trunk and join the WP-Testers mailing list.

When testing make sure you input both invalid and valid information and keep in mind what you are expecting what the actual result is. You are trying to break WordPress! If something doesn’t break, then you aren’t trying hard enough or WordPress already has checks which prevent it from breaking.

Reporting Bugs

Reporting bugs is one of the easiest ways to get involved with quality assurance. If a defect is not reported then the WordPress developers and community will not know of the defect. The sooner a defect is reported and confirmed the sooner it can be fixed.

You can report bugs at the WordPress Trac Site. You can also find more information on reporting bugs at the WordPress Codex: Reporting Bugs. As an reminder, you may need to stay around for the life of the ticket to make sure to answer any questions and to follow up on anything that developers or others may need to satisfy the requirements of the report.

Remember: make sure to check the defect or enhancement hasn’t already been fixed or reported. Doing so, will be appreciated by those who have to mark your ticket a duplicate.

Writing Patches

The next step from reporting defects or offering suggestions for enhancements is to provide solutions to existing defects and enhancements. As for most people, you may choose whatever ticket of your ability and liking. You don’t have to start at the top and work your way down.

It should be noted that the tickets of low priority probably won’t be as committed as quickly as those tickets that have a higher priority. Give enough time for the core development team to look over your ticket and see if it worth committing. Keep in touch after you commit the patch to make sure that answer any questions those in the community and core development team may have.

If a reasonable amount of time has past without any resolution with an existing patch, writing another comment asking for a response or set one of the keywords to include ‘dev-feedback’ (without the quotes). It might be that the development team might have forgotten about your ticket. Leaving a friendly reminder might push the ticket ahead in their minds.

When your patch does get committed, rejoice, it will be one less ticket in the queue. Any amount of help is appreciated.

Writing Codex Documentation

The codex is the central place for finding information and help on WordPress. As many features and solutions that WordPress offers, the amount of help is far to broad to be completely covered by any one page or person. If you notice that there is a section that is missing, then sign up and add it.

Writing Inline Documentation

WordPress also needs to have inline or source documentation for those who browse the source for their information. Not everything can be learned from the codex and since the codex can grow outdated, it would be useful to look at the source from time to time. Those that do look at the source need additional information in order to quickly realize what the code is supposed to be doing.

It is also useful for those who can’t read code as clearly as some of those who have been reading and writing code for a long time. In order words, it helps novices of PHP to learn what WordPress is doing. They might not be able to build an application like WordPress, but they can write plugins that are useful for them and/or other people.

There is currently an Inline Documentation Standard that should be used. It is unwise to write a lot for functions since there is a tiny amount of overhead in processing the comments. Not much, but leaving as much detail to only describe what the function does should be enough. Any examples can be located at the codex.

Writing Test Cases

There is currently an Automated Testing Suite for WordPress which you can provide test cases for. Test cases are useful to prove or disprove a defect and whether a patch fixes the defect. Without test cases it would be difficult without manual testing to find out if the defect was fixed. The test cases also can test whether the defect shows up in the future (called a regression).

Writing test cases will be detailed in a later post. Make sure to stay around to learn more!

January 14, 2008 Posted by | Quality Assurance Series | , , , , , , | Leave a comment

Writing Plugins: What is the Class Callback Format?

Prior to WordPress 2.3.0, there was a bug that prevented object referenced method callbacks from being removed. In WordPress 2.3.x and upcoming WordPress 2.5, in order to remove the original method in the class, you have to use the original object reference. In PHP4, where objects are passed by value, this can be a problem, but PHP5 users shouldn’t have much to worry about as long as the variable they are using holds the original class reference.

Explanation of Problem Prior to WordPress 2.3

To demonstrate the problem, take a look at this code. If you were to run this prior to WordPress 2.3, the hook would not be removed because you changed the class property $test.

class MyPlugin
{
    var $test;

    function MyPlugin() {
        $this->test = false;
        add_action('init', array(&$this, '_init'));
        $this->test = true;
    }

    function init() {
        remove_action('init', array(&$this, '_init));
    }
}

This is a poor example, in that the ‘init’ hook will never run again. Other hooks will demonstrate the problem better in real world practice. That said, the method of adding callbacks to the hook array wouldn’t have allowed you to remove the hook until the state of the class was back in its original form prior to the addition of adding the MyPlugin::_init() to the init hook.

It is a little complicated to explain, but basically, once you changed the properties of the class, you wouldn’t be able to remove any hook you added prior to the change. For most plugins this was a huge deal since they had everything in one Singleton class (big mistake, will detail in later post).

How Method Callbacks are handled in WordPress 2.3+

A new private function was introduced to manage object referenced method callbacks. The form of which is below.

$myplugin = new MyPlugin();

add_action( 'init', array(&$myplugin, '_init') );

As you can see, the callback references the $myplugin variable along with the method in the second element. The reason this can cause a problem, is if you unset the variable afterwards.

$myplugin = new MyPlugin();

add_action( 'init', array(&$myplugin, '_init') );

unset($myplugin);

If you think this will magically remove the reference in the hook array, you are mistaken. PHP will retain the reference to the object and will call the method. This will hinder, but not prevent the removal of the object’s callbacks later.

For a workaround, you can recreate the object reference and it should (purely conjecture) recreate the needed hook string to reference to previously added object reference callback. This will not work if two or more object references of the same class were created, so it is assumed that in most cases only one object reference will be created. If only one were created and destroyed, it might be possible to remove the callbacks from the action or filter using the Plugin API.

New format

The new format for the above object referenced method callbacks are always: class name, followed immediately by the method name, followed by the amount of previously added (classname+methodname). For classes, this allows you to add as many object referenced classes and add methods which don’t override each other.

For static method callbacks, the format is always: class name followed immediately by method name. There is no need to protect against overrides because no two classes can have the same class name (yes, I do know there is an exception to this rule).

For functions, nothing changes, it is just the function name.

January 13, 2008 Posted by | Writing Plugins Series | , , , | 5 Comments

Ohloh No Longer Criticizes WordPress Comment Ratio

Ohloh no longer lists the comment to code ratio as a factor for WordPress! This will hopefully improve as the PHP code base continues to be documented. Hopefully, once the focus is moved over to automated testing, the bugs and functionality will be improved to the point where WordPress will be rock solid.

This will hopefully limit the overall criticism that other developers have on WordPress. It will be a long road for complete documentation and quality assurance in WordPress. It is both fun and worthwhile learning experience. It is something that should have been in WordPress since the early days, but that isn’t important.

What is important is that not only should the quality of the WordPress feature set and defects reduce but the overall quality and assurance of that quality should be improved.

January 12, 2008 Posted by | WordPress | , , , , | Leave a comment

Informal Roadmap: Step 2 Completed

All items that could be documented in wp-includes folder has been documented with @since phpdoc tags. Which will allow for staying in that one file instead of going back and forth from web browser with version information to the editor. Will save time, I believe.

All that is left now is basically the following.

  1. Short Description
  2. Return type and description
  3. Parameter type and description
  4. Long Description

Now that the second step is completed, I’m going to focus more on completing the following files below. During that, I’m going to create tickets for the remain incomplete files that I’m not going to seek to finish. In that arena, there are only 20 incomplete files in wp-includes folder. If I complete the following files, I can get that number down to a more manageable 14. So that the next person that comes along shouldn’t feel a lot of weight on their shoulders.

In no particular order, I want to complete these files before the 14th of January 2008 is up. If I can complete at least 3, then I’ll be happy.

  • kses.phpalmost complete
  • pluggable.php – almost complete
  • comment.php – almost complete
  • cron.php
  • category.php
  • user.php

The most logical course of action is to finish up the almost complete files and have them committed as completed. Then start working on the rest of the easy files which shouldn’t take very long to complete. Probably should get cron.php started first since it is one of the most difficult with extremely sparse documentation. The category and user files will be worked on, in the event that there is more time left over.

So the goal jumped from 3 finished, to 4 finished and in one weekend. Wish me luck.

January 12, 2008 Posted by | WordPress | , , , , | Leave a comment

Writing Plugins: Does the filter or action exist?

This WordPress Plugin API feature is new to WordPress 2.5 and is quite interesting. Its application in plugins will be interesting to see when WordPress 2.5 is released.

The has_action() and has_filter() checks for the existent of hooks and whether a specific callback exists within the filter. This is useful, since it allows you to check whether anyone has added a callback to a specific hook. It also can prevent you from removing a callback that had already been removed.

Testing the Existence of a Hook

Hooks are only created when callbacks are added and in WordPress 2.5, when there remains at least one callback in the hook. If no callbacks are added to a hook or all callbacks are removed then both has_action($hook_name); and has_filter($hook_name); will return false.

This can be useful for creating your own filters for your plugin to see if anyone had hooked into your actions and filters. You can halt running the action or filter if there is nothing attached to the hook.

Removing Callbacks from Hooks

It used to be quite the process to test whether a callback existed and get the priority of the callback in order to remove it. These processes have been simplified in WordPress 2.5 and will make both finding and removing a known callback easier.

The key is that the callback has to be known. With classes, in 2.3.0 and the upcoming 2.5 release, there is a format for how classes are added as a callback. Fortunately, at least in 2.5 you don’t need to worry about the format. I’ll detail the format in a later post for those wanting to know in 2.3.x.

In WordPress 2.5 however, you only need to pass the same reference to the class and the method name. The way to get the reference, if you are removing the callback from another plugin’s class is to get the known global and use that reference.

If the plugin is known to cause problems with yours, then you should be able to get that information easily. It is easier if the offending plugin uses functions or static method calls as the original class reference variable is not needed.

Most of the hooks plugin authors will be removing will be WordPress internal ones, which don’t use classes. If this is the case, then the format is easier.

function myplugin_remove_offending_hook_after_test() {
    if( false !== ($priority = has_filter( 'pre_term_name', 'wp_filter_kses')) ) {
        remove_filter( 'pre_term_name', 'wp_filter_kses', $priority );
        // Hook another filter in its place.
    }
}

myplugin_remove_offending_hook_after_test();

When the second parameter is used, if the callback is found then the priority is returned. You can use this in the method above to remove the hook. As before, you must know the callback before hand.

The has_action() is used in the same way and as with add_filter() and add_action() it is always better to use the correct function for the hook you are referencing, even through they both use the same function.

January 12, 2008 Posted by | Writing Plugins Series | 2 Comments