PHP单元只检查第一个测试

时间:2018-03-12 17:43:21

标签: laravel-5 phpunit

我正在运行Laravel,在尝试开发自动化时遇到了问题。我有以下测试:

class SubmitSurvivorTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */

    //Test for submit with missing parameters
    public function testEmptySubmit()
    {
        $response = $this->get('/submit/survivor');
        $response->assertSee('422');
    }

    //Test for submit with complete parameters
    public function testCorrectSubmit()
    {
        $response = $this->get('/submit/survivor?name=Jhon+Doe&age=22&gender=m&latitude=0&longitude=0&water=6&food=4&medicine=9&ammo=4');
        $response->assertSee('666');
    }
}

第一个应该返回true,因为如果我去/提交/幸存者我会得到

{"status":"422","message":"The request could not be delivered since it's missing one or more paramters"}

第二个应该返回false,因为我

{"status":"204","message":"Created successfully"}

但是第二个仍然是真实的。无论我输入第二个断言的值如何运行phpunit总是给我0失败。对于其他所有测试都是如此,在我看来,它只是验证了第一种方法。

我已尝试将其更改为

public function testEmptySubmit()
{
    $response = $this->get('/submit/survivor');
    $response->assertSee('422');
    $asd = $this->get('/submit/survivor?name=Jhon+Doe&age=22&gender=m&latitude=0&longitude=0&water=6&food=4&medicine=9&ammo=4');
    $asd->assertSee('666');
}

仍然没有失败,但如果我改变了第一个中的值,我仍然会失败。

更改顺序似乎没有任何影响,我将testCorrectSubmit更改为testEmptySubmit以上,但它仍然无法正常工作。

如果我在第二个中将它更改为assertDontSee它会导致失败,即使它应该返回true,错误太大甚至不适合我的终端但是

[A ton of lines with html,js and stuff i can't identify]
</script>\n
</body>\n
</html>\n
' does not contain "666".

C:\xampp\htdocs\mysurvivorapi\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestResponse.php:331
C:\xampp\htdocs\mysurvivorapi\tests\Feature\submitSurvivorTest.php:27

FAILURES!
Tests: 6, Assertions: 6, Failures: 1.

我甚至看不到&#34;未能断言&#34;但我只是假设它在那里

使用assertSeeText似乎与

一样奇怪
public function testCorrectSubmit()
    {
        $response = $this->get('/submit/survivor?name=Jhon+Doe&age=22&gender=m&latitude=0&longitude=0&water=6&food=4&medicine=9&ammo=4');
        $response->assertSeeText('Jhon');
    }

不会返回任何错误,但如果我改变了Jhon&#39;到&#39; 666&#39;即使它们都不在页面中,它也会返回错误

根据文档,它应该看起来像

public function testCorrectSubmit()
    {
        $response = $this->get('/submit/survivor',[
            'name' => 'Jhon Doe',
            'age' => '22',
            'gender' => 'm',
            'latitude' => '0',
            'longitude' => '0',
            'water' => '6',
            'food'=>'4',
            'medicine' =>'9',
            'ammo' => '4']);
        $response->assertSeeText('Jhon');
    }

部分工作,返回

Failed asserting that '{"status":"422","message":"The request could not be delivered since it's missing one or more paramters"}' contains "Jhon".

它向我显示它正在发出请求,但它没有发送GET参数。

我从@Spacemudd完成了第3步,因为我不知道如何进行第4步,现在它正在发送GET参数,因为现在Jhon Doe出现在数据库中。但现在phpunit正在返回

C:\xampp\htdocs\mysurvivorapi>php vendor/phpunit/phpunit/phpunit
PHPUnit 7.0.2 by Sebastian Bergmann and contributors.

.{"status":"204","message":"Created successfully"}

那就是它,没有失败也没有,没有什么,但如果我去幸存者表,我可以看到Jhon Doe被插入,我想这是一个改进?

原来它按预期工作。最后一个奇怪的行为是由于我有其他测试与testCorrectSubmit一样错误。删除它们解决了这个问题,现在我正确地重写了它。

原来我错了,似乎即使是正确的结构,也没有其他测试测试完整提交失败。我删除了所有测试,使用php artisan make创建了一个新测试:test submitSurvivorTest,看起来像这样

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class submitSurvivorTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testSubmitEmpty()
    {
        $route = route('submit.survivor');
        $response = $this->get($route);
        $response->assertSee('422');
    }
    public function testSubmitComplete()
    {
        $route = route('submit.survivor', [
            'name' => 'Jhon Doe',
            'age' => '22',
            'gender' => 'm',
            'latitude' => '0',
            'longitude' => '0',
            'water' => '6',
            'food'=> '4',
            'medicine' => '9',
            'ammo' => '4',
        ]);
        $response = $this->get($route);
        $response->assertStatus(200);
    }
}

我已将名字放入我的路线文件中,它看起来像这样:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

//Go to Index
Route::get('/', 'Controller@goHome');

//Submit a new Survivor
Route::name('submit.survivor')->get('/submit/survivor', 'SurvivorsController@submit');

//See a survivor, if no survivor id is submited sees all registered survivors
Route::name('request.survivors')->get('/request/survivors', 'SurvivorsController@getSurvivors');

//See statistics from the survivors, like average water per survivor for example.
Route::name('request.survivors.reports')->get('/request/survivors/reports', 'SurvivorsController@getReportsSurvivors');

//Update a survivor location
Route::name('update.survivor.location')->get('/update/survivor/location', 'SurvivorsController@updateSurvivorLocation');

//Flag a survivor as contaminated
Route::name('update.survivor.flag')->get('/update/survivor/flag', 'LogsController@submitFlag');

//Trade items between survivors
Route::name('update.survivors.trade')->get('/update/survivor/trade', 'TradesController@submitTrade');

我的提交方法就是

public function submit(Request $request){

        //Check if the required variables where sent, and if no it'll return an error
        $validator = Validator::make($request->all(), [
            'name'      =>  'required',
            'age'       =>  'required',
            'gender'    =>  'required',
            'latitude'  =>  'required',
            'longitude' =>  'required',
            'water'     =>  'required',
            'food'      =>  'required',
            'medicine'  =>  'required',
            'ammo'      =>  'required'
        ]);

        if ($validator->fails()) {
            $result = array('status' => '422', 'message' => 'The request could not be delivered since it\'s missing one or more paramters');
            echo json_encode($result);
        }

        //Create a new survivor
        $survivor = new Survivor;
        $survivor->name = $request->input('name');
        $survivor->age = $request->input('age');
        $survivor->gender = $request->input('gender');
        $survivor->latitude = $request->input('latitude');
        $survivor->longitude = $request->input('longitude');
        $survivor->water = $request->input('water');
        $survivor->food = $request->input('food');
        $survivor->medicine = $request->input('medicine');
        $survivor->ammunition = $request->input('ammo');

        //Save survivor
        $survivor->save();

        //Set the success message
        $result = array('status' => '204', 'message' => 'Created successfully');

        //Save the change into the logs and display the result
        app( 'App\Http\Controllers\LogsController')->submitLog($survivor->id,$survivor->id,"register",$result);
        exit();
    }

所有功能都直接用于浏览器,他们只是不使用自动化测试。

此时运行返回

C:\xampp\htdocs\mysurvivorapi>php vendor/phpunit/phpunit/phpunit
PHPUnit 7.0.2 by Sebastian Bergmann and contributors.

..Array{"status":"204","message":"Created successfully"}

并且使用--testdox-html在我看来它甚至在显示第一个测试的结果之前就停止了它的执行,这很好用

似乎使用--process-isolation运行可以避免崩溃并且测试执行得很好。我已经改变所有echo $响应返回,因为它似乎更好。现在它验证了emptySubmit,但没有验证completeSubmit

现在删除exit(),测试运行时没有--process-isolation并返回 无法断言&#39;&#39;包含&#34; 204&#34;。

C:\xampp\htdocs\mysurvivorapi\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestResponse.php:253
C:\xampp\htdocs\mysurvivorapi\tests\Feature\submitSurvivorTest.php:36

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

但是这是通过设置来解决的,因此响应直接在submit方法中返回,而不是在日志中。现在它似乎正常工作,因为它现在返回基于验证的响应。我将开发其余的自动化测试,看看问题是否再次出现。

1 个答案:

答案 0 :(得分:1)

  1. 确保您的larvel.log在完成测试时没有显示任何异常。
    1. 确保您呼叫的路由不在中间件auth下,在这种情况下,您必须在呼叫路由之前对用户进行身份验证。
    2. $response = $this->actingAs($user)->get('/submit/survivor');

      其中$user可以是您的用户模型类的实例。

      1. 考虑使用帮助程序命令route()来构建URL。
      2. web.php中,为路线添加名称,例如

        Route::name('survivors.submit')->get('survivors/submit', 'SurvivorsController@store');

        在你的测试中,它会变成:

        $route = route('survivors.submit', [
                    'name' => 'Jhon Doe',
                    'age' => '22',
                    'gender' => 'm',
                    'latitude' => '0',
                    'longitude' => '0',
                    'water' => '6',
                    'food'=> '4',
                    'medicine' => '9',
                    'ammo' => '4',
                  ]);
        
        $response = $this->get($route);
        
        1. 在提交控制器/函数中使用dd();,然后运行测试。这有助于您确定问题的确切位置。
        2. 例如,为确保您收到正确的会话数据,请拨打dd(request()->except('_token'));