翻訳者から:「 エリクサーとフェニックスは、最新のウェブ開発がどこに進んでいるかの良い例です。 すでにこれらのツールは、Webアプリケーションのリアルタイムテクノロジーへの質の高いアクセスを提供します。 対話性が向上したサイト、マルチユーザーブラウザーゲーム、マイクロサービスは、これらの技術がうまく機能する分野です。 以下は、Phoenixフレームワークでの開発の詳細な側面を説明する一連の11の記事の翻訳です。ブログエンジンのような些細なことのように思えます。 しかし、急いでつまずかないでください。特に記事がエリクサーに注意を払うか、彼のフォロワーになるように促す場合、それは本当に面白いでしょう。
この部分では、ExMachinaライブラリを含めて、テストプロセスを改善します。 テストしたモデルを作成するために同一のコードをコピーする必要はありません。工場が私たちのためにそれを行います!
現時点では、アプリケーションは以下に基づいています。
- エリクサー :v1.3.1
- フェニックス :v1.2.0
- Ecto:v2.0.2
- コメニン :v2.5.2
はじめに
お気づきのように、このエンジンを作成するプロセスでは、いくつかのライブラリのみを使用します。 次に、ExMachinaと呼ばれる別のものを追加します。 彼女は、RubyのFactory Girlに類似しています。
これは何?
前述のように、ExMachinaは、RubyのFactoryパターン(Thoughtbotのすばらしい人物による)の実装であるFactory Girlのイメージで設計されています。 コードを書き直さずにテストを作成することなく、リレーションシップを持つさまざまなモデルをテストに追加することは素晴らしいことです。 モデルを生成するための単純な関数を含む補助モジュールを使用して、同じことを自分で達成できます。 しかし、それはすべて、必要なデータセットごと、通信ごとなどに、そのようなモジュールを絶えず作成することに帰着します。 これには確かに退屈する時間があります。
降りる
mix.exs
、
mix.exs
ファイルを開いて、
deps
および
application
リストに追加します。 これを行うには、ExMachinaの別のエントリをComeOnInの直後の依存関係のリストに挿入します。
defp deps do [{:phoenix, "~> 1.2.0"}, {:phoenix_pubsub, "~> 1.0"}, {:phoenix_ecto, "~> 3.0"}, {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.6"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.11"}, {:cowboy, "~> 1.0"}, {:comeonin, "~> 2.5.2"}, {:ex_machina, "~> 1.0"}] end
次に、使用されているアプリケーションのリストに
:ex_machina
を追加します。
def application do [mod: {Pxblog, []}, applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext, :phoenix_ecto, :postgrex, :comeonin, :ex_machina]] end
次のコマンドを実行して、アプリケーションコンポーネントの準備ができ、正しく構成されていることを確認します。
$ mix do deps.get, compile
すべてがうまくいけば、ExMachinaのインストールとプロジェクトのコンパイルに関するメッセージが出力に表示されるはずです! コードの変更を開始する前に、
mix test
を実行し、信頼性を高めるために、すべてのテストがグリーンであることを確認する必要があります。
ロールの最初のファクトリーを追加します
ファクトリモジュールを作成し、すべてのテストで使用できるようにする必要があります。 私はテストを膨らませることなくこれを行うことを好みます。 これを行うには、ファクトリを含むモジュールファイルを
test/support
ディレクトリにドロップし、必要なテストでそのインポートを記述します。
それでは、ファイル
test/support/factory.ex
作成することから始めましょう:
defmodule Pxblog.Factory do use ExMachina.Ecto, repo: Pxblog.Repo alias Pxblog.Role alias Pxblog.User alias Pxblog.Post def role_factory do %Role{ name: sequence(:name, &"Test Role #{&1}"), admin: false } end end
このような名前はこのモジュールの本質を反映しているため、これを
Factory
と呼びました。 次に、特別なファクトリー関数を使用します。 これらは、入力に供給されたアトムをサンプルと比較し、 アセンブル / 作成するファクトリのタイプを決定します 。 このライブラリはFactory Girlに非常に近いため、知っておくべき重要な命名規則ももたらします。 最初のそのような名前は
build
です。
build
機能とは、データベースに保存せずにモデル( リビジョンではなく)が
build
ことを意味します。 2番目の規則は、
insert
関数の名前になります。反対に、モデルはデータベースに格納され、それによってモデルが作成されます。
また、ExMachinaがEctoをレポレイヤーとして使用し、モデル、関連付けなどの作成時にそれに応じて動作するように、ExMachina.Ectoの使用を指定
use ExMachina.Ecto
必要があります。 また、ファクトリを作成するすべてのモデルにエイリアスを追加する必要があります。
role_factory
関数は、デフォルトのプロパティを定義する
Role
構造を単に返す必要があります。 この関数は、アリティ1のみをサポートします。
sequence
機能を備えた作品は非常に興味深いものです。 ロールごとに一意の名前を生成する必要があります。 したがって、順次生成されます。 これを行うには、2つの引数を渡す
sequence
関数を使用します。1つ目はシーケンスを生成するフィールドの名前で、2つ目は文字列を返し、その中の値を補間する匿名関数です。 この関数を見てみましょう:
&”Test Role #{&1}”
Elixirに精通している場合は、匿名関数を記述する別の方法を学習している可能性があります。 これはおおよそ次のように変換されます。
fn x -> "Test Role #{x}" end
したがって、
sequence
関数は次のように説明できます。
sequence(:name, fn x -> "Test Role #{x}" end)
最後に、管理フラグを
false
に設定し
false
。 この値をデフォルト条件として使用します。 これを明示的に示すことにより、管理ロールを作成できます。 ExMachinaの他のより高度な機能については、少し後で説明します。 それでは、新しい
Role
ファクトリとコントローラーテストを組み合わせて時間をかけてみましょう。
コントローラテストにロールファクトリを追加する
最初にファイル
test/controllers/user_controller_test.exs
開きます。 上部の
setup
ブロックで、新しい
TestHelper.create_role
関数の使用を追加します。
# ... import Pxblog.Factory @valid_create_attrs %{email: "test@test.com", username: "test", password: "test", password_confirmation: "test"} @valid_attrs %{email: "test@test.com", username: "test"} @invalid_attrs %{} setup do user_role = insert(:role) {:ok, nonadmin_user} = TestHelper.create_user(user_role, %{email: "nonadmin@test.com", username: "nonadmin", password: "test", password_confirmation: "test"}) admin_role = insert(:role, admin: true) {:ok, admin_user} = TestHelper.create_user(admin_role, %{email: "admin@test.com", username: "admin", password: "test", password_confirmation: "test"}) {:ok, conn: build_conn(), admin_role: admin_role, user_role: user_role, nonadmin_user: nonadmin_user, admin_user: admin_user} end # ...
ただし、その前に、ファクトリモジュール自体をインポートします。 10 行目で、
:role
ファクトリを使用してロールを追加します。 13行目でも同じことを行いますが、adminフラグを
true
オーバーライドし
true
。
ファイルを保存して、テストを再開します。 すべてがまだ合格しなければなりません! ここで、ユーザー用のファクトリを作成して、接続を作成します。
ユーザー用のファクトリーを追加する
ユーザー向けの工場をご覧ください。
def user_factory do %User{ username: sequence(:username, &"User #{&1}"), email: "test@test.com", password: "test1234", password_confirmation: "test1234", password_digest: Comeonin.Bcrypt.hashpwsalt("test1234"), role: build(:role) } end
基本的に、このファクトリは、ロールを作成するために以前に記述したものと一致します。 しかし、対処しなければならない落とし穴がいくつかあります。 上記の7行目で 、
password_digest
値を
password_digest
ハッシュ値に設定していることがわかり
password
(ユーザーログインをシミュレートしているため、これも追加する必要があります)。 ComeoninからBcryptモジュールを呼び出し、hashpwsalt関数を使用して、
password
/
password_confirmation
フィールドと同じ値を渡します。 次の行では、
role
を関連付けとして設定します。
build
関数を使用して、アトムの形でアセンブルしたい関連付けの名前を渡します。
ユーザーファクトリを変更したら、ファイル
test/controllers/user_controller_test.exs
に戻りましょう。
setup do user_role = insert(:role) nonadmin_user = insert(:user, role: user_role) admin_role = insert(:role, admin: true) admin_user = insert(:user, role: admin_role) {:ok, conn: build_conn(), admin_role: admin_role, user_role: user_role, nonadmin_user: nonadmin_user, admin_user: admin_user} end
最後に、
TestHelper
へのすべての呼び出しを
TestHelper
への呼び出しに置き換えます。 ロールを取得してファクトリーに転送し、正しいロールを持つユーザーを作成します。 その後、管理者と同じことを行いますが、テストを変更する必要はありません!
それらを実行し、それらがまだ緑色であることを確認します。 続けることができます。
投稿用の工場を追加する
私たちはすでに新しい工場を追加することに取り組んでいると思うので、後者の工場で作業することは問題を引き起こさないはずです。
ここには新しいものはないので、ファイル
test/controllers/post_controller_test.exs
変更してみましょう。
def post_factory do %Post{ title: "Some Post", body: "And the body of some post", user: build(:user) } end
もう一度、
Pxblog.Factory
モジュールを
import
、呼び出しを行っているファクトリーの場所をテストで確認
Pxblog.Factory
します。 次に、
setup
ブロックで投稿を作成するためのすべての手順をファクトリコールに置き換えます。
insert
関数を使用して、
role
構造が作成されます。この構造は、ファクトリを介してユーザーを作成するために使用され、最終的には、それに関連付けられた投稿を作成するために使用されます...
テストを実行します。 彼らは再び緑色になりました!
この場所から、他のすべてはただの余分な仕事です。 戻って、
TestHelper
へのすべての呼び出しを
Factory
呼び出しに置き換えましょう。 これは特に新しいものでも刺激的なものでもないため、詳細の説明にはあまり注意を払いません。
工場を接続する他の方法
工場を各テストに明示的に接続するパスを選択しますが、同じことをしたくない場合は、次のいずれかの方法を使用できます。
ファイル
test/support/model_case.ex
の
using
ブロックにエイリアスを追加します。
using do quote do alias Pxblog.Repo import Ecto import Ecto.Changeset import Ecto.Query import Pxblog.ModelCase import Pxblog.Factory end end
そして、ファイル
test/support/conn_case.ex
:
using do quote do # Import conveniences for testing with connections use Phoenix.ConnTest alias Pxblog.Repo import Ecto import Ecto.Changeset import Ecto.Query import Pxblog.Router.Helpers import Pxblog.Factory # The default endpoint for testing @endpoint Pxblog.Endpoint end end
ExMachinaのその他の機能
小さなブログエンジンの目的のために、ExMachinaが提供する他の機能は必要ありません。 たとえば、
build
と
create
に加えて、利便性のためにいくつかの他の機能のサポートがあり
create
(例として
build
を使用
build
ていますが、これは
create
でも機能し
create
)。
build_pair(:factory, attrs) <- Builds 2 models build_list(n, :factory, attrs) <- Builds N models
build
メソッドを
create
して
create
したモデルを保存するには、
create
メソッドを呼び出し
create
。
build(:role) |> insert
その他の資料
ExMachinaの使用の詳細については、 Githubページをご覧ください 。 また、Thoughtbotの技術ブログにもアクセスできます。このブログでは、クリエイターがExMachinaの優れた発表やその他の使用方法を投稿しています。
まとめると
最初に、私は少し警戒心があり、以前ファクトリーガールの助けを借りていくつかのことを実装した方法を思い出しました。 ここですべてが同じになるのではないかと心配しました。 しかし、Elixirは私たちを自分自身から守ります。これは、テスト時にバランスを見つけるのに役立ちます。 構文は明確でクリーンです。 必要なコードの量が大幅に減少しました。 さらに非常に便利なライブラリを提供してくれた、Thoughtbotの輝かしいスタッフに感謝します。
Wunschからの結論
今日は非常に短い結論です。 エリクサーコミュニティに登録して、毎週ロシア語で興味深い記事を受け取ってください。
シリーズの他の記事
- エントリー
- ログイン
- 役割を追加
- コントローラーで役割を処理します
- ExMachinaを接続します
- マークダウンのサポート
- コメントを追加
- コメントで終了
- チャンネル
- チャネルテスト
- おわりに
研究の成功、私たちと一緒に!