Version 1 by Matthew Weier O'Phinney
on Oct 15, 2009 06:51.

compared with
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (1)

View Page History

Bug hunting should be fun, so pick components and issues you're interested in. Ask questions on IRC if you don't understand how something works.

h2. Tips for more effective bug hunting
In general, the following steps will help you be a more effective bug hunter, and also assure that your patches will be accepted and applied in a timely manner.

h3. Start with the easy stuff
Not feeling confident with unit testing? Don't have a lot of time to help? Consider helping with documentation issues! There are many documentation issues posted that are often as simple as correcting typos or fixing examples. For a list, visit the [docs filter in the issue tracker|].

When updating documentation, please create patches following the rules outlined below under the heading "Create a patch."

h3. Reproduce the issue
Good reporters will provide all the information necessary to reproduce the issue they're reporting. This will include the _minimum code necessary that reproduces_ the problem, what results they were _expecting_, and what _actual results_ they observe.

Your job is to:
* Determine if you have all the above information, or if the information is implied in the report. If not, post a comment, and ask the reporter for the information you need. If the reporter does not provide the information in a timely manner (give it a week or two), we can close the issue as "Incomplete" or "Can not reproduce."
* Capture the reproduce case as a unit test. As an example, if somebody posted the following:
$element = new Zend_Form_Element_Text('foo', array(
'label' => 'Foo',
'decorators' => array(
array('Label', array('tag' => null))),

echo $element->render($view);

// Expected: <label name="foo">Foo</label><input type="text" name="foo" id="foo">
// Actual: <dt><label name="foo"></dt>Foo</label><input type="text" name="foo" id="foo">
You would then capture it in a unit test as follows:
* @group ZF-XXXX
public function testSettingNullTagOptionOnLabelDecoratorShouldOmitSurroundingHtmlTag()
$element = new Zend_Form_Element_Text('foo', array(
'label' => 'Foo',
'decorators' => array(
array('Label', array('tag' => null))),

$html = $element->render(new Zend_View());
$this->assertContains('<label', $html);
$this->assertNotContains('<dt>', $html);
$this->assertNotContains('</dt>', $html);
This test method would be placed in the appropriate test class. There are several things to note about this example. First, the docblock contains an "@group" annotation referencing the issue; this is so others looking through the tests know what issue this method is related to, and also allows us to run unit tests specific to the issue (via the syntax 'phpunit --group ZF-XXXX'). Second, the method name is descriptive of the behavior we're testing; it's self-documenting. Third, note the usage of assertions: learn the [variety of assertions available in PHPUnit|], and choose the assertions pertinent to the behavior you're testing.
* Run the unit tests to verify the failure. If the tests still pass, revisit your reproduce case to see if it accurately represents the report. If so, we can likely close the issue as "Can not reproduce." Regardless, you should still create a patch with the test, to show that the behavior is correct.

h3. Fix the code
Once you have a reproduce case and it's captured in a test, you can finally start fixing the code. Keep in mind the following guidelines:
* *Run your tests.* After you change the code, run your tests to see if they now pass. Also, run the AllTests suite for the component, to ensure you didn't introduce breakage elsewhere.
* *Don't change method signatures.* If you change a method signature, you're potentially creating a backwards compatibility break. The only changes that are allowed:
** Additional, _optional_ parameters
** That's it. Really.
* *Don't change return values.* Consumers of the code operate on the return values, so changes to those will, again, introduce backwards compatibility breaks.
* New methods are allowed, but try to minimize the number of them and how the rest of the class interacts with it. In particular, be cognizant of any interfaces the class is implementing, or having consuming classes utilize the new method.

h3. Create a patch
Creating a patch is fairly easy, once you know what to do.

We recommend _always_ creating patches from the root of your ZF install (i.e., the directory containing "library," "tests," and "documentation"); this makes it trivially easy to apply the patches, and also helps ensure that you're creating patches that include both tests and code.

Here are some typical methods for creating patches from the CLI:
* Using svn: svn diff > ../<issueid>.patch
* Using git: git diff -p --raw > ../<issueid>.patch
* Using an untouched source and modified source directory: diff -ur original/ changed/ > <issueid>.patch

h3. Attach the patch or commit it
Attach the patch to the issue, and then assign it to the component lead. Alternately, if you have commit rights, you can skip creating the patch, and commit it directly. If the functionality affects the current minor release, be sure to merge your commit to the appropriate release branch.

h3. Lather, rinse, repeat
Keep at it! The more issues we close, the better the framework will be!