Monday, October 3, 2011

Unit Testing in PHP

I'm currently working with PHP. I found this bit of code in one of the unit testing tools for PHP. It's not terrible, but it's not great either. To me, it represents one of the tipping points for the value proposition of unit testing in the first place: Having solid unit-test coverage of code should also mean that we can take an extra few minutes to fix it.

public function appendValue($value)
{
   if (is_null($value))
   {
      $this->append('null');
   }
   elseif (is_string($value))
   {
      $this->_toPhpSyntax($value);
   }
   elseif (is_float($value))
   {
      $this->append('<');
      $this->append($value);
      $this->append('F>');
   }
   elseif (is_bool($value))
   {
      $this->append('<');       
      $this->append($value ? 'true' : 'false');
      $this->append('>');
   }
   elseif (is_array($value) || $value instanceof Iterator || $value instanceof IteratorAggregate)
   {
      $this->appendValueList('[', ', ', ']', $value);
   }
   elseif (is_object($value) && !method_exists($value, '__toString'))
   {
      $this->append('<');       
      $this->append(get_class($value));
      $this->append('>');
   }
   else
   {
      $this->append('<');       
      $this->append($value);
      $this->append('>');
   }
   return $this;
}

4 comments:

  1. So, what of this code? First and foremost, I want to be able to read code *quickly.* The simple duplication rampant in this function makes that difficult. Introducing a "wrap" function would resolve that problem.

    Also making reading difficult is the use of complex conditionals later, something a simple extraction would resolve.

    We could also consider a larger change, to introduce a polymorphic hierarchy to support the conversion to printable representation.

    Fixing the first two small problems would be extremely trivial, and would quickly take this method to something rapidly digestible. We should always take the time.

    A quick first pass (untested) might be:

    public function appendValue($value)
    {
    if (is_null($value))
    $this->append('null');
    elseif (is_string($value))
    $this->_toPhpSyntax($value);
    elseif (is_float($value))
    $this->append(wrap($value.'F'));
    elseif (is_bool($value))
    $this->append(wrap($value ? 'true' : 'false'));
    elseif ($this->is_iterable($value))
    $this->append(to_list($value));
    elseif (is_not_stringable($value))
    $this->append(wrap(get_class($value)));
    else
    $this->append(wrap($value));
    return $this;
    }

    ReplyDelete
  2. how does one format code in comments on this blog?

    ReplyDelete
  3. I'm not sure we can. Blogger is a little rough around those edges.

    ReplyDelete
  4. well that sucks. I would suggest to maybe use a different blog engine that's more hospitable to code. I think WordPress has plugins, and right off the bat it seems to work better:
    http://langrsoft.com/jeff/2011/09/tdd-kata-roman-number-converter/

    ReplyDelete