使用Codeception進行Yii2的單元測試(二)測試用例(測試model類爲例)

1、生成測試文件

好比說個人models有一個須要測試得AdminUser類,我須要生成相應得測試文件,那麼咱們可使用下面得命令生成相應得測試文件php

vendor\bin\codecept generate:test unit \models\AdiminUser

執行結果以下
clipboard.pnghtml

clipboard.png

2、測試用例的編寫

咱們生成的測試用例是這個樣子的(AdiminUserTest.php):web

namespace models;

/**
 * Class AdiminUserTest by gy
 * @package models
 */
class AdiminUserTest extends \Codeception\Test\Unit
{
    /**
     * @var \UnitTester
     */
    protected $tester;
    
    protected function _before()
    {
    }

    protected function _after()
    {
    }

    // tests
    public function testSomeFeature()
    {

    }
}

如今咱們來修改這個文件,使它能完成簡單的處理。這裏的assertTrue方法,是用來作真假斷言用的。固然還有不少其餘種類的斷言,如:assertInternalType;assertEquals;assertInstanceOf……能夠查看更多斷言詳細yii2

namespace models;

/**
 * Class AdiminUserTest by gy
 * @package models
 */

class AdiminUserTest extends \Codeception\Test\Unit
{
    /**
     * @var \UnitTester
     */
    protected $tester;
    
    protected function _before()
    {
    }

    protected function _after()
    {
    }

    // tests
    public function testSomeFeature()
    {
        $this->assertTrue(1==1);
    }

    public function testFunction1()
    {
        $this->assertTrue(3 > 1);
    }
    //這個是明顯錯誤
    public function testFunction2()
    {
        $this->assertTrue(3 < 1);
    }

}

如今咱們可使用命令執行咱們的測試用例了:app

vendor\bin\codecept run unit \models\AdiminUserTest

執行結果以下所示(3個成功,1個失敗),testFunction2有明顯錯誤,改正之後會沒有失敗數量的框架

clipboard.png

好了如今咱們已經學會了簡單的斷言。可是,咱們沒有忘記,這個測試用例本意是要對AdminUser這個model類作單元測試的。接下來咱們要真正的步入正題了。yii

3、對指定的類進行單元測試

首先個人AdminUser的類以下(AdminUser.php):ide

namespace app\models;

class AdminUser extends \yii\base\BaseObject implements \yii\web\IdentityInterface
{
    public $id;
    public $username;
    public $password;
    public $authKey;
    public $accessToken;

    private static $users = [
        '100' => [
            'id' => '100',
            'username' => 'admin',
            'password' => 'admin',
            'authKey' => 'test100key',
            'accessToken' => '100-token',
        ],
        '101' => [
            'id' => '101',
            'username' => 'demo',
            'password' => 'demo',
            'authKey' => 'test101key',
            'accessToken' => '101-token',
        ],
    ];


    /**
     * {@inheritdoc}
     */
    public static function findIdentity($id)
    {
        return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
    }

    /**
     * {@inheritdoc}
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        foreach (self::$users as $user) {
            if ($user['accessToken'] === $token) {
                return new static($user);
            }
        }

        return null;
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        foreach (self::$users as $user) {
            if (strcasecmp($user['username'], $username) === 0) {
                return new static($user);
            }
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * {@inheritdoc}
     */
    public function getAuthKey()
    {
        return $this->authKey;
    }

    /**
     * {@inheritdoc}
     */
    public function validateAuthKey($authKey)
    {
        return $this->authKey === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return bool if password provided is valid for current user
     */
    public function validatePassword($password)
    {
        return $this->password === $password;
    }
}

咱們要在AdiminUserTest中去對上述的類作測試,第一步作的就是要能加載到該類。咱們知道,如今大部分框架都是使用psr-4規則的/vendor/autoload.php來完成自動加載的,固然yii2和它的codeception也是同樣的。這邊是多說了一些,等咱們後續遇到這個問題了,再詳細說。單元測試

namespace models;

use app\models\AdminUser;

/**
 * Class AdiminUserTest by gy
 * @package models
 */
class AdiminUserTest extends \Codeception\Test\Unit
{
    /**
     * @var \UnitTester
     */
    protected $tester;
    
    protected function _before()
    {
    }

    protected function _after()
    {
    }

    // tests
    public function testFindUserById()
    {
        expect_that($user = AdminUser::findIdentity(100));
        expect($user->username)->equals('admin');

        expect_not(AdminUser::findIdentity(999));
    }

    public function testFindUserByAccessToken()
    {
        expect_that($user = AdminUser::findIdentityByAccessToken('100-token'));
        expect($user->username)->equals('admin');

        expect_not(AdminUser::findIdentityByAccessToken('non-existing'));
    }

    public function testFindUserByUsername()
    {
        expect_that($user = AdminUser::findByUsername('admin'));
        expect_not(AdminUser::findByUsername('not-admin'));
    }

    /**
     * @depends testFindUserByUsername
     */
    public function testValidateUser($user)
    {
        $user = AdminUser::findByUsername('admin');
        expect_that($user->validateAuthKey('test100key'));
        expect_not($user->validateAuthKey('test102key'));

        expect_that($user->validatePassword('admin'));
        expect_not($user->validatePassword('123456'));
    }

}

expect_that: 假設爲true
expect_not: 假設爲false
和咱們用assertFalse和assertTrue意義是同樣的測試

好了,咱們來執行命令吧。看看如今的會不會如咱們設想的通常。

vendor\bin\codecept run unit \models\AdiminUserTest

clipboard.png

4個測試方法,12個斷言都沒有問題,執行成功。

總結,至此咱們的小小目標基本達成,生成測試文件,測試相關單元的目標基本均可以完成了。固然,咱們仍是有一些問題亟待解決的,好比說,咱們用來測試的數據仍是models的靜態變量(不夠真實);咱們有100個model類難道要一個個手動生成測試類;若是咱們項目文件結構有所改變的話也會會遇到一些問題。不過不要緊,咱們再接下來的幾篇文章裏會介紹相關的內容。

相關文章
相關標籤/搜索