LoginSignup
14
12

More than 5 years have passed since last update.

Laravel & Masonite TDD徹底比較(前編)

Last updated at Posted at 2019-03-03

さて、3月もやってきました。毎月1本Masoniteの記事です。
今回のテーマは、LaravelとMasoniteで全く同じ処理をTDDで作って比較してみよう!です。作るものについては簡単に、ログイン画面だけ作ってみようと思います。
ほとんど同じアーキテクチャを持つフレームワークを、ただ言語がPHPとPythonで違うだけで、どれだけ違いがあるのか、またどれほど同じなのか。じっくり見ていきたいと思います。

Masoniteとはなんぞや?とお思いの方は、まずはこちらの記事を読んでいただければ幸いです。
LaravelそっくりなPython製WebフレームワークMasoniteの紹介

また、TDD(テスト駆動開発)についてご存じない方は、こちらを見ていただければいいと思います。
テスト駆動開発
50 分でわかるテスト駆動開発

ではさっそく、それぞれの言語のインストールから。

インストール

anyenvのインストール

複数の言語を1台のPCにインストールするので、anyenvを入れてからphpenv、pyenvを使ってそれぞれの言語をインストールしてみようと思います。

git clone https://github.com/riywo/anyenv ~/.anyenv  
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile  
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile  
anyenv install --init
exec $SHELL -l

PHP、Pythonのインストール

phpenv、pyenvをインストールします

anyenv install phpenv pyenv

そしてphpenv、pyenvでそれぞれ最新版を検索し、インストールします

mkdir php
cd php
phpenv install -l #インストールできるバージョン一覧を表示
phpenv install 7.3.2
phpenv local 7.3.2
php --version

PHP 7.3.2 (cli) (built: Mar  3 2019 02:51:55) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.2, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.7.0rc1, Copyright (c) 2002-2019, by Derick Rethans
mkdir python
cd python
pyenv install -l #インストールできるバージョン一覧を表示
pyenv install 3.7.2
pyenv local 3.7.2
python -V

Python 3.7.2

現在のディレクトリ構造はこのようになっています

.
├── php
│   └── .php-version
└── python
    └── .python-version

プロジェクト作成

Laravel

まず、phpのパッケージ管理ソフトであるcomposerをインストールします。

apt install -y composer
composer #確認

Download composer.phar ...
All settings correct for using Composer
Downloading...

Composer (version 1.8.4) successfully installed to: /tmp/composer.phar
Use it: php /tmp/composer.phar

Move composer.phar to /home/user/.anyenv/envs/phpenv/versions/7.3.2/composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.8.4 2019-02-11 10:52:10

phpディレクトリ内でComposerを使用しLaravelインストーラをダウンロードして、laravelコマンドを使ってprojectという名前のプロジェクトを作ります。

composer global require laravel/installer
laravel new project

Masonite

pythonディレクトリ内でvenvを作り、pipを使用しmasonite-cliをダウンロードして、craftコマンドを使ってprojectという名前のプロジェクトを作ります。

python -m venv .venv #venvを作る
source .venv/bin/activate #venvを有効化
pip install masonite-cli #Masoniteをインストール
craft new project #projectという名前でMasoniteプロジェクト作成
cd project/
craft install #Masoniteの依存パッケージ類をインストール

LaravelとMasoniteがインストールできたら、それぞれ組み込みサーバーを立ち上げて、ブラウザからアクセスしてみましょう。Laravelは8001番ポート、Masoniteは8002番ポートを使うことにします。
それぞれphp/projectディレクトリ、python/projectディレクトリでコマンドを実行します。

php/project.
php artisan serve --port 8001
python/project.
craft serve -p 8002

Screenshot from 2019-03-03 17-12-51.jpg

さぁ、TDDを始めるぞ

ログイン画面を作る

/loginにアクセスした時に表示される、ログイン画面を作りましょう。

テスト

まずは、ユニットテストを作ります。Laravelではコマンドでテストが作れるのですが、Masoniteではまだテストを作るコマンドは用意されていません。

Laravel
php/project.
php artisan make:test LoginTest --unit

php/project/tests/Unit/LoginTest.phpが自動生成されました。phpunitコマンドを使ってテストを実行してみましょう。

php/project.
vendor/bin/phpunit tests/Unit/LoginTest.php

現在は$this->assertTrue(true);しかテストに書かれていないので、成功すると思います。/loginにアクセスした時にアクセスできるというテストを書いてみましょう。

php/project/tests/Unit/LoginTest.php
class LoginTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     */
    public function test_loginにアクセスした時にアクセスできる()
    {
        $response = $this->get('/login')->assertStatus(200);
    }
}

ここで再度テストを実行すると、まだルーティングを作っていないので、期待通り失敗します。

Masonite

ではMasoniteでもテストを作っていきます。

python/project/tests/unit/test_login.py
from masonite.testing.UnitTest import UnitTest

class TestLogin(UnitTest):
    def test_example(self):
        assert True

テストを動かしてみましょう。

python/project.
python -m pytest tests/unit/test_login.py

現在はassert Trueしかテストに書かれていないので、成功すると思います。/loginにアクセスした時にアクセスできるというテストを書いてみましょう。

python/project/tests/unit/test_login.py
from masonite.testing.UnitTest import UnitTest

class TestLogin(UnitTest):
    def test_loginにアクセスした時にアクセスできる(self):
        assert self.route('/login')

ここで再度テストを実行すると、まだルーティングを作っていないので、期待通り失敗します。

では、/loginにアクセスすると、LoginControllerのindexメソッドが呼ばれて、loginビューが表示される、という処理を作っていきます。

ビューを作る

Laravel

まず、ビューを作ります。LaravelのテンプレートエンジンであるBladeには、テンプレートの継承と言って、ビューの中にビューを埋め込むという処理ができます。これによって、jsやcssのインポート処理、ヘッダーやフッターの定義などは一箇所で済ませることができます。
Laravelにはビューを作るコマンドは無いので、手動でファイルを作ります。

php/project/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@yield('title')</title>
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
  </head>
  <body>
    <div id="content">
      @yield('content')
    </div>
  </body>
</html>
php/project/resources/views/login.blade.php
@extends('layouts.app')

@section('title', 'ログイン')

@section('content')
  <p>Laravelログイン画面</p>
@endsection
Masonite

LaravelのBladeと同じく、Masoniteが採用しているテンプレートエンジンであるJinja2も、継承を使ったテンプレートの埋め込みが使えます。
Laravelの時と同じくlayouts/appとloginを作ります。Masoniteはコマンドでビューが作れます。

python/project.
craft view layouts/app
craft view login

python/project/resources/templates/layouts/app.html
python/project/resources/templates/login.html
が自動生成されました。ここにHTMLを書いていきます。

python/project/resources/templates/layouts/app.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{% block title %}{% endblock %}</title>
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
  </head>
  <body>
    <div id="content">
      {% block content %}{% endblock %}
    </div>
  </body>
</html>
python/project/resources/templates/login.html
{% extends "layouts/app.html" %}

{% block title %}ログイン{% endblock %}

{% block content %}
  <p>Masoniteログイン画面</p>
{% endblock %}

コントローラーを作る

Laravel

コマンドでコントローラーを作ります

php/project.
php artisan make:controller LoginController

indexメソッドを作り、login.blade.phpを返す処理を書きます。

php/project/app/Http/Controllers/LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class LoginController extends Controller
{
    public function index(){
        return view('login');
    }
}
Masonite

コマンドでコントローラーを作ります

python/project.
craft controller Login

indexメソッドを作り、login.htmlを返す処理を書きます。

python/project/app/http/controllers/LoginController.py
""" A LoginController Module """

class LoginController:
    """LoginController
    """

    def index(self):
        return view('login.html')

ルーティングを張る

Laravel

php/project/routes/web.phpに、/loginにgetでアクセスされたらLoginコントローラーのindexメソッドを呼び出す処理を書きます。

php/project/routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/login', 'LoginController@index'); //←追加
Masonite

python/project/routes/web.pyに、/loginにgetでアクセスされたらLoginコントローラーのindexメソッドを呼び出す処理を書きます。

python/project/routes/web.py
"""Web Routes."""

from masonite.routes import Get, Post
from masonite.helpers.routes import get #←追加

ROUTES = [
    Get().route('/', 'WelcomeController@show').name('welcome'),
    get('/login', 'LoginController@index') #←追加
]

テスト

ではここで再度テストを実行してみましょう。

php/project.
vendor/bin/phpunit tests/Unit/LoginTest.php
python/project.
python -m pytest tests/unit/test_login.py

ルーティング、コントローラー、ビューの一連の処理を書いたために、テストが成功すると思います。

php/project.
PHPUnit 7.5.6 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 199 ms, Memory: 16.00 MB

OK (1 test, 1 assertion)
python/project.
================================ test session starts ================================
platform linux -- Python 3.7.2, pytest-3.10.1, py-1.8.0, pluggy-0.9.0
rootdir: /to/your/dir/python/project, inifile:
collected 1 item                                                                    

tests/unit/test_login.py .                                                    [100%]
======================= 1 passed, 0 warnings in 0.37 seconds ========================

また、組み込みサーバーを起動して/loginにアクセスすると、正しくアクセスできるようになっているでしょう。

php/project.
php artisan serve --port 8001
python/project.
craft serve -r -p 8002

Screenshot from 2019-03-03 21-52-12.jpg

まとめ

今回はLaravelとMasoniteについて、インストール、テスト、ビュー、テンプレートエンジン、コントローラー、ルーティングについて比較しました。テストにおける若干の違いは否めませんが、大きな違いはまだ無いように思えます。
後編ではマイグレーション、モデル、ORM、バリデーションについてもTDDをベースに比較してみたいと思います。好ご期待!

14
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12