Sprache:

Suche

Testen: Wie schreibt man eigentlich Tests?

  • Teilen:
Testen: Wie schreibt man eigentlich Tests?

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: indexshowcreatestoreeditupdatedelete. 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:

img.png

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 migrationseederfactorypolicyresource 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.

img_1.png

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:

img_2.png

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:

img_3.png

img_4.png

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:

img_5.png

 

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:

img_6.png

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:

img_7.png

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:

https://github.com/JunaidQadirB/how-to-actually-write-tests

TWT Staff

TWT Staff

Writes about Programming, tech news, discuss programming topics for web developers (and Web designers), and talks about SEO tools and techniques