Akelos Framework v1 forum archive. This forum is no longer maintained. To report bugs please visit https://github.com/akelos/akelos/issues
    • CommentAuthortom
     
    Hi there,

    is there any documentation on how to test controller functionality? Is this feature implemented yet?

    Cheers,
    Tom
    •  
      CommentAuthorbermi
     

    Hi Tom, and welcome to the forum!

    Functional tests are implemented in a far from ideal way.

    You need to make your test/fixtures/public folder visible on your web server.

    Then in your config/config.php you'll need to tell Akelos where is the testing URL like:

    defined('AK_TESTING_URL') ? null : define('AK_TESTING_URL', 'http://localhost/framework_tests/test/fixtures/public');
    

    You will need to create a fake controller at

    test/fixtures/app/controllers/post_controller.php
    

    which just needs to include the original controller (like model fixtures).

    Then for testing Akelos uses simple test WebTestCase like

    <?php
    
    require_once(dirname(__FILE__).'/../../../fixtures/config/config.php');
    
    class PostControllerTest extends AkWebTestCase 
    {
    
        function test_should_get_index()
        {
            $this->setMaximumRedirects(0);
            $this->get(AK_TESTING_URL.'/post/');
            $this->assertResponse(200);
            $this->assertTextMatch('Hello from Index');
        }
    }
    
    ak_test('PostControllerTest');
    
    ?>
    

    Hope you find it useful.

    • CommentAuthortom
     
    Ok, thanks!

    ...at least there IS a way :)
    • CommentAuthoralake
     
    I'm struggling with trying to understand your response to Tom, Bermi. I think you think that I understand some things that you do, but I'm not so sure. Please help me by confirming or correcting what I've done.

    First, you said: "You need to make your test/fixtures/public folder visible on your web server." I tried to do this by going to my docroot directory and creating the following directory structure: "framework_tests/test/fixtures/". I then did this:
    "ln -s /home/alan/develop/php/vuokraten/test/fixtures/public/ framework_tests/test/fixtures/public". I chose the names in order that the next instruction might be valid.

    "Then in your config/config.php you'll need to tell Akelos where the testing URL is:
    defined('AK_TESTING_URL') ? null : define('AK_TESTING_URL', 'http://localhost/framework_tests/test/fixtures/public');"
    This seems quite clear, although I did change your English a bit as well as to point to my URL: http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public.

    "You will need to create a fake controller at test/fixtures/app/controllers/post_controller.php which just needs to include the original controller (like model fixtures)." I interpreted this to mean that the contents of the php file should be

    <?php
    require_once(AK_BASE_DIR.DS.'app'.DS.'controllers'.DS.substr(strrchr(__FILE__, DS), 1));
    ?>

    Finally, you gave this instruction: "Then for testing Akelos uses simple test WebTestCase like..."
    Of course, I had to modify this file a bit to access http://alan.infolake.com/vuokraten/infolake.

    <?php

    require_once(dirname(__FILE__).'/../../../fixtures/config/config.php');

    class InfolakeControllerTest extends AkWebTestCase
    {

    function test_should_get_index()
    {
    $this->setMaximumRedirects(0);
    $this->get(AK_TESTING_URL.'/../../');
    $this->assertResponse(200);
    $this->assertTextMatch('InfolakeController:index()');
    }
    }

    ak_test('InfolakeControllerTest');

    ?>


    Here's where I think that I'm lost, but I'm going to guess. Rails reserves the term "unit test" for models and the term "functional test" for controllers. Because the project contains the directory structure "test/unit/app/models", it would be redundant to have "unit" and "models" in the same directory structure if we were going to follow the Rails pattern. The Wiki entry "Introducing AkUnitTest indicates that a test may be written anywhere within the test directory. I put my test script in "test/unit/app/controllers/infolake.php.

    As for your code, you start out by requiring config.php. At first, I thought that this was config/config.php, but closer examination shows that it is test/fixtures/config/config.php. I think that the location of my test script will make the require line work OK. It should be noted that putting one's script into another structure will require that this line be recoded.

    The class statement is "class PostControllerTest extends AkWebTestCase", but the AkUnitTest Wiki says that it should be coded "class PostControllerTestCase extends AkWebTestCase" in order for script/test to find it. In the case of my test would be "class InfolakeControllerTestCase extends AkWebTestCase". The statement to call the test, then should be "./script/test test/unit/app/controllers/infolake.php." In order for this test to succeed, though, I guess that I should have the string 'InfolakeController:index()' assigned to a variable in app/controllers/infolake_controller.php.

    I can easily see that AK_TESTING_URL resolved to http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public, just as specified. But that is linked to test/fixtures/public, which is empty. Adding "/../../" to the url enables me to avoid a 404, but I still fail on the assertTextMatch. The page that it is searching is a page made from test/fixtures/public, so it is of no value. I still can't see how to make the "get" point to app/controllers/infolake.php (or to another controller, once I get more than one).

    Your help with this great product is appreciated.
    • CommentAuthorKaste
     

    thats a long post, so I can't follow everything you wrote.

    But that is linked to test/fixtures/public, which is empty.

    there should be

    .htaccess
    index.php
    

    in /fixtures/public.

    So in the end

    $this->get(AK_TESTING_URL);
    $this->assertResponse(200);
    $this->assertTextMatch('InfolakeController:index()');
    

    fetches a page/url and the assertTextMatch(...) matches against the returned view/response.

    • CommentAuthoralake
     

    I need some help "adjusting" the first statement above: $this->get(AK_TESTING_URL); I've tried several things, but nothing seems to get me where I want, which is app/controllers/infolake_controller.php

    I understand that I should put return "InfolakeController:index()"; in the index function of app/controllers/infolake_controller.php to get a true from the assertTextMatch above. Please correct me if I'm wrong.

    • CommentAuthorKaste
     

    but

    return InfolakeController:index();
    

    wouldn't be valid php.

    I meant against the view or response, so say you have a template with <h1>Hello</h1> you then fetch the page and assert

    assertTextMatch('Hello');
    

    can you point your browser to test/fixtures/public in a way?

    • CommentAuthoralake
     

    Thanks, Kaste.

    The first statement was supposed to have quotes around the "InfolakeController:index()" string. From what you say, I guess that I need to pass diagnostic strings to a view and then assertTextMatch against those strings. Do you (or anyone) know how to pass strings from a controller to a view?

    I have a link from my docroot directory to test/fixtures/public. What I don't know is how to make something in text/fixtures/public point to the controller that I want to test.

    • CommentAuthorKaste
     

    Do you (or anyone) know how to pass strings from a controller to a view?

    Look here.

    What I don't know is how to make something in text/fixtures/public point to the controller that I want to test.

    Actually what do you get when you point your browser to this location? (The index.php in there should do the 'point'.)

    • CommentAuthoralake
     

    I'm still trying to get my mind around MVC. You have helped. When I finally get this down, I'll include how it's done in detail in Agile Web Development in Akelos.

    I had thought that I was supposed to run tests from a command line.

    $ ./script/test test/unit/app/controllers/infolake_controller.php

    InfolakeControllerTest http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public/infolake/ 1) Expecting response in [200] got [500] at [/home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php line 13] in test_should_get_index 2) Pattern [/^InfolakeController:index()$/] not detected in [String: ] at [/home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php line 14] in test_should_get_index FAILURES!!! Test cases run: 1/1, Passes: 0, Failures: 2, Exceptions: 0

    /home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php

    If I think in MVP, I can see where, if I specify that I run test/unit... that an introspection of that line would point me to app/controllers/infolake_controller.php. Because I got a 500, I'm going to look at the configuration of my virtual server again.

    You used the phrase "point your browser", so I pointed my browser at the entry in my docroot: http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public/. This time I got a 404.

    I figured that what might be needed would be to point to the test in my development area (not in the docroot). This hardly makes sense, but it was worth a try. It yielded: Fatal error: Could not find the file /app/controllers/test_controller.php for the controller TestController in /home/alan/develop/Software/akelos/lib/AkRequest.php on line 759

    Anyhow, I'm going to keep fooling around with this and maybe I'll be able to figure it out. If you see something, please let me know.

    • CommentAuthorKaste
     

    I just try to guide you. After all, when everything works, you can run your tests from the command line. I'll do.

    two things.

    [1.] I'm not sure you know what the AkWebTestCase is all about.

    class DummyWebtestcase extends AkWebTestCase 
    {
        function testShouldGetTheGoogle()
        {
            $this->get("http://www.google.com");
            $this->assertText("Google");
        }
    }
    

    run this from the command-line. it should get the google-page and search for the string "Google".

    so to speak, the ->get-method is a HTTP-Get.

    [2.] So "fixtures/public" needs to be public, exposed, reachable by a browser. To test this, I thought, point your browser to this dir.

    You can - I did it once - configure a seperate vhost just for this purpose. then practically http://my-akelos-test/ could point/link to this dir and you should see ... yeah what do we see?

    you could just test this apache-thing by putting a index.html into this dir.

    ok, next thing: in fact, in this dir there should be an index.php which dispatches the Request and starts the whole Akelos Framework. But this would be the next thing. In this step we could see if the dispatcher finds the right controller etc. This is mainly a Router-thing inside Akelos.

    the last step would be configure AK_URL or other constants.

    • CommentAuthoralake
     

    [1] I put your code into /home/alan/develop/php/vuokraten/test/unit/app/controllers/dummy_web.php. I added the <?php and ?> at the beginning and end. It ran with the command:

    $ ./script/test test/unit/app/controllers/dummy_web.php
    

    but the output was followed by a bunch of session related errors, which I suppose was OK. I reran

    $ ./script/test test/unit/app/controllers/infolake_controller.php, but still got a 500 error.
    

    [2] I created a name virtual host with the following code:

    <VirtualHost akelos.lakeinfoworks.com>
      ServerName akelos.lakeinfoworks.com
      DirectoryIndex index.html index.php index.htm index.shtml 
      ServerAdmin alan.lake@lakeinfoworks.com
      DocumentRoot /home/alan/develop/php/vuokraten/test/fixtures/public
      <Directory "/home/alan/develop/php/vuokraten/test/fixtures/public">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
      </Directory>
    </VirtualHost>
    
    /home/alan/develop/php/vuokraten/test/fixtures/public already contains an index.php, which I've attached.  As you can see, I added an echo statement to make certain that I got there.
    

    I can execute this index.php either by the new virtual server defined above or through the link that I had earlier. In either case, the browser displays

    test/fixtures/public/index.php
    404 Page not found
    

    As I understand it, the way to resolve this is through config/routes.php. Mine is still in its original state, which contains the line

    $Map->connect('/', array('controller' => 'page', 'action' => 'index'));
    

    I notice that log/testing.log contains this:

    PARAMS{
        - controller: page
        - action: index
        - AK_c2659f: 1n6rtbvtl7t2rmcb95q9jlat34 
        }
    

    As I read this, I think to look at the file called app/controllers/page_controller.php, in the index method. Is this not correct? I am ignoring the -AK_ line, as I don't understand it. It seems to me that, if control were going to the PageController class, I wouldn't be getting the 404 message.

    I edited app/controllers/page_controller.php, adding an echo statement to the index method. A test does not show a display from the echo statement, so the test/fixtures/public/index.php must be pointing somewhere other than to the PageController. It doesn't seem reasonable to me that every test would require the modification of either the routes.php or page_controller.php.

    I thought to experiment with the last step, must to see what I could find. In the XREF, I saw the advice to run Ak::get_constants();, but no indication how to do it. I opened test/fixtures/public/index.php and added this line:

    echo Ak::get_constants();
    

    I got no output, so I modified it:

    $result = Ak::get_constants();
    echo $result;
    

    I still get no output. I don't know what to do now...

    • CommentAuthoralake
     

    I was not allowed to send a php file as an attachment, so here's the code:

    echo "test/fixtures/public/index.php<br />";
    $result = Ak::get_constants();
    echo $result;
    
    include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
    
    require_once(AK_LIB_DIR.DS.'AkDispatcher.php');
    $Dispatcher =& new AkDispatcher();
    $Dispatcher->dispatch();
    
    • CommentAuthormatiasf
     
    Alake, I'm new to Akelos, so probably you should wait for the proper answer from Kaste.

    In the meantime...

    I will assume a couple of things:

    1. You already have a link called "vuokraten" pointing to your /home/alan/develop/php/vuokraten directory
    2. You don't have a link to "test/fixtures/public" (it seems you created one)
    3. Everything else in Apache is configured correctly: mod_rewrite, allowoverride's, etc.

    Try this:

    a. On your main config.php file (~/develop/php/vuokraten/config/config.php) set AK_TESTING_URL to 'http://alan.lakeinfoworks.com/vuokraten/test/fixtures/public'
    b. On your vuokraten/test/fixtures/public/.htaccess file, uncomment the RewriteBase line setting it to:

    RewriteBase /vuokraten/test/fixtures/public

    c. The fake controllers you want to use for testing (I assume your InfoLake controller is one of them) should be placed in your vuokraten/test/fixtures/app/controllers directory, not on vuokraten/app/controllers.

    I think that's all, but probably I'm missing something. Run your tests again with the configuration above, and if they still do not work, please try Kaste suggestion about pointing your browser to vuokraten/test/fixtures/public again, this time with this configuration and paste your results here, please.

    HTH,
    Matías.
    • CommentAuthoralake
     
    Matias, I do appreciate your help.
    a. This was already set.
    b. I did this
    c. I don't think I understand the fake controllers. In vuokraten/test/fixtures/app/controllers/infolake_controller.php, I have this:
    <?php
    require_once(dirname(__FILE__).'/../../../fixtures/config/config.php');

    class InfolakeControllerTest extends AkWebTestCase
    {

    function test_should_get_index()
    {
    $this->setMaximumRedirects(0);
    $url = AK_TESTING_URL.'';
    echo $url."\n";
    $this->get($url);
    $this->assertResponse(200);
    $this->assertTextMatch('InfolakeController:index()');
    }
    }

    ak_test('InfolakeControllerTest');
    ?>
    vuokraten/app/controllers/infolake_controller.php is my real controller. I think that I want to reach from the "fake" controller to the "real" one, as I want to see what is happening there. Within the real controller, I have string messages assigned to an array. This array is supposed to be displayed in views. The result of a command line test is:
    InfolakeControllerTest
    http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public
    1) Expecting response in [200] got [301] at [/home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php line 13]
    in test_should_get_index
    2) Pattern [/^InfolakeController\:index\(\)$/] not detected in [String: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>301 Moved Permanently</title>
    </head><body>
    <h1>Moved Permanently</h1>
    <p>The document has moved <a href="http://alan.lakeinfowor...] at [/home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php line 14]
    in test_should_get_index
    FAILURES!!!
    Test cases run: 1/1, Passes: 0, Failures: 2, Exceptions: 0

    vuokraten/test/fixtures/public/index.php contains this code:
    <?php

    echo "test/fixtures/public/index.php<br />";
    $result = Ak::get_constants();
    echo $result;

    include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');

    require_once(AK_LIB_DIR.DS.'AkDispatcher.php');
    $Dispatcher =& new AkDispatcher();
    $Dispatcher->dispatch();

    ?>
    Lines 3-5 are what I added. The result was the first echo. That is all.
    • CommentAuthormatiasf
     
    Sorry, I think I misunderstood you and now I'm not sure exactly what are you trying to test.

    Are you trying to test that you get the right controller/action to be called when you point to the root of your Akelos application?
    • CommentAuthoralake
     

    I know that I can get to the controller originally with the URL http://server/project/controller. The default action will be the index function. The controller is to handle the importation of a CSV file. Because I have a batch task to perform, the program must route itself back to the controller repeatedly. Therefore, this index method must do different things depending upon what has happened. This controller must also allow interactive input, just as the framework is designed for.

    The input method will read a record, then send it off to a standard verify routine, just as though it was entered interactively. If there are errors, the record will go to the edit method, which will be standard except that it will permit the user to skip the record if it can't be fixed. After either skipping or saving each record, action will return to the import method until EOF. The select method is where the user supplies the name of the file to be imported. It will have a link that will connect back to the listing method, from where the user can enter data interactively.

    This index method is in the controller.

    function index()
    {
      $this->Introspekt[] = 'InfolakeController:index()';
    

    // $this->renderAction('listing'); This line is the original code for the function. if(exist($this->csv_file)){ if(exist($this->csv_file_is_open)){ $this->renderAction('import') // At EOF, the variable called $this->csv_file will be deleted, // but $this->csv_sought will remain true }else{ $this->renderAction('open'); } $this->renderAction('index'); }elseif(exist($this->csv_sought)){ $this->renderAction('listing'); }else{ $this->renderAction('select'); $this->csv_sought = true; $this->renderAction('index'); } }

    function import()
    {
      $this->Introspekt[] = 'InfolakeController:import()';
    }
    
    function open()
    {
      $this->Introspekt[] = 'InfolakeController:open()';
    }
    
    function select()
    {
      $this->Introspekt[] = 'InfolakeController:select()';
    }
    

    In the app/view, I have files import.php, open.php and select.php. Right now, each of them just echoes the contents of Introspekt. What I want to test is that this index.php works as intended. I want to add code a bit at a time as I confirm that what I have works as intended.

    As I see it, the "fake" controller should cause the "real" controller to be executed, so that I can see what is going on -- a trace, if you will.

    BTW, I don't know where in the world the rest of you all are. I'm north of Helsinki, Finland. I'm between 7 and 10 hours earlier than folks I know in my native U.S.A. :-)

    • CommentAuthoralake
     
    I apologize for not knowing how to use markdown. I went to a markdown site but using what it said didn't help. I also tried to use the markdown for the wiki. I hate to lose the indentation...

    function index()
    {
    $this->Introspekt[] = 'InfolakeController:index()';
    // $this->renderAction('listing'); This line is the original code for the function.
    if(exist($this->csv_file)){
    if(exist($this->csv_file_is_open)){
    $this->renderAction('import')
    // At EOF, the variable called $this->csv_file will be deleted,
    // but $this->csv_sought will remain true
    }else{
    $this->renderAction('open');
    }
    $this->renderAction('index');
    }elseif(exist($this->csv_sought)){
    $this->renderAction('listing');
    }else{
    $this->renderAction('select');
    $this->csv_sought = true;
    $this->renderAction('index');
    }
    }
    • CommentAuthorKaste
     

    In vuokraten/test/fixtures/app/controllers/infolake_controller.php, I have this: [...]

    in the fixtures-dir, you can't have tests. fixtures are test-controllers or are pointing to your real controllers, so they import/include them.

    I'll put the tests in test/unit/app.

    [...]

    It ran with the command: $ ./script/test test/unit/app/controllers/dummy_web.php

    but the output was followed by a bunch of session related errors, which I suppose was OK.

    why are thrown errors ok?

    In either case, the browser displays test/fixtures/public/index.php 404 Page not found

    As I understand it, the way to resolve this is through config/routes.php.

    Is this a Apache-404 or an Akelos-404? config_routes only applies when the Akelos Framework actually dispatches the request. On a real 404 or 5xx Apache-error (see your Apache log) we would have a configuration-problem.

    $result = Ak::get_constants();

    you call this even before including the framework. So from my understanding you really should be getting an error.


    I might be stupid and I am stuck but

    1. The Google-example should work
    2. Put an index.html with <h1>HelloWorld</h1> into fixtures/public.
    3. Adjust the 'google test', so it fetches the Testing-Url and matches HelloWorld

    Then you would have a valid WebTestCase. A very simple one without controllers and fancy stuff. But a not-failing one.

    Right now, I simply don't hear a clear-case for these 3 prerequisites.

    • CommentAuthorThijs
     

    Alake, here's the markdown syntax (I linked to the part about code blocks)

    • CommentAuthoralake
     

    Thrown errors are not OK. In this case, I got a normal result followed by the errors. I was unable to know what threw the error, but because I could see the result I wanted, I said "OK."

    The 404 comes from (if I'm not mistaken) akelos/lib/AkRequest.php, at either line 763 or line 774.

    I think that my basic problem is that I'm moving around in the dark. When I think that I understand where the flow of the Akelos framework is supposed to take me, I take a turn in that direction, but I bump my nose against a wall that I didn't realize was present. I need to learn the basic principles. Things have been written that give step by step instructions, but without knowing what is behind them, I can't make a needed adjustment when things don't work. Here is an example:

    1. The Google-example should work. I tried to do what I had done earlier, but I must have changed something. I don't remember what it might have been, but because I don't understand the principle behind it, I have to guess how I might get it to work.

    I decided to go back to the Wiki, Introducing AkUnitTest. I created test/hello_test.php and ran it from /home/alan/develop/php/vuokraten with:

    .script/test  hello_test.php
    

    I got a valid result, but with a PHP error. I checked /etc/php.ini to make certain that session.savepath indeed points to /var/lib/php/session. The files in it are all owned by apache:apache with an rw permission for the user. I restarted httpd, but this didn't clear the error. (continued after the output)

    HelloTestCase
    OK
    Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
    /home/alan/develop/php/vuokraten/test/hello_test.php
    PHP Warning:  Unknown: open(/var/lib/php/session/sess_14m93icat7434o2tkpe3mntpn4, O_RDWR) failed: Permission denied (13) in Unknown on line 0
    
    Warning: Unknown: open(/var/lib/php/session/sess_14m93icat7434o2tkpe3mntpn4, O_RDWR) failed: Permission denied (13) in Unknown on line 0
    PHP Warning:  Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/session) in Unknown on line 0
    
    Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/session) in Unknown on line 0
    

    I ran ./script/test test/unit/app/controllers/dummy_web.php and got the following result, a listing of the file rather than an execution of it.

        class DummyWebtestcase extends AkWebTestCase 
        {
            function testShouldGetTheGoogle()
            {
                $this->get("http://www.google.com");
                $this->assertText("Google");
            }
        }
        /home/alan/develop/php/vuokraten/test/unit/app/controllers/dummy_web.php
    

    I think I'll just go scratch my head for a few hours. I'm bumfoozled.

    • CommentAuthoralake
     

    I've researched the PHP error by googling "Failed to write session data". Many users with this problem are using Windows. I'm using Linux. It seems to be a PHP error that is worked around in the application code in one way or another. One possible workaround was to use session_destroy(); before creating a session. I wouldn't know where in the Akelos code to try this. At any rate, this doesn't seem to be anything that I can fix.

    I might also note that I started a new project, the booklink tutorial. I stopped before creating any controllers, but added the "Hello" test. This, too, gives the PHP error.

    • CommentAuthormatiasf
     

    I got a valid result, but with a PHP error. I checked /etc/php.ini to make certain that session.savepath indeed points to /var/lib/php/session.

    Ok, this has nothing to do with functional tests. Please double-check that your editing the right php.ini, the session.savepath contents, if the directory exists, if it has the right permissions, etc.

    I ran ./script/test test/unit/app/controllers/dummy_web.php and got the following result, a listing of the file rather than an execution of it.

    Maybe you forgot to enclose your test between php tags?

    Regards, Matías.

    • CommentAuthoralake
     

    I've got to tell you folks. I so appreciate the fact that you're hanging in there with me! One of the problems that I had with Rails was the large number of posts (not just mine) on their forum that were not responded to.

    PHP configuration double checked. None of these changed from the time before I got the error messages until I started getting them. Based on what I've read on the web, a workaround must come from within the application. The workaround appears to be different depending upon one's platform.

    I'll keep working on it. Is the session code in Akelos in just one file, class, etc.?

    Second point. &lt;stupid expression>&lt;blush>&lt;?php echo "What can I say?"; ?>&lt;/blush>&lt;/stupid expression>

    It, too, gives a valid test, but with the PHP error: $ ./script/test unit/app/controllers/dummy_web.php DummyWebtestcase OK Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0 /home/alan/develop/php/vuokraten/test/unit/app/controllers/dummy_web.php PHP Warning:...

    • CommentAuthoralake
     

    I'm going to start a new thread with the PHP bug, because, although the bug is in PHP, the workarounds are in the application, in this case Akelos.

    Back to the test case. It seems that we have a valid test with test_hello.php and also with dummy_web.php (find Google).

    In the Wiki entry for unit tests, the instructions for what to do have yet to be written. My test infolake_controller looks like this:

    <?php
    require_once(dirname(__FILE__).'/../../../fixtures/config/config.php');
    
    class InfolakeControllerTest extends AkWebTestCase 
    {
    
        function test_should_get_index()
        {
            $this->setMaximumRedirects(0);
            $this->get(AK_TESTING_URL);
            $this->assertResponse(200);
    //        $this->assertTextMatch('InfolakeController:index()');
        }
    }
    
    ak_test('InfolakeControllerTest');
    ?>
    

    It seems to me that one should not assertTextMatch until assertResponse is successful. Here's the test for that:

    [alan@erie vuokraten]$ ./script/test unit/app/controllers/infolake_controller.php
    InfolakeControllerTest
    1) Expecting response in [200] got [301] at 
    [/home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php line 11]
            in test_should_get_index
    FAILURES!!!
    Test cases run: 1/1, Passes: 0, Failures: 1, Exceptions: 0
    
    /home/alan/develop/php/vuokraten/test/unit/app/controllers/infolake_controller.php
    
    • CommentAuthormatiasf
     

    Ok, so we're back to your tests:

    It seems to me that one should not assertTextMatch until assertResponse is successful.

    Well, if the response assertion did not pass, it is unlikely that your assertTextMatch passes, that's ok.

    Now, to fix your test. What exactly do you see if you point your browser to the current contents of your AK_TESTING_URL?

    Regards, Matías.

    • CommentAuthoralake
     

    My AK_TESTING_URL is http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public. When I put that in my browser, I get a blank page except for the text: 404 Page not found.

    The only place that I see that message in that format in the Akelos source is in akelos/lib/AkRequest.php, in this code:

        if(@!include_once($controller_path)){
            if(AK_ENVIRONMENT == 'development'){
                trigger_error(Ak::t('Could not find the file /app/controllers/<i>%controller_file_name</i> for '.
                'the controller %controller_class_name',
                array('%controller_file_name'=> $controller_file_name,
                '%controller_class_name' => $controller_class_name)), E_USER_ERROR);
            }elseif(@include(AK_PUBLIC_DIR.DS.'404.php')){
                exit;
            }else{
                die('404 Page not found');
            }
        }
        if(!class_exists($controller_class_name)){
    
            if(AK_ENVIRONMENT == 'development'){
                trigger_error(Ak::t('Controller <i>%controller_name</i> does not exist',
                array('%controller_name' => $controller_class_name)), E_USER_ERROR);
            }elseif(@include(AK_PUBLIC_DIR.DS.'404.php')){
                exit;
            }else{
                die('404 Page not found');
            }
        }
    

    I checked the value of AK_ENVIRONMENT. It is "testing".

    What to do about it is still beyond me.

    • CommentAuthormatiasf
     
    If you want this http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public to work, I think you need to point your "framework_tests" symlink to the root folder of your akelos app. Probably it is pointing to your public or test/fixtures/public folder?

    Regards,
    Matías.
    • CommentAuthoralake
     

    In Bermi's response to Tom (at the beginning of this thread), he said You need to make your test/fixtures/public folder visible on your web server.That is what http://alan.lakeinfoworks.com/framework_tests/test/fixtures/public does.

    I have another symlink that goes to vuokraten/public. This starts my application, but not as a test.

    When I start my test, action goes to test/fixtures/public/index.php. This creates a $Dispatcher object from the Akelos/lib/AkDispatcher.php file. It then executes $Dispatcher->dispatch, which executes $this->Request =& AkRequest(); $this->Controller =& $this->Request->recognize();
    In that code is an attempt to include_once test/fixtures/app/controllers/page_controller.php. Because there is no such file and AK_ENVIRONMENT == "testing", the task executed die('404 Page not found'); on line 763.

    Who knows why it requires test/fixtures/app/controllers/page_controller.php? I thought that perhaps it should have been looking for test/fixtures/app/controllers/infolake_controller.php, because I do have one of those. I put an entry in config/routes.php, but that didn't help. Perhaps I need a test/fixtures/config/routes.php, but there isn't one in the Akelos tree.

    There is a test/fixtures/app/controllers/page_controller.php in the Akelos tree, so I made a copy of it in my project. The two methods in it are empty. Does anyone know what should Of course, I'll need a test/fixtures/app/views/ for the page methods. I copied index.tpl and setup.tpl over from akelos/test/fixtures/app/views/page. Index.tpl has only a placeholder in it. Setup.tpl has the same "Welcome Aboard" code that is in app/views/page/index.tpl. This doesn't seem to be appropriate because tests should be run from the command line.

    Can someone shed some light on this situation while I get some shut-eye? Thanx.

    • CommentAuthoralake
     

    One more thing. Because the index and setup methods in test/fixtures/app/controllers/page_controller.php were empty, I put echo statements in them so I could see if I got there. My last test did get me to the index method. But, of course, I still have a very understandable failure. What I need to learn is how to get to test app/controllers/infolake_controller.

    $ ./script/test test/app/controllers/infolake_controller.php
    InfolakeControllerTest
    1) Pattern [/^InfolakeController\:index\(\)$/] not detected in [String: test PageController:index
    
    Test::page::index] at [/home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php line 12]
        in test_should_get_index
    FAILURES!!!
    Test cases run: 1/1, Passes: 1, Failures: 1, Exceptions: 0
    
    /home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php
    
    • CommentAuthorKaste
     

    Now you're up and running.

    As I understand you placed a controller (the page_controller) and a dummy view (from our framework-tests) into the fixtures folders. So that when you invoke the index action on the page controller it renders the view which only consists of the string "Test::page::index".

    That isn't very informative but I hope we can work it out.

    AkRequest defaults (hard-wired via the constants AK_DEFAULT_CONTROLLER & AK_DEFAULT_ACTION) to a so-called page-controller if no set route matches. So I assume you're trying to

    ->get(AK_TESTING_URL)
    

    which points to fixtures/public. This is kinda the root of the public folder. Just like

    ->get('http://my.url.com/")
    

    would be.

    ->get(AK_TESTING_URL.'/infolake')
    

    should be delegated to the infolake_controller (and the index action).

    You could set up the config/routes.php so that '/' gets delegated to the infolake_controller

    $Map->connect('/', array('controller' => 'infolake', 'action' => 'index'));
    
    • CommentAuthoralake
     

    In order to get "up and running", I had to make a change to the simple web test case that Bermi first wrote for Tom:
    Because the test case is in test/app/controllers, we need to get to the test config.php by backing out only two directories, not three:require_once(dirname(__FILE__).'/../../fixtures/config/config.php'); However,$this->get(AK_TESTING_URL.'/infolake/');doesn't get me what I want. I got

    $ ./script/test test/app/controllers/infolake_controller.php
    InfolakeControllerTest
    1) Expecting response in [200] got [500] at 
    [/home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php line 11]
        in test_should_get_index
    FAILURES!!!
    Test cases run: 1/1, Passes: 0, Failures: 1, Exceptions: 0
    
    /home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php
    

    This failure occurs regardless of whether or not I make the change that you recommended to config/config.php. If I leave the line in test/app/controllers/infolake_controller.php as $this->get(AK_TESTING_URL);I don't get an error in the file access. I don't really like putting $Map->connect('/', array('controller' => 'infolake', 'action' => 'index')); in config/routes.php because it means that production code has to be modified in order to run a test. In any event, whether or not I modify config/config.php, I get the same result from $this->assertTextMatch('InfolakeController:index()');

    $ ./script/test test/app/controllers/infolake_controller.php
    InfolakeControllerTest
    1) Pattern [/^InfolakeController\:index\(\)$/] not detected in [String: test PageController:index
    
    Test::page::index] at [/home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php line 12]
        in test_should_get_index
    FAILURES!!!
    Test cases run: 1/1, Passes: 1, Failures: 1, Exceptions: 0
    
    /home/alan/develop/php/vuokraten/test/app/controllers/infolake_controller.php
    

    I think that we are not going to make test/app/controllers/infolake_controller.php work with the get line of $this->get(AK_TESTING_URL.'/infolake/'); without modifying the Akelos code, even though, from a designer's perspective, this would be the most elegant solution.

    While remaining open to more suggestions, I'm going to continue to experiment to see what I might be able to do with the application...

    • CommentAuthoralake
     

    Akelos/lib/AkDispatcher.php has a comment at the beginning that I'd like to ask about because it may help in the solution to this problem. It says @deprecated Please use AkDispatcher on your public/index.php instead Yet, my test/fixtures/public/index.php calls this one with this line: require_once(AK_LIB_DIR.DS.'AkDispatcher.php'); I don't have an AkDispatcher in my test/fixtures/public directory. Perhaps I should have a copy of AkDispatcher there that would be slightly different than the one in Akelos/lib. That difference might go to the test that I want instead of to the page controller.

    • CommentAuthoralake
     

    I have created a Wiki entry under Testing Guide / Testing a Controller that documents our progress up to this point.

    I've been trying to trace what happens with the use of $this->get(AK_TESTING_URL.'/infolake/'); in test/app/controllers/infolake_controller.php. test/fixtures/public/index.php calls AkDispatcher.php, which calls AkRequest.php. At line 752, there is an attempt to include_once($controller_path) I echoed the value of $controller_path and it contained the location of my controller: /home/alan/develop/php/vuokraten/app/controllers/infolake_controller.phpJust what I think should have been there. (I had to remove the echo statement in order to keep it from overwriting an output buffer that I don't really know how to manipulate.) Unfortunately, the operation, with or without the echo statement, gives me a 500 "Internal server" error.

    I repeated the test from my browser with `http://alan.lakeinfoworks.com/framework_tests/test/controllers/infolake_controller.php and got the single line "Test::page::index", which is in test/fixtures/app/views/page/index.tpl. This, of course, came from test/fixtures/app/controllers/page_controller.php.

    Any ideas, folks?

    • CommentAuthoralake
     

    I've begun a new project, which seems to have a different directory structure in the test section. Let me work at the new project functional test, then bring this one into compliance with it. I'll make another post...

    • CommentAuthoralake
     

    I've harmonized the two projects and can compare the differences. I've updated the Testing A Controller wiki to show the current state of affairs. When testing the original project, vuokraten, I get the same result as I got in comment 34. When testing the new project, gawenda, I get an Akelos 404 (from AkRequest.php). The difference is that the gawenda project did not have page_controller files generated in the test environment.

    Although I have not yet added it to the wiki, I have added my controller to config/routes.php. It made no difference. Adding a copy of routes.php to test/fixtures/config, makes no difference, either. My main routes.php looks like this

    <?php
    
    // You can find more about routes on /lib/AkRouters.php and /test/test_AkRouter.php
    
    $Map->connect('/:controller/:action/:id', array('controller' => 'page', 'action' => 'index'));
    $Map->connect('/', array('controller' => 'user', 'action' => 'index'));
    $Map->connect('/', array('controller' => 'page', 'action' => 'index'));
    
    ?>
    

    I have two outstanding questions:

    1. How can I make the test go to my controller instead of to "page" (if present)?
    2. Where I have several tests, how can I specify that only one (or some) of them should be run?
    • CommentAuthorcurve
     
    Any news on this?
    • CommentAuthorKaste
     
    1. It works for me. We never figured out what exactly the problem is.
    2. I've done a PHPUnit-Plugin, you can look at.
    • CommentAuthorjan
     

    Got a similar problem as alake: When I point web browser to the test/fixtures/public directory with only .htaccess and index.php (without any modifications to them), the message '404 Not found' is displayed. It comes from AkRequest.php, line 738. As alake identified already, the framework is looking for the page controller test/fixtures/app/controllers/page_controller.php which is not available. If it is copied to that location from project/app/controller/, the following error is displayed in the browser instead:

     Warning: Missing template /home/jm/linux-projects/pt/test/fixtures/app/views/page/index.tpl
     in /usr/local/web/akelos_framework/lib/AkActionController.php on line 986
    
     Fatal error: No tpl.php, js.tpl or delegate template found for
     index in /usr/local/web/akelos_framework/lib/AkActionView.php
     on line 231
    

    So can anyone please explain to me what must be configured for the browser access to tests to work properly? BTW, I have successfully created and run the dummy_web.php test from the command line, the same for hello_test.php.

    • CommentAuthorKaste
     

    Say you have a virtual server booklinktest which root points to DocumentRoot "path_to_booklink/test/fixtures/public". Then your normal routing-rules apply: http://booklinktest/book would expect a controller in path_to_booklink/test/fixtures/app/controllers/book_controller.php, which in turn looks for the view-templates in the other directory.

    What is the expected behaviour when you point your browser to test/fixtures/public?

    • CommentAuthorjan
     

    I don't use a virtual server, instead symlinks were created: DocumentRoot/project -> DevDir/project/public and DocumentRoot/project_test -> DevDir/project/test/fixtures/public.

    The directory DevDir/project/test/fixtures/app/controllers does not exist nor any templates in the test tree. OK, now I have created a simple controller DevDir/project/test/fixtures/app/controllers/device.php:

      <?php
      class DeviceTestCase extends AkWebTestCase
      {
          function testShouldGetTheGoogle()
          {  
              $this->get("http://www.google.com");
              $this->assertText("Google");
          }
      }
      ?>
    

    Not sure if this is appropriate as a test run via browser or how it should be invoked.

    The file test/fixtures/public/index.php is what has been created by the framework:

     <?php
      include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
    
      require_once(AK_LIB_DIR.DS.'AkDispatcher.php'); 
      $Dispatcher =& new AkDispatcher();
      $Dispatcher->dispatch();
      ?>
    

    I am not sure what is supposed to happen, my expectation was that the dispatch would rn the unit tests or something like that.

    • CommentAuthorKaste
     

    Ok, actually the tescases are run from the command line. Put your device.php inside test/functional/controllers f.i. [If you've used the generators you should find some dummy testcases there.]

    Add

    require_once(dirname(__FILE__).'/../../fixtures/config/config.php');
    ak_test('SearchControllerTest',true);
    

    to your device.php and run your script.

    Now the basic idea is instead of getting the google, fetch your own website.

     $this->get("http://boklinktest/"); //or whatever
    
    • CommentAuthorjan
     

    Thanks Kaste for your comments, I can see some light at the end of the tunnel now even though I am still now out of the darkness.

    You say that the 'testcases are run from the command line', when do you suggest using the browser to run tests (and what kinds of tests)? The command line execution of tests works fine for me.

    Your mention that the generators should create some dummy testcases in test/functional/controllers made me to look again at what I did and found an interesting discrepance in the use of the generators. I used ./scripts/generate model Device ./scripts/generate scaffold Device because the help claimed the scaffold generator creates controller scripts if they don't exist. But they have not put anything in test/functional/controllers. For example:

      $ ./script/generate scaffold Lap
      The following files have been created:
      /home/jm/linux-projects/pt/app/models/lap.php 
      /home/jm/linux-projects/pt/app/installers/lap_installer.php
      /home/jm/linux-projects/pt/test/unit/app/models/lap.php 
      /home/jm/linux-projects/pt/test/fixtures/app/models/lap.php
      /home/jm/linux-projects/pt/test/fixtures/app/installers/lap_installer.php
      /home/jm/linux-projects/pt/app/controllers/lap_controller.php
      /home/jm/linux-projects/pt/app/helpers/lap_helper.php
      /home/jm/linux-projects/pt/app/views/layouts/lap.tpl
      /home/jm/linux-projects/pt/app/views/lap/add.tpl
      /home/jm/linux-projects/pt/app/views/lap/destroy.tpl
      /home/jm/linux-projects/pt/app/views/lap/edit.tpl
      /home/jm/linux-projects/pt/app/views/lap/listing.tpl
      /home/jm/linux-projects/pt/app/views/lap/show.tpl
      /home/jm/linux-projects/pt/app/views/lap/_form.tpl
    
    
      $ ./script/generate controller Device
      The following files have been created:
      /home/jm/linux-projects/pt/app/controllers/device_controller.php 
      /home/jm/linux-projects/pt/app/helpers/device_helper.php
      /home/jm/linux-projects/pt/test/functional/controllers/device_controller.php
      /home/jm/linux-projects/pt/test/fixtures/app/controllers/device_controller.php
      /home/jm/linux-projects/pt/test/fixtures/app/helpers/device_helper.php
    

    There is obviously (now) a difference in what stubs get created depending on generator options. What is the most recommended aproach to generating the stubs? Is it

      ./scripts/generate model Device
      ./scripts/generate controller Device
    

    and not the scaffold?

    BTW, I have replaced test/fixtures/public/index.php with a link to test/app.php and now the web browser shows the output of all tests.

    • CommentAuthorKaste
     
    1. I think using the browser was a suggestion to check if the Apache config is right. Personally I always use the command line.

    2. The recommended approach to generate the stubs would be to fix the generator I think ;-) Check first if you're running the latest version, maybe someone fixed it already. [BTW I'm dumb when it comes to the implementaion of the generators, so I can't say much about them.]

    • CommentAuthordale
     
    FYI: For those receiving a response of 500 instead of 200, I traced a problem down to a missing directory. I had to create a tmp directory within my test directory (mkdir test/tmp) and give my web server write permissions to that directory.