HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

BDD tests in PHPUnit

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
bddphpunittests

Problem

No one in my team knows how to write BDD tests, so I started writing some and it's quite working well. I think the time has come to improve the code quality.

This contains a lot of duplicated code and unused features:

```
given('For a mValue (mixedValue) and we want to validate if it is an integer')
->when('sJobId is a positive integer', 123)
->then('return of positive integer should be', 'TRUE')
->when('sJobId is a negative integer', -123)
->then('return of a negative integer should be', 'FALSE')
->when('sJobId is a float', 1.23)
->then('return of a float should be', 'FALSE')
->when('sJobId is a string containing only digits', '123')
->then('return of a string (containing only digits) should be', 'TRUE')
->when('sJobId is a string containing not only digits', '123abc-?')
->then('return of a string (containing not only digits) should be', 'TRUE');
}

public function runGiven(&$world, $action, $arguments) {
switch($action) {
case 'For a mValue (mixedValue) and we want to validate if it is an integer': {
$world['helper'] = new cHelperValidation();
}
break;

default: {
return $this->notImplemented($action);
}
}
}

public function runWhen(&$world, $action, $arguments) {
switch($action) {
case 'sJobId is a positive integer': {}
case 'sJobId is a negative integer': {}
case 'sJobId is a float': {}
case 'sJobId is a string containing only digits': {}
case 'sJobId is a string containing not only digits': {}
break;

default: {
return $this->notImplemented($action);
}
}
}

public function runThen(&$world, $action, $arguments) {
switch($action) {
case 'return of positive integer shou

Solution

Your switch statements will run through until they find a break statement. Having the braces {} only defines a block of code and has no effect on breaking out of the case.

switch (1)
{
case 1: {
   echo 'One';
}
case 2: {
   echo 'Two';
}
default: {
   echo 'Also default';
      }
}


The one above prints out "OneTwoAlso default" whereas the following prints out "One".

switch (1)
{
case 1:
   echo 'One';
   break;
case 2:
   echo 'Two';
   break;
default:
   echo 'Also default';
}


I think your testing would be cleaner if you didn't use then and when methods. Normally I create an array of test data and expected results and loop over them. As you are writing the test for the isId method I would have something like this:

public function test_isID()
{
   $object = new Object_That_You_Are_Testing();

   $tests = array(
      array('Data'            => 123,
            'Expected_Result' => true,
            'Test_Name'       => 'Positive Integer'),
      array('Data'            => -123,
            'Expected_Result' => false,
            'Test_Name'       => 'Negative Integer'));

   foreach ($tests as $test)
   {
      $this->assertEquals($test['Expected_Result'],
                          $object->isID($test['Data']),
                          $test['Test_Name'] . ' Failed');
   }
}


You could do more clever things than this. Also a test will not always be so simple. Normally I find that I have mocked objects and am ensuring that they get called appropriately.

Code Snippets

switch (1)
{
case 1: {
   echo 'One';
}
case 2: {
   echo 'Two';
}
default: {
   echo 'Also default';
      }
}
switch (1)
{
case 1:
   echo 'One';
   break;
case 2:
   echo 'Two';
   break;
default:
   echo 'Also default';
}
public function test_isID()
{
   $object = new Object_That_You_Are_Testing();

   $tests = array(
      array('Data'            => 123,
            'Expected_Result' => true,
            'Test_Name'       => 'Positive Integer'),
      array('Data'            => -123,
            'Expected_Result' => false,
            'Test_Name'       => 'Negative Integer'));

   foreach ($tests as $test)
   {
      $this->assertEquals($test['Expected_Result'],
                          $object->isID($test['Data']),
                          $test['Test_Name'] . ' Failed');
   }
}

Context

StackExchange Code Review Q#6606, answer score: 3

Revisions (0)

No revisions yet.