So I'm confused, before 5.4 I could validate both url and page content in the same place but now do I need to validate url in Feature and page content in Browser in separate tests?
For example this will pass the test even though I dont have this url registered:
$this->browse(function (Browser $browser) {
$browser->visit('/testpage');
});
And this one gives just an error that there's no matching content in body:
$this->browse(function (Browser $browser) {
$browser->visit('/testpage')
->assertSee('test');
});
Am I doing things just wrong or Feature is the place to do all the page response testing?
Kevin
Answering the title question: You can validate it by calling assertRouteIs, assertPathIs or assertPageIs.
Dusk gives you the power of manipulating a real browser. $browser->visit() won't give you any assertion, it will only open a new tab and go to the page you provided (you can even use it on the internet for boring tasks).
With Dusk, you can really test end-to-end application, such as
$browser->visit('/some-page')
->click('some-element') // Triggers an Ajax Call
->waitFor('.alert') // Wait for the ajax response by waiting for something you know will show up
->assertSee('Successfully saved!'); // Assert it worked
$this->assertDatabaseHas('table', ['column' => 'modified by ajax call']);
While with Features, you will only be able to make a HTTP Request and assert the response (without an actual browser interaction).
After understanding each one, you'll have to make the decision on what you want to test as what. Somethings you will not be able to test with Features and the decision will be easy: Only dusk can test it. Others you will be able to test from both and depending on what it is it might be better to stick with Features because it's faster and doesn't rely on external services.
For me, I'm running all my end-to-end tests on Dusk while testing elements manipulation from Features. For instance, imagine you have a dropdown with some records. Someone might inspect element and change the values there and try to break something on your software. You can test the standard behavior (is the select box working?) from Dusk. But you can fake the bad behavior of a user from Features by easily making a call that you know the ID doesn't exist and asserting that an appropriate error message is within the response. That way, you cover the happy-path of your Software Functionality from Dusk and check if you're validating your inputs correctly from Features (for faster and easier tests).
Also, APIs would usually be tested by Features since they don't require a browser to work.
Thanks, makes sense.
Sorry for opening this again but I'm still kinda confused.
Which one I should use for test driven programming like Adam Wathan does.
I understand that Dusk is just for manipulate with browser like a real person but how do I test my code now?
For example how I test now that controller is created for the model.
In 5.3 when I used $this->see('something') then it throws error when controller is not found or something else missing.
Feature testing has assertViewHas command but it also doesn't care about any other code but only checks if there's any view returned.
Edit:
So What I found that this code will pass:
$response = $this->get('/workername');
But when I dd($response) then I see the exception error message like:
#message: "Method App\Http\Controllers\WorkersController::show() does not exist"
So the error message is there but how do I get this visible?
Kevin
Don't know who or what Adam Wathan is or does and I'm not sure what you're trying to achieve. $response = $this->get('/workername'); is not really _passing_, you're just not asserting anything. It will fail if you
$response = $this->get('/workername');
$response->assertStatus(200);
If the exception was thrown, then the status code must not be 200, hence you can test it failed.
Personally, I believe end-to-end test aren't really testing your code, but rather your software. With Dusk, you could assert you see a custom 500 Internal Server Error page rendered, while with Features you are limited to only checking status code and information available on the view.
I want to achieve test driven coding. So I create my test first and then will start to code depend on what error I will get.
Right now it doesn't work because it doesn't show all the errors like if url is registered but controller is missing in web.php
Route::get('/{worker}', 'WorkersController@show');
It does find this error and stores it in $response but it doesn't display it.
Seems like the solution is not out there and this is kinda off-topic so I close the issue.
@KevinLeht I just bought the course and now I have the same issue. Have you found a solution yet?
@DonatoSal - I've only started learning TDD within the last week, and I just found Dusk within the last couple hours, so I have no idea if this is good practice, but it's possible to combine $response = $this->get('/testpage')->assertStatus(200); and $this->browse(function (Browser $browser) { $browser->visit('/testpage') ->assertSee('test'); }); in one Dusk file. As of a few minutes ago, I tried
public function test_viewFact() {
$date = date('Y-m-d');
$fact = factory(Fact::class)->create([
'date' => date('Y-m-d'),
'title' => 'My first fact',
'description' => 'This is the fact description'
]);
$this->get('/facts')
->assertStatus(200);
$this->browse(function ($browser) {
$browser->visit('/facts')
->assertPathIs('/facts')
->assertSee('My first fact')
->assertSee('This is the fact description');
});
}
As I haven't created the /facts route yet, I expected/got this when I ran the code:
There was 1 failure:
1) Tests\Feature\FactBrowserTest::test_viewFact
Expected status code 200 but received 404.
Failed asserting that false is true.
Maybe this will help you and @KevinLeht achieve what you want, and maybe someone a little more experienced (@deleugpn ?) could tell me if this is a good approach?
@DonatoSal @TatiannaWS and @KevinLeht After almost one year working a lot with Laravel and learning about the Laravel community I now know who Adam Watham is and kind of know what you guys are talking about :D
One thing I still hold true from what I said before, Dusk is not ideal for TDD, it's an end-to-end test coverage, something you do after everything is done and you just want to be sure that the whole process/software/functionality is perfectly fine. So what I would recommend is the Feature Test that comes with Laravel by default in order to test your HTTP Request / View layer on a TDD basis. It's likely that you could end up with multiple tests for a specific feature, like:
All of these could be individual feature tests that would help you drive your code (TDD). Once everything is done, you could write a single end-to-end test that covers the most important aspects of the Login Process, something like
$this->browse(functiom ($browser) {
$browser->visit('/login')
->type('email', $email);
->type('password', $password)
->press('login')
->assertPathIs('/home');
});
See that the Dusk Test will not be covering a lot of the little details, but rather cover the process as a whole. It's likely that if you remove the email input from the form, some feature test will break, but if for some reason it doesn't, as a last resort, Dusk will make sure to fail. The error message may not be friendly because you're not asserting you can see the field, you're just assuming it exists and trying to type on it, but like I said, Dusk is not the way to achieve the TDD, it's a way to protect core functionalities of the product as a whole.
@TatiannaWS I wouldn't recommend mixing Feature Test (calling $this->get) on a Browser Test. Keep responsibilities separated.
Most helpful comment
Answering the title question: You can validate it by calling
assertRouteIs,assertPathIsorassertPageIs.Dusk gives you the power of manipulating a real browser.
$browser->visit()won't give you any assertion, it will only open a new tab and go to the page you provided (you can even use it on the internet for boring tasks).With Dusk, you can really test end-to-end application, such as
While with Features, you will only be able to make a HTTP Request and assert the response (without an actual browser interaction).
After understanding each one, you'll have to make the decision on what you want to test as what. Somethings you will not be able to test with Features and the decision will be easy: Only dusk can test it. Others you will be able to test from both and depending on what it is it might be better to stick with Features because it's faster and doesn't rely on external services.
For me, I'm running all my end-to-end tests on Dusk while testing elements manipulation from Features. For instance, imagine you have a dropdown with some records. Someone might inspect element and change the values there and try to break something on your software. You can test the standard behavior (is the select box working?) from Dusk. But you can fake the bad behavior of a user from Features by easily making a call that you know the ID doesn't exist and asserting that an appropriate error message is within the response. That way, you cover the happy-path of your Software Functionality from Dusk and check if you're validating your inputs correctly from Features (for faster and easier tests).
Also, APIs would usually be tested by Features since they don't require a browser to work.