Building Advance Blog on Laravel 5.5 with TDD mode #2 Prepare the first test
Tags: php, laravel5, laravel, phpdevelopers
Published: 2017-11-26 13:00:09

---
title: "Building Advance Blog on Laravel 5.5 with TDD mode #2 Prepare the first test"
published: true
tags: php,laravel-5,laravel,php-developers
canonical_url: https://medium.com/lordofdev/building-advance-blog-on-laravel-5-5-with-tdd-mode-2-prepare-the-first-test-80c4687cfca6
---

![](https://cdn-images-1.medium.com/max/1024/1*P2ZqT01b-aiU5bschYM-Ng.png)

previously post [we prepare an environment for testing&nbsp;mode](https://dev.to/krissnawat/building-advance-blog-on-laravel-55-with-tdd-mode-1-prepare-environment-and-database-5ha-temp-slug-2286225)

I assume you gonna heard PHPUnit before in this post I’ve set up the first&nbsp;test

for now when we use php artisan do everything blah blah we need to include --env=testing you and me so very&nbsp;boring

but we can remove with an apply configuration to&nbsp;PHPUnit

### Locate PHPUnit

in Laravel PHPUnit executable is hide in vendor/bin

![](https://cdn-images-1.medium.com/max/207/1*_Phavx-ziWwZlODKCpIMBw.png)

when use we need to include&nbsp;path

![](https://cdn-images-1.medium.com/max/752/1*xLlij2babZ7nAFyUiW46sA.png)

#### Alias phpunit&nbsp;path

my typing is slow so that I’ve set shortcut with alias p ='vendor/bin/phpunit'

![](https://cdn-images-1.medium.com/max/687/1*L6opuvBBnMcsZMjL57Gj9g.png)

now we call p&nbsp;instead

#### Setup PHPUNIT

In test environment we need to use sqlite and instead create a real record in database then we keep it in memory&nbsp;, then open phpunit.xml

![](https://cdn-images-1.medium.com/max/210/1*Jz8M67j0TZMqLA7ThV4SYg.png)

scroll down to environment setting

first set DB connection to&nbsp;SQLite

```
<env name=”DB_CONNECTION” value=”sqlite”/>
```

and set a database to&nbsp;:memory: because we keep a record in&nbsp;memory

```
<env name=”DB_DATABASE” value=”:memory:”/>
```

![](https://cdn-images-1.medium.com/max/626/1*MuB1w8PaG3k5vOqy3nBGUA.png)

next station&nbsp;,create the first&nbsp;Test

#### Set up built-in auth for quick&nbsp;scaffold

when starting from scratch we don’t have any view file so that we use built-in authentication for quick scaffold&nbsp;view

try php artisan make:auth

now we have a layout an simple authentication mechanism

![](https://cdn-images-1.medium.com/max/210/1*SdcT6HFm3UBXDWepwrCFag.png)

and simple&nbsp;layout

#### a\_guest\_can\_view\_all\_thread

for the first test I’ve to use Artisan for quick create a code&nbsp;snippet

php artisan make:test PostTest

after use file still appear&nbsp;in

![](https://cdn-images-1.medium.com/max/205/1*hzyKIJEDLWUQ1tc6zHrnXw.png)

and open&nbsp;this

![](https://cdn-images-1.medium.com/max/624/1*k6eQFk72RpZxSAK6lwcy3A.png)

line 3 we define namespace by folder   
line 5 include TestCase Class  
line 6 include RefreshDatabase trait for refresh database every time when test is called think like we call php artisan migrate:refresh every time when call a test because it’s clear for clean all condition

for a first function we see testExample that assertTrue when&nbsp;true

### Test access&nbsp;endpoint

now we change function name to a\_guset\_can\_access\_blog\_index   
this make sure blog homepage have can&nbsp;access

```
public function a_guset_can_access_blog_index()
    {
    $response = $this->get('/blog'); //make GET access to blog route
        
    $response->assertStatus(200); //assert http status return is 200 
    }
```

run PHPUnit

![](https://cdn-images-1.medium.com/max/671/1*1mqwqJLQJfJYiX_4eaLglg.png)

nope why not found a test&nbsp;?

try googling with php unit warning test not found and find an answer in stack&nbsp;overflow

[from this&nbsp;answer](https://stackoverflow.com/a/27599293/733676)

> The only methods that PHPUnit will recognize as tests are those with names [starting with&nbsp; **test**](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html).> So you should rename the it\_fetches\_posts() method to test\_it\_fetches\_posts ortestItFetchesPosts. The camel case naming is optional but useful if you use the --testdox option&nbsp;later.> Also, as stated in other answer you can also add the @test annotation to any method and it will be considered a test by&nbsp;PHPUnit.

that’s has 2 ways to solve use @test annotation or use test&nbsp;prefix

I choose prefix it’s quick&nbsp;way

```
public function test_a_guset_can_access_blog_index()
```

try p&nbsp;again

![](https://cdn-images-1.medium.com/max/833/1*nxdevI0v6Vh24PEtx4kFoA.png)

cause of 404&nbsp;is

1. route for the blog doesn’t&nbsp;exist
2. controller for the post doesn’t&nbsp;exist
3. the method doesn’t&nbsp;exist

I’ve to try to fix step by&nbsp;step

#### create blog&nbsp;route

open /route/web.php and&nbsp;fill

```
Route::get(‘/blog’,’PostsController@index’);
```

run p&nbsp;again

![](https://cdn-images-1.medium.com/max/828/1*JbFWJq7jtYtHn_Sj9Wi2Ng.png)

that’s still an error because PostsController doesn’t&nbsp;exist

try php make:controller PostsController and still try&nbsp;top

![](https://cdn-images-1.medium.com/max/925/1*D1FC18xmnFoTMn8ZN8l31w.png)

Yeah&nbsp;,seem error change 404 to 500 and last I still try add index&nbsp;method

```
public function index(){
        return view('home');
}
```

and use a home view for temporary and try p&nbsp;again

![](https://cdn-images-1.medium.com/max/711/1*Cb1lXn0E1l1tDagw1p5crQ.png)

that’s work

let’s view in a browser if you use c9 click&nbsp;this

![](https://cdn-images-1.medium.com/max/816/1*C-tiKFLIWZ-DhdrOMXU0uQ.png)

terminal instant show server&nbsp;status

![](https://cdn-images-1.medium.com/max/1009/1*7SDJjgOmStObjRgFX6gzzg.png)

click link to this and fill URL&nbsp;blog

![](https://cdn-images-1.medium.com/max/1008/1*zWLbLOtZDnseP2k-skrEmQ.png)

that really work but css&nbsp;, js doesn’t work because apublic&nbsp;folder

I’ve try to investigate this issue without removing public folder find this answer from [stack&nbsp;overflow](https://stackoverflow.com/a/32580688/733676)

> Renaming the server.php to index.php (no modifications)> Copy the&nbsp;.htaccess from public folder to root folder (like rimon.ekjon said&nbsp;below)> Changing&nbsp;.htaccess it a bit as follows for&nbsp;statics:> RewriteEngine On  
> RewriteCond %{REQUEST\_FILENAME}&nbsp;!-d  
> RewriteRule ^(.\*)/$ /$1 [L,R=301]  
> RewriteCond %{REQUEST\_URI}&nbsp;!(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]  
> RewriteCond %{REQUEST\_FILENAME}&nbsp;!-d  
> RewriteCond %{REQUEST\_FILENAME}&nbsp;!-f  
> RewriteRule ^ index.php [L]  
> RewriteCond %{REQUEST\_FILENAME}&nbsp;!-d  
> RewriteCond %{REQUEST\_FILENAME}&nbsp;!-f  
> RewriteCond %{REQUEST\_URI}&nbsp;!^/public/  
> RewriteRule ^(css|js|images)/(.\*)$ public/$1/$2 [L,NC]> If there are any other **static files** needed just add the extension to the previous declared&nbsp;list

and I’ve try this work! we can use blog route without&nbsp;public

it’s work I don’t know! why? because I don’t become a&nbsp;sysadmin

![](https://cdn-images-1.medium.com/max/1024/1*9k_ADw7ph2KlEnJsspMQOQ.png)

but asset doesn’t load properly because a domain is use https let’s fix&nbsp;later

next, we display all&nbsp;posts

### Test Display all&nbsp;post

first include Post model withUse App\Post;

and update index method&nbsp;with

```
public function index(Post $post){ // inject Post Model
        // query sort by created_at desc
        $posts = $post::latest()->get(); 
        // bind query result to view
         return view('post.index')->with(['posts'=>$posts]);
    }
```

next we create folder and view create post/index.blade.php

![](https://cdn-images-1.medium.com/max/175/1*xOWCTnoKH08BRi-s18_rug.png)

open home.blade.php and grab all HTML paste to index.blade.php and add code like this&nbsp;image

![](https://cdn-images-1.medium.com/max/835/1*3K_A3kYYEtwAwZonxQLcfw.png)

loop $posts display in the article&nbsp;tag

now we try to run a&nbsp;test

![](https://cdn-images-1.medium.com/max/627/1*TcF-VY4HZSDbmPW6h8SGkg.png)

it’s pass because the test doesn’t complicate more than expect HTTP status&nbsp;200

now we view in&nbsp;browser

![](https://cdn-images-1.medium.com/max/1024/1*aF9-PSTwmav7Wr11iPQRPg.png)

it’s doesn’t work because cloud9 apache doesn’t read env.testing and laravel builtin server doesn’t work on&nbsp;cloud9

in this situation for quick solution I’ve open&nbsp;.env file and change mysql to sqlite like&nbsp;so

![](https://cdn-images-1.medium.com/max/784/1*auSVVwTzVZVRDqBYou82zg.png)

save and refresh browser&nbsp;again

![](https://cdn-images-1.medium.com/max/1015/1*TEx21VasbGnID3Z-sPZjlw.png)

it’s time to fix https asset&nbsp;issue

open layouts/app.blade.php and use find and replace like an&nbsp;image

![](https://cdn-images-1.medium.com/max/1024/1*cMRuDFmXnCq_ytwxZwZP7g.png)

then save and&nbsp;refresh

![](https://cdn-images-1.medium.com/max/1024/1*5gj5hTYhfohW1akI-eChlQ.png)

look much&nbsp;better

let’s take improve test for a little&nbsp;smart

I assume you know[what is BDD User Story](https://dannorth.net/whats-in-a-story/) then write user story when we need to see post title appear after&nbsp;create

```
public function test_a_guset_can_access_blog_index()
    {
        // Giving post object
       // When guest access blog url
       // Then I've see blog title that create before

}
```

let’s fill test&nbsp;code

```
public function test_a_guset_can_access_blog_index()
    { // Giving post object
        $post = factory('App\Post')->create();//create post data
        // When guest access blog url
        $response = $this->get('/blog'); //visit blog homepage 
        // Then I've see blog title that create before
        $response->assertSee($post->title); // expect to see post 
    }
```

try run&nbsp;test

![](https://cdn-images-1.medium.com/max/758/1*ECcDkIK92Eg0HiK_G1M9qw.png)

it’s work next I’ve go to test when we show single&nbsp;post

### Display single&nbsp;post

create test function name test\_a\_guest\_can\_see\_single\_post

first I’ve draft BDD user&nbsp;story

```
public function test_a_guest_can_see_single_post(){
        // giving post data
        // when guest access blog/{id}
        // expect to see post title
    }
```

then fill&nbsp;code

```
public function test_a_guest_can_see_single_post(){
        // giving post data
        $post = factory('App\Post')->create();
        // when guest access blog/{id}
        $response = $this->get('/blog/'.$post->id);
        // expect to see post title
        $response->assertSee($post->title);
    }
```

save and run&nbsp;test

![](https://cdn-images-1.medium.com/max/755/1*DvUymurqhoxcZ2SLDLqjTA.png)

yeah&nbsp;,&nbsp;Fail

next, I plan to create route&nbsp;, show function and show&nbsp;view

#### create show&nbsp;route

open route/web.php and fill&nbsp;route

![](https://cdn-images-1.medium.com/max/687/1*q2zjtwv-Zr8zJObnUekQ6A.png)

run test

![](https://cdn-images-1.medium.com/max/731/1*ZUjd0CMGiIX3-10s4i6BUw.png)

expected to&nbsp;meet

now create show&nbsp;method

![](https://cdn-images-1.medium.com/max/597/1*qzAvhAIMZ1aJCHrPiWA5Ng.png)

we use [model binding](https://laravel.com/docs/5.5/routing#route-model-binding) mechanism handling

run test

![](https://cdn-images-1.medium.com/max/533/1*CuwaQN28A70NptqEissG2Q.png)

it’s paste why? open&nbsp;browser

![](https://cdn-images-1.medium.com/max/931/1*LSQ5hKQ0pTKYHF2CnD7-qA.png)

we expect to see&nbsp;it

I’ve make sure you don’t need to show raw data so, let’s modify show&nbsp;funciton

```
public function show(Post $post){
        return view('post.show')->with(['post'=>$post]);
    }
```

next, we create show&nbsp;view

![](https://cdn-images-1.medium.com/max/176/1*cRNYJ-JySXZsnlBwVkmuKw.png)

and grab a code from index.blade.php paste in show.blade.php

and update make the header to post title and remove form&nbsp;loop

![](https://cdn-images-1.medium.com/max/721/1*So3RY6a0vQgi_UFydhpS3Q.png)

just save and refresh a&nbsp;browser

![](https://cdn-images-1.medium.com/max/1024/1*Gf5Sa5JEIuT7mQsTGRgOvg.png)

ah look nice and run a test&nbsp;again

![](https://cdn-images-1.medium.com/max/723/1*o9jf1F1mAdiHunDfrjEkpQ.png)

next, wee add link for access single post in blog&nbsp;index

![](https://cdn-images-1.medium.com/max/868/1*CDNKrrzLErrvzbxR1nuSnA.png)

we add a link to single post let’s test in the&nbsp;browser

![](https://cdn-images-1.medium.com/max/1024/1*6fum1WTyUmVw9dzfjT8DlA.png)

complete how I&nbsp;feel

<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2Fl4FGni1RBAR2OWsGk%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2Fl4FGni1RBAR2OWsGk%2Fgiphy.gif&amp;image=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2Fl4FGni1RBAR2OWsGk%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="246" frameborder="0" scrolling="no"><a href="https://medium.com/media/d86879fd098964acfcb8c713abcb8022/href">https://medium.com/media/d86879fd098964acfcb8c713abcb8022/href</a></iframe>

**if you like this please give me 50 claps and hit follow that encouragement to move&nbsp;forward**

**this** [**project Github commit**](https://github.com/krissnawat/advance-blog-in-laravel-5.5-in-tdd/commit/70a70bc55e6a95efb9304a73aa18ea5fd591e9de) **and you can star&nbsp;it**

* * *