Warum Tests schreiben?
In der Anfangsphase der Entwicklerkarriere oder in Unternehmen, in denen es keine richtigen Arbeitsabläufe gibt, kommen viele von uns damit davon (und viele tun es immer noch), keine Tests zu schreiben. Wir greifen darauf zurück, unseren Code manuell zu testen, d. h. die Seite zu öffnen, das Formular auszufüllen und auf mögliche Probleme zu prüfen.
Jedes Mal, wenn wir Änderungen vornehmen oder neue Funktionen zu unserer Anwendung hinzufügen, sind wir am Tag der Veröffentlichung besorgt und hoffen und beten, dass sie nicht kaputt geht.
Lesen Sie auch: Softwaretests vs. Qualitätssicherung
Lesen Sie auch: Livewire Kommentare Laravel
Je mehr Funktionen eine App hat, desto hektischer wird es, sie zu warten.
Der beste Weg, diese Angst ein für alle Mal loszuwerden, ist das Schreiben von Tests.
Aber wie soll ich anfangen?
Haben Sie auch schon Stunden damit verbracht, Ihrem Lieblings-YouTube-Lehrer dabei zuzusehen, wie er Sie durch jeden Schritt von der Installation von Laravel und PHPUnit bis zur Konfiguration der Datenbank und dem Schreiben Ihres ersten Tests führt, aber am Ende sind Sie immer noch nicht in der Lage, selbst Tests zu schreiben?
Lesen Sie auch: Top Programmier-Jobs in Großbritannien
In diesem Artikel gebe ich Ihnen ein genaues Konzept an die Hand, das Ihnen nicht nur dabei helfen wird, Ihren ersten Test zu schreiben, sondern auch dabei, Tests schnell und effizient zu erstellen.
Bevor ich Ihnen also den Bauplan vorstelle, lassen Sie uns einige Annahmen treffen. Erstens haben Sie ein Grundwissen über Laravel, MVC und CRUD. Zweitens gehe ich davon aus, dass Sie Grundkenntnisse über PHPUnit haben und wissen, wie man es installiert. Falls nicht, empfehle ich Ihnen, sich diese beiden tollen Serien über das Testen in Laravel von Jeffrey Way anzusehen: Testing Laravel and Testing Jargon. Drittens haben Sie bereits alles eingerichtet, was Sie brauchen, um mit dem Schreiben von Tests zu beginnen. Sie sollten also grünes Licht bekommen, wenn Sie ausführen:
php artisan test
Fangen wir also an.
Die Blaupause
Wir wissen also, dass jeder Controller mindestens eine der folgenden Methoden hat: index
, show
, create
, store
, edit
, update
, delete
. Wir schreiben unsere Tests auf der Grundlage dieser Aktionen. Werfen wir einen Blick auf den Entwurf für das Schreiben von Tests für die Methoden index und show:
public function test_it_shows_all_the_posts()
{
// Given in our database, we have 5 posts
// When we visit the posts page
// Then we should see a paginated list of all the posts
}
public function test_it_shows_a_single_post()
{
// Given in our database, we have a post with the title "This is a test post"
// When we visit the post page
// Then we should see the post with the title "This is a test post"
}
Was Sie oben sehen, nennt man das Given-When-Then-Muster oder Arrange, Act, Assert. Damit können Sie Ihre Tests strukturieren. Es erleichtert Ihnen auch das Lesen und Verstehen Ihrer Tests.
Lesen Sie auch: Die wichtigsten PHP-Trends im Jahr 2022
Zur Sache selbst
Lassen Sie uns nun den Test tatsächlich schreiben. Wir beginnen mit der Erstellung einer neuen Testklasse. Wir nennen sie PostControllerTest.php
innerhalb der tests/Features
Ordner. Außerdem erstellen wir innerhalb der Klasse eine neue Methode namens test_it_shows_all_the_posts
und diese Methode stellt die index
Methode in unserem Controller.
Sie können auch die artisan
Befehl, um die Testklasse für Sie zu erstellen. Führen Sie einfach php artisan make:test PostControllerTest
.
Entfernen Sie die test_example
Methode und ersetzen Sie sie durch die test_it_shows_all_the_posts
methode.
<?php
namespace Tests\Feature;
use \Illuminate\Foundation\Testing\RefreshDatabase;
use \Tests\TestCase;
class PostControllerTest extends TestCase
{
use RefreshDatabase;
public function test_it_shows_all_the_posts()
{
$posts = \App\Models\Post::factory()->count(5)->create();
$this->get('/posts')
->assertStatus(200)
->assertSee('Posts')
->assertSee($posts[0]->title)
->assertSee($posts[1]->title)
->assertSee($posts[2]->title)
->assertSee($posts[3]->title)
->assertSee($posts[4]->title);
}
}
Um den Test durchzuführen, führen wir den Befehl php artisan test
und wir sollten so etwas wie das hier sehen:
Bei TDD verwenden wir einen Begriff namens "Red-Green-Refactor". Das bedeutet, dass wir einen Test schreiben, der fehlschlägt, dann schreiben wir den Code. Jetzt schreiben wir also den Code, der den Test erfolgreich macht.
Aus der Fehlermeldung können wir ersehen, dass der Test fehlschlägt, weil das Modell Post
gibt es nicht. Lassen Sie es uns also erstellen. Wir erstellen ein neues Modell namens Post
. Wir erstellen auch die migration
, seeder
, factory
, policy
, resource controller
, und Formularanforderungsklassen für die Post
Modell. Und das geht am besten, indem man den Befehl php artisan make:model Post -a
.
Wir werden zwar nicht die policy
so gut entfernen app/Policies/PostPolicy.php
.
Bevor wir weitermachen, fügen wir einige Spalten zur posts
Tabelle über die Migrationsdatei. öffnen die database/migrations/NNNN_NN_NN_NNNNNN_create_posts_table
und ersetzen die up
Methode mit den folgenden:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->longText('content');
$table->string('image')->nullable();
$table->string('status')->default('Draft');
$table->timestamps();
$table->softDeletes();
});
}
Werfen wir nun einen Blick auf die PostFactory.php
Datei. Wir ersetzen die definition
Methode mit den folgenden:
public function definition()
{
return [
'title' => $this->faker->sentence,
'slug' => $this->faker->slug,
'content' => $this->faker->paragraph,
'image' => $this->faker->imageUrl(1920,720, 'cats', true),
'status' => $this->faker->randomElement([
'Draft', 'Publish', 'Unlisted',
]),
];
}
Führen wir den Test nun erneut durch. Wir sollten etwa so etwas sehen.
In Zeile 22 erwarten wir also die Seite mit einer ungeordneten Liste von fünf Beiträgen, aber wir erhalten 404, weil wir die Route für die Seite nicht erstellt haben. posts
dennoch.
Jetzt werden wir den Code schreiben, der den Test erfolgreich macht. Wir bearbeiten unsere routes/web.php
Datei und fügen Sie Folgendes hinzu:
\Illuminate\Support\Facades\Route::resource('posts', \App\Http\Controllers\PostController::class);
jetzt laufen php artisan test
noch einmal und Sie erhalten dies:
Wie Sie sehen, ist der Fehler im vorherigen Screenshot in Zeile 22 aufgetreten, dieses Mal aber in Zeile 23. Sehen wir uns nun an, was in Zeile 23 vor sich geht.
In Zeile 23 stellen wir sicher, dass wir den Text sehen Posts
wenn wir die Seite öffnen, aber wir erhalten nichts. Denn, wenn wir /posts
, ruft es die index
Aktion unserer PostController
Controller-Klasse, und wir haben den Controller noch nicht berührt, nachdem wir unser Modell generiert haben.
So sieht unser Controller aus, wie er von artisan
Befehl:
<?php
namespace App\Http\Controllers;
use \AppHttpRequests\StorePostRequest;
use \App\Http\Requests\UpdatePostRequest;
use \App\Models\Post;
class PostController extends Controller
{
public function index()
{
//
}
public function create()
{
//
}
public function store(StorePostRequest $request)
{
//
}
public function show(Post $post)
{
//
}
public function edit(Post $post)
{
//
}
public function update(UpdatePostRequest $request, Post $post)
{
//
}
public function destroy(Post $post)
{
//
}
}
Konzentrieren wir uns auf die Indexmethode. Im Moment können wir sehen, dass sie nichts tut. Deshalb hat die Antwort des Tests einen leeren String zurückgegeben:
public function index()
{
//
}
Wir wissen, dass beim Laden der Beitragsseite eine Liste der Beiträge angezeigt werden soll. Und so machen wir es:
public function index()
{
$posts = \App\Models\Post::paginate();
return view('posts.index', compact('posts'));
}
Führen wir nun den Test erneut durch. Wir sollten etwa so etwas sehen:
Wir erhalten also eine Fehlermeldung, weil wir keine Ansicht für die posts.index
Seite. Lassen Sie uns diese also erstellen. Wir erstellen eine neue Datei namens index.blade.php
im resources/views/posts
Verzeichnis. Und wir fügen den folgenden Code ein:
@extends('layouts.app')
@section('content')
<div >
<h1 >Posts</h1>
<ul>
@foreach($posts as $post)
<li >
<a
href="{{route('posts.show', $post->id)}}">{{ $post->title }}</a>
</li>
@endforeach
</ul>
</div>
@endsection
Erstellen Sie außerdem eine neue Datei namens app.blade.php
im resources/views/layouts
Verzeichnis. Und fügen Sie den folgenden Code hinzu:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width, initial-scale=1">
<title>Laravel</title>
<script src=https://cdn.tailwindcss.com></script>
<!-- Fonts -->
<link href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Nunito', sans-serif;
}
</style>
</head>
<body >
<div >
<main>
<div>
<h1 ><a href="/posts">My Blog</a></h1>
</div>
<div>
@yield('content')
</div>
</main>
</div>
</body>
</html>
Führen wir nun den Test erneut durch. Wir sollten etwa so etwas sehen:
Lesen Sie auch: Warum ist Laravel das beste PHP-Framework?
Und wir haben einen bestandenen Test. Fügen wir nun einen Test für die show
Aktion. Wir fügen den folgenden Code in die PostTest.php
datei:
public function test_it_shows_a_single_post()
{
$post = \App\Models\Post::factory()
->create(['title' => 'This is a test post']);
$response = $this->get(route('posts.show', $post->id));
$response->assertStatus(200);
$response->assertSee($post->title);
}
Führen Sie den Test erneut durch. Wir sollten etwas wie dies sehen:
Wir erhalten also eine Fehlermeldung, weil wir keine Ansicht für die posts.show
Seite. Lassen Sie uns diese also erstellen. Wir erstellen eine Datei namens show.blade.php
im resources/views/posts
Verzeichnis. Und wir fügen den folgenden Code ein:
@extends('layouts.app')
@section('content')
<div >
<div >
<p>{{$post->created_at->format('M d, Y')}}</p>
<h1 >{{$post->title}}</h1>
</div>
<img src={{$post->image}} alt="{{$post->title}}" />
<div >
{{$post->content}}
</div>
</div>
@endsection
und bearbeiten Sie die PostController.php
und fügen Sie den folgenden Code hinzu:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
Führen wir nun den Test erneut durch. Wir sollten etwa so etwas sehen:
Und wir haben einen weiteren erfolgreichen Test!
Hoffentlich haben Sie jetzt eine Vorstellung davon, wie Sie Tests für Ihre Laravel-Anwendung schreiben können.
Jetzt sind Sie an der Reihe, einige Tests für Ihre Anwendung zu schreiben.
Originalartikel von Junaid Qadir
Quellcode
Hier ist das GitHub-Repositorium für das Projekt: