Skip to content

Instantly share code, notes, and snippets.

@dusta
Last active August 21, 2018 10:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dusta/0ffe9b0d1eca8f43d539f76ea6871891 to your computer and use it in GitHub Desktop.
Save dusta/0ffe9b0d1eca8f43d539f76ea6871891 to your computer and use it in GitHub Desktop.
Projekt z użyciem Composer’a i PHPUnit
Sławomir Kaleta - Full Stack Developer w firmie Web24.com.pl sp. z.o.o. Współtwórca wielu projektów open source między innymi silnika templatek SMARTY oraz PHP-SRC interpretera php. Github.com to jego drugi dom.

Jak rozpocząć projekt z użyciem Composera i PHPUnit

Composer

To narzędzie pozwalające na łatwe zarządzanie zależnościami między bibliotekami w projekcie. Tak jak kiedyś pobierało się paczki ze skryptem który był nam potrzebny to composer robi to za nas i jednym poleceniem można je aktualizować.

Composer wprowadza pewne standardy grupy ludzi promujących się pod nazwą PHP-FIG — PHP Framework Interop Group. Więcej przeczytać możecie na php-fig.org. Grupa ta stała się na tyle duża że część programistów zaczęła uznawać i przestrzegać te (nieoficjalne) standardy. Wynikiem tego działa jest bardzo miła spójność kodu u różnych osób. Między innymi standard PSR-4 następca PSR-0 który stosuje Composer. Wszystkie Instrukcje instalacji oraz konfiguracji composera można znaleźć pod adresem Getcomposer.org - Download

PHPunit

Najpopularniejsze narzędzie do wykonywania testów jednostkowych. W zasadzie framework w "wielkim skrócie" który sprawdza, czy nasz wynik jest równy naszym oczekiwaniom.


Projekt

Gdy już przejdziemy proces instalacji musimy mieć jakąś podstawkę dlatego przy użyciu konsoli w naszym katalogu (np. htdocs) uruchamiamy polecenie:

$ composer create-project dframe/dframe-demo justgeek

Rozpocznie to w tym przypadku proces instalacji szkieletu projektu Dframe. Na jego przykładzie przygotujemy własną paczkę, którą będzie można w podobny sposób instalować.

Gdy uruchomione polecenie się zakończy, pojawią się nam pliki w katalogu. Jeśli nie masz np. xampa do uruchomienia Apache2, w konsoli z pomocą php należy wpisać polecenie:

$ php -S localhost:8080 -t web/ server.php

Dzięki temu uruchomi nam to web-server, więcej na ten temat znajdziesz na PHP Manual - webserver. Gdy wszystko zrobimy poprawnie pod adresem http://localhost:8080 znajdziemy nasz projekt.

Composer.json

Teraz przejdzmy do kodu. By wszystko działało poprawnie w musimy mieć załadowany plik vendor/autoload.php. Odpowiada on miedzy innymi za załączenie do naszego projektu odpowiednich bibliotek.

require_once __DIR__ . '/../vendor/autoload.php';

W naszym projekcie jest ona includowana w pliku web/index.php. W folderze projektu znajduje się plik composer.json który jest już uzupełniony jednak dla własnych potrzeb trzeba do zmodyfikować.

{
    "name": "your-vendor-name/package-name",
    "description": "A short description of what your package does",
    "license": "MIT",
    "type": "project",
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    },
    "require": {
        "php": "^7.0",
        "another-vendor/package": "1.*"
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests"
        }
    },
    "require-dev": {
        "phpunit/phpunit": "^6.5"
    }
}

Package Name – Każdą przygotowaną paczkę można umieścić w serwisie packagist.org który zajmuje się jedo dystrybucją
"name": "your-vendor-name/package-name",
Autoload – to standard zajmujący się autoloaderm dzięki któremu możemy cieszyć się prostotą używania narzędzia przedstawionego w tym artykule. Różne rodzaje paczek również znajdziemy na packagist.org
"autoload": {
    "psr-4": {
        "Vendor\\Package\\": "src/"
    }
},

Instalacje paczek można wykonać poprzez konsole. Jeśli w naszej paczce chcielibyśmy użyć np PHPMailer (https://github.com/PHPMailer/PHPMailer) - popularnej biblioteki do obsługi maili. W konsoli wpisujemy:

$ composer require phpmailer/phpmailer

W ten sposób w projekcie możemy już go używać. Dla przykładu w pliku app\Controller\Page.php w metodzie index()

namespace Controller;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

class PageController extends \Controller\Controller
{
    /* ... */
    
    /**
      * Route: http://localhost:8080/page/index
      */
    public function index()
    {
        $mail = new PHPMailer;
        var_dump($mail);
        // https://github.com/PHPMailer/PHPMailer/blob/master/examples/smtp.phps
    }
  /* ... */

Testy jednostkowe

PHPUnit - Instalacja testów nie jest potrzebna na produkcji dlatego w pliku composer.json mamy możliwość instalacji określonych paczek tylko na serwerze testowym.
"autoload-dev": {
    "psr-4": {
        "Vendor\\Package\\": "tests/"
    }
},

W projekcie mamy już zainstalowany PHPUnit, ale gdybyśmy chcieli użyć go w innym projekcie instalacje PHPUnit możemy wykonać za pomocą polecenia.

composer require --dev phpunit/phpunit ^6.5

Ciekawą techniką pisania testów jest TDD (Test-driven development). Składa się on z 3 cykli red, green, refactor. To znaczy najpierw piszemy test w którym oczekujemy ze nasz docelowy skrypt będzie zwracał, potem go piszemy. Na samym końcu poprawiamy jego wydajność i staramy się zoptymalizować.

Poniższa grafika przedstawia ten proces.

W przykładowym zadaniu mamy polecenie, by napisać prosty kalkulator, który będzie zwracał nam wynik.

Rozpoczynamy więc od napisania naszego testu. W naszym projekcie mamy folder app/Tests/ z reguły powinien się znajdować poza folderem app jednak w tym przypadku mamy wyjątek. W podanym powyżej folderze stwórzmy plik o nazwie MyTest.php dla PHPUnit ważne jest by w nazwie była końcówka ...Test.php.

namespace Tests;

class MyTest extends TestCase
{
    public function testFistTest()
    {
         $this->myLib = new \Libs\MyLib();
         $sum = $this->myLib->add(2, 2);
         $this->assertEquals($sum, 4);
    }
}

W powyższy oto sposób napisaliśmy test dla skryptu, który jeszcze nieistnienie i po uruchomieniu w konsoli poniższego polecenia powinniśmy otrzymać negatywny jego wynik.

$ vendor/bin/phpunit

Red - Test mamy gotowy i jak i jego wynik jest prawidłowy, gdyż pierwszy test nigdy nie może się udać z uwagi na brak danej klasy. Skoro go jej nie mamy to czas ją napisać.

Stwórzmy plik app/Libs/MyLib.php

namespace Libs;

class MyLib
{
    public function add($first, $second){
        return $first+$second;
    }
}

Teraz ponownie uruchamiamy polecenie

$ vendor/bin/phpunit

Green - I po zakończeniu powinniśmy uzyskać pozytywny wynik.

Refactory - W kolejnym kroku można byłoby poprawić kod, dodając walidacje wprowadzanych wartości.

Podsumowanie

Testy są bardzo ważne, wiele osób tego nie docenia, ale w dłuższym czasie naprawdę się sprawdzają. Potrafią zaoszczędzić sporo nerwów i czasu w przyszłości. Jeśli pracujesz i firmie nie ma jeszcze testów to warto zarzucić pomysł. Podstawowych testów można nauczyć się w kilka godzin. Nie trzeba pisać od razu testów do wszystkiego, można je wdrażać z czasem. Jeśli spotkasz się z wymówką, że brak na to funduszy to pomyśl, ile czasu się poświęca na CodeReview.

Bibliografia

https://getcomposer.org/doc/
https://dframeframework.com/en/docs/dframe/master/installation/overview
https://cheesecakelabs.com/blog/tdd-mobile-dev-matter-timing/
http://www.jamesshore.com/Blog/Red-Green-Refactor.html
https://pl.wikipedia.org/wiki/Test-driven_development
http://agiledata.org/essays/tdd.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment