PHP unit and output buffer

Hello guys,

currently i’am trying to practise refactoring, therefore i picked up an old project (from 2004 i gues) no classes, only functions. So the first thing iam trying to do is, to get result of the home.php and compare it with a string, hope to get a gues which things are executed with the code coverage report. But sadly php unit prints out the output of the include and the test is terminated.

so this i want to get

    <?php
namespace Logd\Core\Test;
class HomeTest extends \PHPUnit_Framework_TestCase
{
    public function testCanViewIndexPage(){
        ob_start();
        include __DIR__.'/../home.php';
        $actualOutput = ob_get_clean();
        $this->assertSame($actualOutput,$expectedOutput);
    }
}

the strange thing is, when i do following

namespace Logd\Core\Test;
class HomeTest extends \PHPUnit_Framework_TestCase
{
    public function testCanViewIndexPage(){
        ob_start();
        //include __DIR__.'/../home.php';
        echo "test";
        $actualOutput = ob_get_clean();
        $this->assertSame($actualOutput,"test");
    }
}

no output is generated.

this is the home.php https://github.com/BlackScorp/logd2/blob/master/home.php as far as i could figure out the script use a global variable $output and fill it with functions, some functions use global to import the variable and at the end the $output is echoed out. i thought the output buffer would handle that but it seems that the script is able to ignore the output buffer, maybe someone has an idea?

Cheers

PS: phpunit version 5.2.8 and PHP version is 5.6

EDIT: just found in the script that there is an exit() call, which terminate the test process, and i cannot replace it with return since the return value of the method is not checked

1 Like

What you are trying to do isn’t really unit testing. It seems more like functional testing to me. For unit testing, one must test the units of code or the modules, the SRPs, within the application. Unfortunately, the old page controller form of application architecture was never really built with unit testing in mind.

If you want to unit test, you need to break up the pages into clear objects and behaviors (classes and methods). Then test the objects for their proper behaviors. That is unit testing. Well, that is unit testing as I understand it. Maybe someone else has a different view? :smile:

Scott

Well i didnt really wanted to unit test in first place, my idea was, to create an automated test which compares the HTML Output and then i could fiddle around on functions which were marked by code coverage, and run the tests each time i change something to ensure that i did not break anything.

Sadly… HTML Comparison is not working well, because of whitespaces, i gues i have to try another way.

You could take a look at Selenium.

Scott

as far as i know, Selenium cannot generate code coverage, so i don’t even know when i change a part of a code that this part has something to do with the page iam testing. the code is not mine, it is an old open source project which is not maintained anymore because of the age.

Is the project you are working programmed in an object oriented fashion?

Scott

no, only functions and global variables, it contains even things like this

if(!function_exists("file_get_contents")) {
     function file_get_contents($file) {
          return join("", file($file));
     }
}

i like challanges :smiley:

you know, its easy to start a greenfield project, but it is hard to refactor existing one, in all the years as php developer, mostly i worked on existing projects, and if you do not know the code, you may make many mistakes, which might have some consequences, so i’d like to practise this in the freetime to apply this at work later on. i knew it would be hard, but i never expected that this will be that hard if the project has only functions

I’d say, you’re going to have to determine the modules or “units” within the code and find a way to separate them to test them. You don’t test a whole page of functions, you need to test the functions, as units. OOP makes this easier, because of SRP. You test the object for its proper behavior, both for good and bad input. If you can see a page like that, ok. But, I would still venture to say, that is functional testing and not unit testing. So, in end effect, you are basically using the wrong tool for the job and that’s why it is so difficult.

Edit: testing the whole page could also be considered integration testing too. Still, unit testing and the tools for it aren’t built for the tests, which you are trying to carrying out.

Scott

i do integration tests with PHPUnit as well, its just a framework with assert methods. i dont really need to use phpspec or behat or selenium, the kind of tests differ on the context you test, not the tools. as i told, the reason why i use phpunit is that phpunit generates a code coverage, which actually shows you that the code executed a part of a file during the test, this way you know exactly where you can start to refactor and which methods you can ignore. (well this is the theory :smiley: the reallity is a bid harder )

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.