Akita Nakarmi

@nakarmi.akita

What is Test Driven Development?

TDD is a software development discipline where developers write test cases for features before writing any code.

YES

The simple answer is

Enter the TDD Loop

Write a test, Watch it fail

Write enough code to pass the test

Improve on the code

PHP frameworks for Test 

PREPARE LARAVEL TEST SUITE

 Update your phpunit.xml file

 

 

//set enviroments for testing

  <env name="DB_CONNECTION" value="sqlite"/>
  <env name="DB_DATABASE" value=":memory:"/>
  <env name="API_DEBUG" value="false"/>
  <env name="MAIL_DRIVER" value="log"/>
  <ini name="memory_limit" value="512M" />

Prep base TestCase class


abstract class TestCase extends BaseTestCase
{
    use CreatesApplication, DatabaseMigrations, DatabaseTransactions;
    
    protected $faker;
    /**
     * Set up the test
     */
    public function setUp()
    {
        parent::setUp();
        $this->faker = Faker::create();
    }
    /**
     * Reset the migrations
     */
    public function tearDown()
    {
        $this->artisan('migrate:reset');
        parent::tearDown();
    }
}

Write a Test case


class PostApiTest extends TestCase
{
  public function test_it_can_create_a_post()
  {
      //Arrange
      $data = [
        'title'   => $this->faker->sentence,
        'content' => $this->faker->paragraph
      ];
      
      //Act
      $this->post(route('posts.store'), $data)
      
      //Assert
        ->assertStatus(201)
        ->assertJson($data);
  }
}

Run PHPUint

Error: Route not found

Test Result

Add route


//posts route
Route::post('posts', 'PostsApiController@store')->name('posts.store');

Run PHPUnit Again

Error: PostApiController does not Exist

Test Result

Create Controller

 

//create controller
php artisan make:controller PostsApiController 

Add store method


class PostsApiController extends Controller 
{
    //post method to store post
    public function store() {
        dd('here!');
    }
}

Run test 

Create the post 

    //create post from the request data
    public function store(Request $request) {
      $data=$request->all();
      $post=Post::create($data);
      
      return $post;
    }

Run Phpunit Again

Error: Opps! Post Class Not Found

Test Result 

Create model Post

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable=
        [
            'title',
            'content',
        ];
}

Run Test again and Check

Error: No Post Table Found

Test Result

Create a migration for table post

 

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

Run PHPUnit again to see what is going on

Test pass successfully!

Test Result

Refactor

Add Validation

<?php
namespace App\Articles\Requests;
use Illuminate\Foundation\Http\FormRequest;

class PostAddRequest extends FormRequest
{
  
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required',
            'content' => 'required'
        ];
    }
}

Run PHPUnit to check

Validation Test

public function test_tile_is_required(){
    $data = [
        'content' => $this->faker->paragraph,
    ];

    $this->post(route('posts.store'), $data)
         ->assertStatus(422);
}

public function test_content_is_required(){
    $data = [
        'title' => $this->faker->sentence,
    ];

    $this->post(route('posts.store'), $data)
         ->assertStatus(422);
}

Takeaway 1

We design and plan for requirement before we code

Takeaway 2

It forces us to write modular code.

Takeaway 3

TDD gives us confidence to deploy our code.

Takeaway 4

Encourages design of testable code.

Testable code looks a lot like good code.

RESULT

You write better code FASTER

CAVEAT 1

It takes a while to learn

AND

be Good at it.

CAVEAT 2

Management support is essential.

Tips While using TDD

  • Start with an assert

  • Do not write application logic in tests

  • Do not worry about testing "RIGHT" or which library to use

  • Not every feature can and should be tested

  • Just get started...

Any Questions?

Thank You 

PHP Meetup Ktm 2019 - TDD in Laravel

By nakarmi_akita

PHP Meetup Ktm 2019 - TDD in Laravel

  • 519