Run PHPUnit Tests in Certain Order

前端 未结 8 1417
悲哀的现实
悲哀的现实 2020-12-04 15:20

Is there a way to get the tests inside of a TestCase to run in a certain order? For example, I want to separate the life cycle of an object from creation to use

8条回答
  •  借酒劲吻你
    2020-12-04 15:43

    Alternative solution: Use static(!) functions in your tests to create reusable elements. For instance (I use selenium IDE to record tests and phpunit-selenium (github) to run test inside browser)

    class LoginTest extends SeleniumClearTestCase
    {
        public function testAdminLogin()
        {
            self::adminLogin($this);
        }
    
        public function testLogout()
        {
            self::adminLogin($this);
            self::logout($this);
        }
    
        public static function adminLogin($t)
        {
            self::login($t, 'john.smith@gmail.com', 'pAs$w0rd');
            $t->assertEquals('John Smith', $t->getText('css=span.hidden-xs'));
        }
    
        // @source LoginTest.se
        public static function login($t, $login, $pass)
        {
            $t->open('/');
            $t->click("xpath=(//a[contains(text(),'Log In')])[2]");
            $t->waitForPageToLoad('30000');
            $t->type('name=email', $login);
            $t->type('name=password', $pass);
            $t->click("//button[@type='submit']");
            $t->waitForPageToLoad('30000');
        }
    
        // @source LogoutTest.se
        public static function logout($t)
        {
            $t->click('css=span.hidden-xs');
            $t->click('link=Logout');
            $t->waitForPageToLoad('30000');
            $t->assertEquals('PANEL', $t->getText("xpath=(//a[contains(text(),'Panel')])[2]"));
        }
    }
    

    Ok, and now, i can use this reusable elements in other test :) For instance:

    class ChangeBlogTitleTest extends SeleniumClearTestCase
    {
        public function testAddBlogTitle()
        {
          self::addBlogTitle($this,'I like my boobies');
          self::cleanAddBlogTitle();
        }
    
        public static function addBlogTitle($t,$title) {
          LoginTest::adminLogin($t);
    
          $t->click('link=ChangeTitle');
          ...
          $t->type('name=blog-title', $title);
          LoginTest::logout($t);
          LoginTest::login($t, 'paris@gmail.com','hilton');
          $t->screenshot(); // take some photos :)
          $t->assertEquals($title, $t->getText('...'));
        }
    
        public static function cleanAddBlogTitle() {
            $lastTitle = BlogTitlesHistory::orderBy('id')->first();
            $lastTitle->delete();
        }
    
    • In this way, you can build hierarchy of you tests.
    • You can steel keep property that each test case is totaly separate from other (if you clean DB after each test).
    • And most important, if for instance, the way of login change in future, you only modify LoginTest class, and you don'n need correct login part in other tests (they should work after update LoginTest) :)

    When I run test my script clean up db ad the begining. Above I use my SeleniumClearTestCase class (I make screenshot() and other nice functions there) it is extension of MigrationToSelenium2 (from github, to port recorded tests in firefox using seleniumIDE + ff plugin "Selenium IDE: PHP Formatters" ) which is extension of my class LaravelTestCase (it is copy of Illuminate\Foundation\Testing\TestCase but not extends PHPUnit_Framework_TestCase) which setup laravel to have access to eloquent when we want to clean DB at the end of test) which is extension of PHPUnit_Extensions_Selenium2TestCase. To set up laravel eloquent I have also in SeleniumClearTestCase function createApplication (which is called at setUp, and I take this function from laral test/TestCase)

提交回复
热议问题