測試laravel commands的方法詳解

引言

最近使用到laravel的consolo命令行工具,在編寫命令,想寫一些測試的時候,發現官方文檔中并沒有提到command的測試方法。花了點時間,翻墻找了資料,實踐成功并記錄一下,方便更多人。

推薦:《laravel教程

測試方法

大家都知道laravel中使用了很多symfony的成熟組件,Laravel的console組件使用的就是Symfony/console。

幸運的是,Symfony/console 組件中提供了用于command測試的CommandTester, 使用方法如下

... use?FooCommand; use?SymfonyComponentConsoleApplication; use?SymfonyComponentConsoleTesterCommandTester; ... public?function?testSample(){ ????//創建一個console測試應用平臺,用來搭載測試的命令 ????$application?=?new?Application(); ???? ????//創建待測試的command ????$testedCommand?=?$this->app->make(FooCommand::class); ????//設置命令執行需要的laravel依賴 ????$testedCommand->setLaravel(app()); ????//添加待測試的command到測試應用上 ????//同時command?也綁定?application ????$application->add($testedCommand); ????//實例化命令測試類 ????$commandTester?=?new?CommandTester($testedCommand); ????//命令輸入流,對應每次交互需要提供的輸入內容 ????$commandTester->setInputs([ ????????//... ????????]); ????//執行命令 ????$commandTester->execute(['command'?=>?$testedCommand->getName()]); ????//對命令執行結果進行斷言測試,主要是依靠正則判斷 ????//$commandTester->getDisplay()?方法可以獲取命令執行后的輸出結果 ????$this->assertRegExp("/some?reg/",?$commandTester->getDisplay()); }

示例

我們現在有一個手動創建新用戶的命令createUser,作用就是手動創建一個用戶。

需要交互式讓用戶輸入name,email,password,comfirm password,這些數據。

待測試的command

<?php namespace AppConsoleCommands; use AppUser; use IlluminateAuthEventsRegistered; use IlluminateConsoleCommand; use IlluminateSupportFacadesValidator; class CreateUser extends Command {     /**      * The name and signature of the console command.      *      * @var string      */     protected $signature = &#39;createUser&#39;;     /**      * The console command description.      *      * @var string      */     protected $description = &#39;create new user for system manually&#39;;     /**      * Create a new command instance.      *      * @return void      */     public function __construct()     {         parent::__construct();     }     /**      * Execute the console command.      *      * @return mixed      */     public function handle()     {         $this->line($this-&gt;description); ????????//?獲取輸入的數據 ????????$data?=?[ ????????????'name'?=&gt;?$this-&gt;ask('What's?your?name?'), ????????????'email'?=&gt;?$this-&gt;ask('What's?your?email?'), ????????????'password'?=&gt;?$this-&gt;secret('What's?your?password?'), ????????????'password_confirmation'?=&gt;?$this-&gt;secret('Pleas?confirm?your?password.') ????????]; ????????//?驗證輸入內容 ????????$validator?=?$this-&gt;makeValidator($data); ????????if?($validator-&gt;fails())?{ ????????????foreach?($validator-&gt;errors()-&gt;toArray()?as?$error)?{ ????????????????foreach?($error?as?$message)?{ ????????????????????$this-&gt;error($message); ????????????????} ????????????} ????????????return; ????????} ????????//?向用戶確認輸入信息 ????????if?(!$this-&gt;confirm('Confirm?your?info:?'?.?PHP_EOL?.?'name:'?.?$data['name']?.?PHP_EOL?.?'email:'?.?$data['email']?.?PHP_EOL?.?'is?this?correct?'))?{ ????????????return; ????????} ????????//?注冊 ????????$user?=?$this-&gt;create($data); ????????event(new?Registered($user)); ????????$this-&gt;line('User?'?.?$user-&gt;name?.?'?successfully?registered'); ????} ????/** ?????*?Get?a?validator?for?an?incoming?registration?request. ?????* ?????*?@param??array?$data ?????*?@return?IlluminateContractsValidationValidator ?????*/ ????protected?function?makeValidator($data) ????{ ????????return?Validator::make($data,?[ ????????????'name'?=&gt;?'required|string|max:255|unique:users', ????????????'email'?=&gt;?'required|string|email|max:255|unique:users', ????????????'password'?=&gt;?'required|string|min:6|confirmed' ????????]); ????} ????/** ?????*?Create?a?new?user?instance?after?a?valid?registration. ?????* ?????*?@param??array?$data ?????*?@return?AppUser ?????*/ ????protected?function?create($data) ????{ ????????return?User::create([ ????????????'name'?=&gt;?$data['name'], ????????????'email'?=&gt;?$data['email'], ????????????'password'?=&gt;?bcrypt($data['password']) ????????]); ????} }

正確的結果

如果正確輸入信息的話,會得到如下輸出

$?path-to-your-app/app#?php?artisan?createUser create?new?user?for?system?manually ?What's?your?name?: ?&gt;?vestin ?What's?your?email?: ?&gt;?correct@abc.com ?What's?your?password?: ?&gt;? ?Pleas?confirm?your?password.: ?&gt;? ?Confirm?your?info:? name:vestin email:correct@abc.com is?this?correct??(yes/no)?[no]: ?&gt;?yes User?vestin?successfully?registered

想要測試的內容

我想要測試兩塊內容:

1.數據輸入驗證測試

● email有效性測試

●?password兩次輸入是否相同的測試

2.正確創建用戶測試

●?編寫單元測試

<?php namespace TestsUnitcommand; use AppConsoleCommandsCreateUser; use SymfonyComponentConsoleApplication; use SymfonyComponentConsoleTesterCommandTester; use TestsTestCase; use IlluminateFoundationTestingRefreshDatabase; class CreateUserTest extends TestCase {     use RefreshDatabase;     /**      * 測試數據驗證      *      * @return void      */     public function testValidation()     {         $application = new Application();         $testedCommand = $this->app-&gt;make(CreateUser::class); ????????$testedCommand-&gt;setLaravel(app()); ????????$application-&gt;add($testedCommand); ????????$commandTester?=?new?CommandTester($testedCommand); ????????$commandTester-&gt;setInputs(['Vestin',?'badEmail@abc',?'123456',?'654321']); ????????$commandTester-&gt;execute(['command'?=&gt;?$testedCommand-&gt;getName()]); ????????//?assert ????????$this-&gt;assertRegExp("/The?email?must?be?a?valid?email?address/",?$commandTester-&gt;getDisplay()); ????????$commandTester-&gt;setInputs(['vestin',?'correct@abc.com',?'123456',?'654321']); ????????$commandTester-&gt;execute(['command'?=&gt;?$testedCommand-&gt;getName()]); ????????//?assert ????????$this-&gt;assertRegExp("/The?password?confirmation?does?not?match/",?$commandTester-&gt;getDisplay()); ????} ????/** ?????*?測試成功注冊用戶 ?????* ?????*?@return?void ?????*/ ????public?function?testSuccess() ????{ ????????$application?=?new?Application(); ????????$testedCommand?=?$this-&gt;app-&gt;make(CreateUser::class); ????????$testedCommand-&gt;setLaravel(app()); ????????$application-&gt;add($testedCommand); ????????$commandTester?=?new?CommandTester($testedCommand); ????????$commandTester-&gt;setInputs(['Vestin',?'correct@abc.com',?'123456',?'123456',?'y']); ????????$commandTester-&gt;execute(['command'?=&gt;?$testedCommand-&gt;getName()]); ????????//?assert ????????$this-&gt;assertRegExp("/User?Vestin?successfully?registered/",?$commandTester-&gt;getDisplay()); ????????$this-&gt;assertDatabaseHas('users',?[ ????????????'email'?=&gt;?'correct@abc.com', ????????????'name'?=&gt;?'Vestin' ????????]); ????} }

執行測試

$?path-to-your-app/app#??./vendor/bin/phpunit? PHPUnit?6.4.3?by?Sebastian?Bergmann?and?contributors. ..??????????????????????????????????????????????????????????????????3?/?3?(100%) Time:?659?ms,?Memory:?14.00MB

以上就是測試

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享