Test::Mojo

Yuki Kimoto edited this page Apr 8, 2015 · 10 revisions

Mojolicious API リファレンス

名前

Test::Mojo - Mojoの試験

使い方

use Test::More;
use Test::Mojo;

my $t = Test::Mojo->new('MyApp');

# HTML/XML
$t->get_ok('/welcome')->status_is(200)->text_is('div#message' => 'Hello!');

# JSON
$t->post_ok('/search.json' => form => {q => 'Perl'})
  ->status_is(200)
  ->header_is('Server' => 'Mojolicious (Perl)')
  ->header_isnt('X-Bender' => 'Bite my shiny metal ass!')
  ->json_is('/results/4/title' => 'Perl rocks!');

# WebSocket
$t->websocket_ok('/echo')
  ->send_ok('hello')
  ->message_ok
  ->message_is('echo: hello')
  ->finish_ok;

done_testing();

説明

Test::Mojo は、MojoMojolicious アプリケーションを開発する すべての人への、テストのためのヘルパーの集まりです。

Test::MojoMojo::UserAgentに基づいたテストのためのユーザーエージェントです。 通常は、Mojoliciousアプリケーションをテストするために、Test::Moreと 一緒に利用されます。 Mojolicious::Command::testコマンドかproveを使って、 テストを実行することができます。

$ ./script/my_app test
$ ./script/my_app test -v t/foo.t
$ prove -l -v t/foo.t

まだ定義されていなかった場合は、 MOJO_LOG_LEVEL環境変数は HARNESS_IS_VERBOSE環境変数の値に応じて、 debugfatalに設定されます。

属性

Test::Mojoは次の属性を実装しています。

message

my $msg = $t->message;
$t      = $t->message([text => $bytes]);

フレームとペイロードを含んだ 配列のリファレンスとして表現された現在のWebSocketメッセージ。

# もっと仕様の試験をする
use Mojo::JSON 'decode_json';
my $hash = decode_json $t->message->[1];
is ref $hash, 'HASH', 'right reference';
is $hash->{foo}, 'bar', 'right value';

# カスタムメッセージのテスト
$t->message([binary => $bytes])
  ->json_message_has('/foo/bar')
  ->json_message_hasnt('/bar')
  ->json_message_is('/foo/baz' => {yada => [1, 2, 3]});

success

my $bool = $t->success;
$t       = $t->success($bool);

最後のテストが成功すれば真。

# Build custom tests
my $location_is = sub {
  my ($t, $value, $desc) = @_;
  $desc ||= "Location: $value";
  local $Test::Builder::Level = $Test::Builder::Level + 1;
  return $t->success(is($t->tx->res->headers->location, $value, $desc));
};
$t->get_ok('/')
  ->status_is(302)
  ->$location_is('http://mojolicio.us')
  ->or(sub { diag 'Must have been Joel!' });

tx

my $tx = $t->tx;
$t     = $t->tx(Mojo::Transaction::HTTP->new);

現在のトランザクション。 通常は Mojo::Transaction::HTTPまたはMojo::Transaction::WebSocket オブジェクトです。

# よりスペシフィックな試験
is $t->tx->res->json->{foo}, 'bar', 'right value';
ok $t->tx->res->is_multipart, 'multipart content';

# カスタムトランザクションを試験
$t->tx($t->tx->previous)->status_is(302)->header_like(Location => qr/foo/);

ua

my $ua = $t->ua;
$t     = $t->ua(Mojo::UserAgent->new);

テストのために利用されるユーザーエージェント。 デフォルトはMojo::UserAgentオブジェクトです。

# リダイレクトを許可
$t->ua->max_redirects(10);

# ベーシック認証のリクエストに絶対URLを使う
my $url = $t->ua->server->url->userinfo('sri:secr3t')->path('/secrets.json');
$t->post_ok($url => json => {limit => 10})
  ->status_is(200)
  ->json_is('/1/content', 'Mojo rocks!');

# すべてのトランザクションをカスタマイズ (続くリダイレクトを含む)
$t->ua->on(start => sub {
  my ($ua, $tx) = @_;
  $tx->req->headers->accept_language('en-US');
});

メソッド

Test::MojoMojo::Baseのすべてのメソッドを継承しており、 次の新しいメソッドを実装しています。

app

my $app = $t->app;
$t      = $t->app(Mojolicious->new);

Mojo::UserAgent::Serverappにアクセスします。

# ログレベルの変更
$t->app->log->level('fatal');

# アプリケーションを直接試験する
is $t->app->defaults->{foo}, 'bar', 'right value';
ok $t->app->routes->find('echo')->is_websocket, 'WebSocket route';
my $c = $t->app->build_controller;
ok $c->render(template => 'foo'), 'rendering was successful';
is $c->res->status, 200, 'right status';
is $c->res->body, 'Foo!', 'right content';

# アプリケーションの動きを変更
$t->app->hook(before_dispatch => sub {
  my $c = shift;
  $c->render(text => 'This request did not reach the router.')
    if $c->req->url->path->contains('/user');
});

# 追加の情報を抽出
my $stash;
$t->app->hook(after_dispatch => sub { $stash = shift->stash });

content_is

$t = $t->content_is('working!');
$t = $t->content_is('working!', 'right content!');

Mojo::Messagetextからコンテンツを取得した後に、 レスポンスのコンテンツが完全に一致するかをチェックします。

content_isnt

$t = $t->content_isnt('working!');
$t = $t->content_isnt('working!', 'different content');

content_isの否定です。

content_like

$t = $t->content_like(qr/working!/);
$t = $t->content_like(qr/working!/, 'right content!');

Mojo::Messagetextからコンテンツを取得した後に、 レスポンスが類似マッチするかどうかをチェックします。

content_unlike

$t = $t->content_unlike(qr/working!/);
$t = $t->content_unlike(qr/working!/, 'different content');

content_likeの否定です。

content_type_is

$t = $t->content_type_is('text/html');

レスポンスの Content-Type ヘッダが完全に一致するかをチェックします。

content_type_isnt

$t = $t->content_type_isnt('text/html');

content_type_isの否定です。

content_type_like

$t = $t->content_type_like(qr/text/);
$t = $t->content_type_like(qr/text/, 'right content type!');

レスポンスの Content-Type ヘッダが類似マッチするかどうかをチェックします。

content_type_unlike

$t = $t->content_type_unlike(qr/text/);
$t = $t->content_type_unlike(qr/text/, 'different content type');

content_type_likeの否定です。

delete_ok

$t = $t->delete_ok('/foo');
$t = $t->delete_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->delete_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->delete_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

DELETE リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentdeleteと同じ引数を受け取ります。

element_exists

$t = $t->element_exists('div.foo[x=y]');
$t = $t->element_exists('html head title', 'has a title');

Mojo::DOMatを使って、CSS3 セレクタと最初にマッチする XML/HTML 要素が 存在するかをチェックします。

# 属性値のチェック
$t->get_ok('/login')
  ->element_exists('label[for=email]')
  ->element_exists('input[name=email][type=text][value*="example.com"]')
  ->element_exists('label[for=pass]')
  ->element_exists('input[name=pass][type=password]')
  ->element_exists('input[type=submit][value]');

element_exists_not

$t = $t->element_exists_not('div.foo[x=y]');
$t = $t->element_exists_not('html head title', 'has no title');

element_existsの否定です。

finish_ok

$t = $t->finish_ok;
$t = $t->finish_ok(1000);
$t = $t->finish_ok(1003 => 'Cannot accept data!');

WebSocket接続が終了しているか。

get_ok

$t = $t->get_ok('/foo');
$t = $t->get_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->get_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->get_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

GET リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentgetと同じ引数を受け取ります。

# リモートホストに対して、試験を実行
$t->get_ok('http://mojolicio.us/perldoc')->status_is(200);

# ベーシック認証においてリクエストのために相対URLを使用する
$t->get_ok('//sri:secr3t@/secrets.json')
  ->status_is(200)
  ->json_is('/1/content', 'Mojo rocks!');

# トランザクションの追加の試験をする
$t->get_ok('/foo')->status_is(200);
is $t->tx->res->dom->at('input')->{value}, 'whatever', 'right value';

head_ok

$t = $t->head_ok('/foo');
$t = $t->head_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->head_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->head_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

HEAD リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentheadと同じ引数を受け取ります。

header_is

$t = $t->header_is(ETag => '"abc321"');
$t = $t->header_is(ETag => '"abc321"', 'right header');

レスポンスヘッダが完全に一致するかどうかをチェックします。

header_isnt

$t = $t->header_isnt(Etag => '"abc321"');
$t = $t->header_isnt(ETag => '"abc321"', 'different header');

header_isの否定です。

header_like

$t = $t->header_like(ETag => qr/abc/);
$t = $t->header_like(ETag => qr/abc/, 'right header');

レスポンスヘッダが類似マッチするかどうかをチェックします。

header_unlike

$t = $t->header_unlike(ETag => qr/abc/);
$t = $t->header_unlike(ETag => qr/abc/, 'different header');

header_likeの否定です。

json_content_is

$t = $t->json_content_is([1, 2, 3]);
$t = $t->json_content_is([1, 2, 3], 'right content!');

JSONデータであるレスポンスのコンテンツをチェックします。

json_has

$t = $t->json_has('/foo');
$t = $t->json_has('/minibar', 'has a minibar');

Mojo::JSON::Pointerで与えられたJSONポインターを使って、 JSONレスポンスに識別される値が含まれているかどうかをチェックします。

json_hasnt

$t = $t->json_hasnt('/foo');
$t = $t->json_hasnt('/minibar', 'no minibar');

json_hasの否定。

json_is

$t = $t->json_is({foo => [1, 2, 3]});
$t = $t->json_is('/foo' => [1, 2, 3]);
$t = $t->json_is('/foo/1' => 2, 'right value');

Mojo::JSON::Pointerで与えられたJSONポインタを使って、 JSONレスポンスから抽出された値をチェックします。 JSONポインタが省略された場合は、ルート(/)になります。

json_like

$t = $t->json_like('/foo/1' => qr/^\d+$/);
$t = $t->json_like('/foo/1' => qr/^\d+$/, 'right value');

Mojo::JSON::Pointerで 与えられたJSONポインタを使って、 JSONレスポンスから抽出された値を、類似チェックします。

json_message_has

$t = $t->json_message_has('/foo');
$t = $t->json_message_has('/minibar', 'has a minibar');

Mojo::JSON::Pointerによって与えられたJSONポインタをを使って、識別される値がJSON WebSocketメッセージに含まれているかどうかをチェックします。

json_message_hasnt

$t = $t->json_message_hasnt('/foo');
$t = $t->json_message_hasnt('/minibar', 'no minibar');

json_message_hasの否定。

json_message_like

$t = $t->json_message_like('/foo/1' => qr/^\d+$/);
$t = $t->json_message_like('/foo/1' => qr/^\d+$/, 'right value');

Mojo::JSON::Pointerによって 与えられたJSONポインタを使用して、 JSON WebSocketメッセージから抽出された値の類似チェックします。

json_message_unlike

$t = $t->json_message_unlike('/foo/1' => qr/^\d+$/);
$t = $t->json_message_unlike('/foo/1' => qr/^\d+$/, 'different value');

json_message_likeの反対。

json_unlike

$t = $t->json_unlike('/foo/1' => qr/^\d+$/);
$t = $t->json_unlike('/foo/1' => qr/^\d+$/, 'different value');

json_likeの反対。

json_message_is

$t = $t->json_message_is({foo => [1, 2, 3]});
$t = $t->json_message_is('/foo' => [1, 2, 3]);
$t = $t->json_message_is('/foo/1' => 2, 'right value');

Mojo::JSON::Pointerによって与えられたJSONポインタをを使って、 JSON WebSocketメッセージから抽出された値をチェックします。 JSONポインタが省略された場合は、ルート(/)になります。

message_is

$t = $t->message_is({binary => $bytes});
$t = $t->message_is({text   => $bytes});
$t = $t->message_is('working!');
$t = $t->message_is('working!', 'right message');

WebSocketメッセージが完全に一致するかをチェックします。

message_isnt

$t = $t->message_isnt({binary => $bytes});
$t = $t->message_isnt({text   => $bytes});
$t = $t->message_isnt('working!');
$t = $t->message_isnt('working!', 'different message');

message_isの否定。

message_like

$t = $t->message_like({binary => qr/$bytes/});
$t = $t->message_like({text   => qr/$bytes/});
$t = $t->message_like(qr/working!/);
$t = $t->message_like(qr/working!/, 'right message');

WebSocketメッセージが類似マッチするかどうかをチェックします。

message_ok

$t = $t->message_ok;
$t = $t->message_ok('got a message');

次のWebSocketメッセージが到着するのを待ちます。

# メッセージを待って、複数の試験を実行する
$t->websocket_ok('/time')
  ->message_ok
  ->message_like(qr/\d+/)
  ->message_unlike(qr/\w+/)
  ->finish_ok;

message_unlike

$t = $t->message_unlike({binary => qr/$bytes/});
$t = $t->message_unlike({text   => qr/$bytes/});
$t = $t->message_unlike(qr/working!/);
$t = $t->message_unlike(qr/working!/, 'different message');

message_likeの否定。

new

my $t = Test::Mojo->new;
my $t = Test::Mojo->new('MyApp');
my $t = Test::Mojo->new(MyApp->new);

新しい[Test::Mojo]]オブジェクトを生成します。

options_ok

$t = $t->options_ok('/foo');
$t = $t->options_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->options_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->options_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

OPTIONS リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentoptionsとまったく同じ引数を受け取ります。

or

$t = $t->or(sub {...});

successの値が偽であれば、コールバックを実行します。

# 詳細を出力
$t->get_ok('/bad')->or(sub { diag 'Must have been Glen!' })
  ->status_is(200)->or(sub { diag $t->tx->res->dom->at('title')->text });

patch_ok

$t = $t->patch_ok('/foo');
$t = $t->patch_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->patch_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->patch_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

PATCH リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentpatchとまったく同じ引数を受け取ります。

post_ok

$t = $t->post_ok('/foo');
$t = $t->post_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->post_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->post_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

POST リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentpostとまったく同じ引数を受け取ります。

post_form_ok

$t = $t->post_form_ok('/foo' => {a => 'b'});
$t = $t->post_form_ok('/foo' => 'UTF-8' => {a => 'b'} => {DNT => 1});

POST フォームを送信し、成功するかどうかをチェックします。 Mojo::UserAgentpost_formとまったく同じ引数を受け取ります。

# ファイルアップロードの試験
my $upload = {foo => {content => 'bar', filename => 'baz.txt'}};
$t->post_ok('/upload' => form => $upload)->status_is(200);

# JSON APIの試験
$t->post_json_ok('/hello.json' => json => {hello => 'world'})
  ->status_is(200)
  ->json_is({bye => 'world'});

put_ok

$t = $t->put_ok('/foo');
$t = $t->put_ok('/foo' => {Accept => '*/*'} => 'Hi!');
$t = $t->put_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->put_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});

PUT リクエストを実行し、成功するかどうかをチェックします。 Mojo::UserAgentputとまったく同じ引数を受け取ります。

request_ok

$t = $t->request_ok(Mojo::Transaction::HTTP->new);
$t = $t->request_ok(Mojo::Transaction::HTTP->new, 'request successful');

リクエストを実行し、透過的なエラーのためのチェックを行います。

# カスタムメソッドによるリクエスト
my $tx = $t->ua->build_tx(FOO => '/test.json' => json => {foo => 1});
$t->request_ok($tx)->status_is(200)->json_is({success => 1});

# カスタムクッキーでリクエスト
my $tx = $t->ua->build_tx(GET => '/account');
$tx->req->cookies({name => 'user', value => 'sri'});
$t->request_ok($tx)->status_is(200)->text_is('head > title' => 'Hello sri');

# カスタムWebSocketハンドシェイク
my $tx = $t->ua->build_websocket_tx('/foo');
$tx->req->headers->remove('User-Agent');
$t->request_ok($tx)->message_ok->message_is('bar')->finish_ok;

reset_session

$t = $t->reset_session;

ユーザーエージェントのセッションをリセットします。

send_ok

$t = $t->send_ok({binary => $bytes});
$t = $t->send_ok({text   => $bytes});
$t = $t->send_ok({json   => {test => [1, 2, 3]}});
$t = $t->send_ok([$fin, $rsv1, $rsv2, $rsv3, $op, $payload]);
$t = $t->send_ok($chars);
$t = $t->send_ok($chars, 'sent successfully');

WebSocketメッセージあるいはフレームを送信します。

# JSONオブジェクトをテキストメッセージとして送信
$t->websocket_ok('/echo.json')
  ->send_ok({json => {test => 'I ♥ Mojolicious!'}})
  ->message_ok
  ->json_message_is('/test' => 'I ♥ Mojolicious!')
  ->finish_ok;

status_is

$t = $t->status_is(200);
$t = $t->status_is(200, 'right status');

レスポンスのステータスが完全に一致するかをチェックします。

status_isnt

$t = $t->status_isnt(200);
$t = $t->status_isnt(200, 'different status');

status_isの否定です。

text_is

$t = $t->text_is('div.foo[x=y]' => 'Hello!');
$t = $t->text_is('html head title' => 'Hello!', 'right title');

Mojo::DOMatを使って、CSS3 セレクタと最初にマッチする XML/HTML 要素の テキスト内容が完全に一致するかどうかをチェックします。

text_isnt

$t = $t->text_isnt('div.foo[x=y]' => 'Hello!');
$t = $t->text_isnt('html head title' => 'Hello!', 'different title');

text_isの否定です。

text_like

$t = $t->text_like('div.foo[x=y]' => qr/Hello/);
$t = $t->text_like('html head title' => qr/Hello/, 'right title');

Mojo::DOMatを使って、CSS3 セレクタと最初にマッチする XML/HTML 要素の テキスト内容が類似マッチするかどうかをチェックします。

text_unlike

$t = $t->text_unlike('div.foo[x=y]' => qr/Hello/);
$t = $t->text_unlike('html head title' => qr/Hello/, 'different title');

text_likeの否定です。

websocket_ok

$t = $t->websocket_ok('/echo');
$t = $t->websocket_ok('/echo' => {DNT => 1} => ['v1.proto']);

透過的なハンドシェイクでWebSocket接続がオープンするかをチェックします。 Mojo::UserAgentwebsocketとまったく同じ引数を受け取ります。

# permessage-deflate圧縮のついたWebSocket
$t->websocket_ok('/' => {'Sec-WebSocket-Extensions' => 'permessage-deflate'})
  ->send_ok('y' x 50000)
  ->message_ok
  ->message_is('z' x 50000)
  ->finish_ok;

参考

Mojolicious, Mojolicious::Guides, http://mojolicio.us.

(Mojolicious 6.05を更新)

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.