模块:测试::莫霍
起源:Mojo::基础

名称

测试::Mojo-测试Mojo

简介

使用测试::更多;使用测试::Mojo;my$t=测试::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'})->状态_ is(200)->header_is('Server'=>'Mojolicious(Perl)')->header_isnt('X-Bender'=>'咬我闪亮的金属屁股!')->json_is('/results/4/title'=>“Perl摇滚乐!”)->json_like('/results/7/title'=>qr/Perl/);#WebSocket$t->websocket_ok('/echo')->send_ok(“你好”)->消息_ok->message_is('echo:hello')->finish_ok;done_testing();

描述

测试::Mojo是基于的测试用户代理Mojo::用户代理,通常与一起使用测试::更多进行测试Mojolicious公司应用程序。只需使用运行测试证明.

$证明-l-v$prove-l-v t/foo。t吨

如果尚未定义,则MOJO_LOG_级别环境变量将设置为追踪致命的,取决于线束_IS_传感器环境变量。为了更容易测试HTTPS/WSS web服务Mojo::UserAgent中的“不安全”默认情况下将为激活“ua”.

请参见Mojolicious::指南::测试了解更多信息。

属性

测试::Mojo实现以下属性。

处理程序

我的$cb=$t->处理程序;$t=$t->处理程序(子{…});

用于连接的回调测试::Mojo具有测试::更多.

$t->处理程序(子($name,@args){return测试::更多->can($name)->(@args);});

消息

我的$msg=$t->消息;$t=$t->消息([文本=>$bytes]);

当前WebSocket消息表示为包含帧类型和负载的数组引用。

#更具体的测试使用Mojo::JSON qw(decode_JSON);我的$hash=解码json$t->message->[1];是ref$hash,'hash','right-reference';是$hash->{foo},“bar”,“right value”;#测试自定义消息$t->消息([二进制=>$bytes])->json消息具有('/foo/bar')->json消息hasnt('/bar')->json消息is('/foo/baz'=>{yada=>[1,2,3]});

成功

我的$bool=$t->成功;$t=$t->成功($bool);

如果上次测试成功,则为True。

#生成自定义测试my$location_is=sub($t,$value,$desc=''){$desc||=“位置:$value”;本地$Test::Builder::Level=$Test:;return$t->success(is($t->tx->res->headers->location,$value,$desc));};$t->get_ok('/')->状态(302)->$location_is('https://mojolicious.org')->或(子{diag“一定是Joel!”});

tx公司

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

当前交易,通常是Mojo::Transaction::HTTPMojo::Transaction::WebSocket对象。

#更具体的测试是$t->tx->res->json->{foo},“bar”,“right value”;ok$t->tx->res->content->is-multipart,“多部分内容”;是$t->tx->previous->res->code,302,“正确状态”;

ua公司

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

用于测试的用户代理,默认为Mojo::用户代理对象。

#允许重定向$t->ua->max_redirects(10);$t->get_ok('/redirect')->status_is(200)->content_like(qr/redirected/);#将协议从HTTP切换到HTTPS$t->ua->server->url(“https”);$t->get_ok('/secure')->status_is(200)->content_like(qr/secure/);#对具有基本身份验证的请求使用绝对URL我的$url=$t->ua->server->url->userinfo('sri:secr3t')->path('/secrets.json');$t->post_ok($url=>json=>{limit=>10})->状态_ is(200)->json_is('/1/content','Mojo rocks!');#自定义所有事务(包括后续重定向)$t->ua->打开(开始=>sub($ua,$tx){$tx->req->headers->accept_language('en-US')});$t->get_ok('/hello')->status_is(200)->content_like(qr/Howdy/);

方法

测试::Mojo从继承所有方法Mojo::基础并实现了以下新功能。

应用程序

我的$app=$t->app;$t=$t->app(Mojolicios->new);

使用访问应用程序Mojo::UserAgent::Server中的“app”.

#更改日志级别$t->app->log->level(“致命”);#直接测试应用程序是$t->app->defaults->{foo},“bar”,“right value”;ok$t->app->routes->find('echo')->is_websocket,'websocket route';我的$c=$t->app->buildcontroller;ok$c->render(template=>'foo'),'渲染成功';是$c->res->status,200,“正确状态”;是$c->res->body,'Foo!','正确的内容';#更改应用程序行为$t->app->hook(before_dispatch=>sub($c)){如果$c->req->url->path->contains(“/user”);});$t->get_ok('/user')->status_is(200)->content_like(qr/not reach the router/);#提取其他信息我的$stash;$t->app->hook(after_dispatch=>sub($c){$stash=$c->stash});$t->get_ok('/hello')->status_is(200);是$stash->{foo},“bar”,“right value”;

属性(_I)

$t=$t->attr_is('img.cat','alt','Grumpy cat');$t=$t->attr_is('img.cat','alt','Grumpy cat','右alt文本');

使用检查属性的文本内容Mojo::DOM中的“attr”在CSS选择器处,首先匹配HTML/XML元素,以便与Mojo::DOM中的“at”.

属性(_isnt)

$t=$t->attr_isnt('img.cat','alt','Calm cat');$t=$t->attr_isnt('img.cat','alt','Calm cat','不同的alt文本');

的对面“属性_ is”.

类属性(_L)

$t=$t->attr_like('img.cat','alt',qr/Grumpy/);$t=$t->attr_like('img.cat','alt',qr/Grumpy/,'right alt text');

使用检查属性的文本内容Mojo::DOM中的“attr”在CSS选择器处,首先匹配HTML/XML元素,以进行类似匹配Mojo::DOM中的“at”.

属性不相似

$t=$t->attr_unlike('img.cat','alt',qr/Calm/);$t=$t->attr_unliverse('img.cat','alt',qr/Calm/,'different alt text');

的对面“attr_like”.

内容(_I)

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

从中检索响应内容后,检查其是否完全匹配Mojo::Message中的“text”.

内容

$t=$t->content_isnt('工作!');$t=$t->content_isnt('工作!','不同内容');

的对面“内容_is”.

内容类(_L)

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

从中检索响应内容后,检查类似匹配项Mojo::Message中的“text”.

内容类型

$t=$t->content_type_is('text/html');$t=$t->content_type_is('text/html','正确的内容类型');

检查响应内容类型用于精确匹配的标题。

内容类型

$t=$t->content_type_isnt('text/html');$t=$t->content_type_isnt('text/html','不同的内容类型');

的对面“内容类型”.

内容类型类

$t=$t->content_type_like(qr/text/);$t=$t->content_type_like(qr/text/,'正确的内容类型');

检查响应内容类型类似匹配的标题。

内容类型不同

$t=$t->内容类型不同(qr/text/);$t=$t->content_type_unlike(qr/text/,'不同的内容类型');

的对面“内容类型类”.

内容不同

$t=$t->内容不同(qr/working!/);$t=$t->content_unliverse(qr/working!/,'different content');

的对面“类似内容”.

删除_确定

$t=$t->delete_ok('http://example.com/foo');$t=$t->delete_ok('/foo');$t=$t->delete_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->delete_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->delete_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行删除请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“删除”,回调除外。

元素count_is

$t=$t->element_count_is('div.foo[x=y]',5);$t=$t->element_count_is('html body div',30,'三十个元素');

检查CSS选择器与匹配的HTML/XML元素的数量Mojo::DOM中的“查找”.

元素_存在

$t=$t->元素存在('div.foo[x=y]');$t=$t->element_exists('html标题','有标题');

首先检查是否存在与HTML/XML元素匹配的CSS选择器Mojo::DOM中的“at”.

#检查属性值$t->get_ok('/login')->元素存在('label[for=email])->element_exists('input[name=email][type=text][value*=“example.com”]')->元素存在('label[for=pass]')->元素存在('input[name=pass][type=password]')->element_exists('input[type=submit][value]);

元素_exists_not

$t=$t->element_exists_not('div.foo[x=y]');$t=$t->element_exists_not('html标题','没有标题');

的对面“元素存在”.

完成(_O)

$t=$t->finish_ok;$t=$t->finish_ok(1000);$t=$t->finish_ok(1003=>“无法接受数据!”);

正常关闭WebSocket连接。

完成(_O)

$t=$t->finished_ok(1000);

等待WebSocket连接正常关闭并检查状态。

获取(_O)

$t=$t->get_ok('http://example.com/foo');$t=$t->get_ok('/foo');$t=$t->get_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->get_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->get_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行GET(获取)请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“get”,回调除外。

#对远程主机运行测试$t->get_ok('https://docs.mojolicious.org')->状态_is(200);#对具有基本身份验证的请求使用相对URL$t->get_ok('//sri:secr3t@/secrets.json')->状态_ is(200)->json_is('/1/content','Mojo rocks!');#对事务运行其他测试$t->get_ok('/foo')->status_is(200);是$t->tx->res->dom->at(‘input’)->val,‘whatever’,‘right value’;

标题(_O)

$t=$t->head_ok('http://example.com/foo');$t=$t->head_ok('/foo');$t=$t->head_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->head_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->head_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行头部请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“head”,回调除外。

标头已存在

$t=$t->header_exists(“ETag”);$t=$t->header_exists('ETag','header exists');

检查响应标头是否存在。

标题存在否

$t=$t->header_exists_not(“标记”);$t=$t->header_exists_not('ETag','header is missing');

的对面“header_exists”.

标题(_I)

$t=$t->header_is(ETag=>'“abc321”');$t=$t->header_is(ETag=>'“abc321”','右标题');

检查响应标题是否完全匹配。

标题(_isnt)

$t=$t->header_isnt(Etag=>'“abc321”');$t=$t->header_isnt(ETag=>'“abc321”','不同的头');

的对面“header_is”.

标题类(_L)

$t=$t->header_like(ETag=>qr/abc/);$t=$t->header_like(ETag=>qr/abc/,'右标题');

检查响应标头是否存在类似匹配。

header_unliverse(标题_不同)

$t=$t->头部不同(ETag=>qr/abc/);$t=$t->header_unliverse(ETag=>qr/abc/,'不同的头');

的对面“header_like”.

json有

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

检查JSON响应是否包含可以使用给定的JSON指针识别的值Mojo::JSON::指针.

json_hasnt公司

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

的对面“json_has”.

json是

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

使用给定的JSON指针检查从JSON响应中提取的值Mojo::JSON::指针,如果省略,则默认为根值。

#使用空JSON指针通过测试描述测试整个JSON响应$t->json_is(''=>{foo=>[1,2,3]},'右对象');

类json

$t=$t->json-like('/foo/1'=>qr/^\d+$/);$t=$t->json_like('/foo/1'=>qr/^\d+$/,'右值');

使用给定的JSON指针检查从JSON响应中提取的值Mojo::JSON::指针用于类似匹配。

json消息具有

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

检查JSON WebSocket消息是否包含可以使用给定的JSON指针通过Mojo::JSON::指针.

json消息hasnt

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

的对面“json消息具有”.

json消息

$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,'正确值');

使用给定的JSON指针检查从JSON WebSocket消息中提取的值Mojo::JSON::指针,如果省略,则默认为根值。

类似于json的消息

$t=$t->json_message_like('/foo/1'=>qr/^\d+$/);$t=$t->json_message_like('/foo/1'=>qr/^\d+$/,'正确值');

使用给定的JSON指针检查从JSON WebSocket消息中提取的值Mojo::JSON::指针用于类似匹配。

json消息不同

$t=$t->json消息不一样('/foo/1'=>qr/^\d+$/);$t=$t->json_message_unliverse('/foo/1'=>qr/^\d+$/,'不同的值');

的对面“类似json消息”.

json不一样

$t=$t->json_unliverse('/foo/1'=>qr/^\d+$/);$t=$t->json_indic('/foo/1'=>qr/^\d+$/,'不同值');

的对面“json_like”.

消息_is

$t=$t->message_is({binary=>$bytes});$t=$t->message_is({text=>$bytes});$t=$t->message_is(“正在工作!”);$t=$t->message_is('工作!','正确的消息');

检查WebSocket消息是否完全匹配。

消息_isnt

$t=$t->message_isnt({binary=>$bytes});$t=$t->message_isnt({text=>$bytes});$t=$t->message_isnt('工作!');$t=$t->message_isnt('工作!','不同的消息');

的对面“message_is”.

类消息

$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!/,'正确的消息');

检查WebSocket消息是否存在类似匹配。

消息_ok

$t=$t->message_ok;$t=$t->message_k('收到消息');

等待下一个WebSocket消息到达。

#等待消息并对其执行多项测试$t->websocket_ok('/time')->消息_ok->类消息(qr/\d+/)->消息不同(qr/\w+/)->完成(_ok);

消息不一样

$t=$t->message_difference({binary=>qr/$bytes/});$t=$t->message_difference({text=>qr/$bytes/});$t=$t->消息不同(qr/working!/);$t=$t->message_unliverse(qr/working!/,'不同的消息');

的对面“消息类”.

新的

my$t=测试::Mojo->new;my$t=测试::Mojo->new(“MyApp”);my$t=测试::Mojo->new(“MyApp”,{foo=>“bar”});my$t=Test::Mojo->new(Mojo::File->new('/path/to/myapp.pl'));my$t=Test::Mojo->new(Mojo::File->new('/path/to/myapp.pl'),{foo=>'bar'});my$t=测试::Mojo->new(MyApp->new);my$t=Test::Mojo->new(MyApp->new,{foo=>'bar'});

新建测试::Mojo对象。除了类名或Mojo::文件对象指向应用程序脚本时,可以传递带有配置值的散列引用,这些配置值将用于覆盖应用程序配置。特殊配置值配置覆盖(_O)将设置为Mojolicious中的“config”它还用于禁用配置插件,如Mojolicious::插件::配置,Mojolicious::插件::JSONConfigMojolicious::插件::NotYAMLConfig用于测试。

#加载相对于“t”目录的应用程序脚本使用Mojo::File qw(curfile);my$t=Test::Mojo->new(curfile->dirname->sibling('myapp.pl'));

选项(_O)

$t=$t->options_ok('http://example.com/foo');$t=$t->options_ok('/foo');$t=$t->options_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->options_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->options_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行选项请求并检查传输错误,采用与Mojo::UserAgent中的“选项”,回调除外。

$t=$t->或(子{…});

如果的值为“成功”为false。

#诊断$t->get_ok('/bad')->或(sub{diag'一定是Glen!'})->状态_is(200)->或(子{diag$t->tx->res->dom->at(“标题”)->文本});

补丁(_O)

$t=$t->patch_ok('http://example.com/foo');$t=$t->patch_ok('/foo');$t=$t->patch_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->patch_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->patch_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行补丁请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“补丁”,回调除外。

发布(_O)

$t=$t->post_ok('http://example.com/foo');$t=$t->post_ok('/foo');$t=$t->post_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->post_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->post_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行邮政请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“帖子”,回调除外。

#测试文件上传my$upload={foo=>{content=>'bar',filename=>'baz.txt'}};$t->post_ok('/upload'=>form=>$upload)->status_is(200);#测试JSON API$t->post_ok('/hello.json'=>json=>{hello=>'world'})->状态_ is(200)->json_is({bye=>“世界”});

输入(_O)

$t=$t->put_ok('http://example.com/foo');$t=$t->put_ok('/foo');$t=$t->put_ok('/foo'=>{Accept=>'*/*'}=>'内容!');$t=$t->put_ok('/foo'=>{Accept=>'*/*'}=>form=>{a=>'b'});$t=$t->put_ok('/foo'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行PUT(输出)请求并检查传输错误,使用与相同的参数Mojo::UserAgent中的“put”,回调除外。

请求(_O)

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

执行请求并检查传输错误。

#使用自定义方法请求我的$tx=$t->ua->build_tx(FOO=>'/test.json'=>json=>{FOO=>1});$t->request_ok($tx)->status_is(200)->json_is({success=>1});#带有自定义cookie的请求my$tx=$t->ua->build_tx(GET=>'/account');$tx->req->cookie({name=>'user',value=>'sri'});$t->request_ok($tx)->status_is(200)->text_is('head>title'=>'Hello sri');#自定义WebSocket握手我的$tx=$t->ua->build_websocket_tx('/foo');$tx->req->headers->remove(“用户代理”);$t->request_ok($tx)->message_k->message_is('bar')->finish_ok;

重置会话

$t=$t->重置会话;

重置用户代理会话。

发送(_O)

$t=$t->send_k({binary=>$bytes});$t=$t->send_ok({text=>$bytes});$t=$t->send_k({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,'发送成功');

通过WebSocket发送消息或帧。

#以“文本”消息形式发送JSON对象$t->websocket_ok('/echo.json')->send_ok({json=>{test=>'IMojolicious!“}})->消息_ok->json_message_is('/test'=>'I莫乔利奇!”)->finish_ok;

状态_is

$t=$t->status_is(200);$t=$t->status_is(200,‘正确状态’);

检查响应状态是否完全匹配。

状态

$t=$t->status_isnt(200);$t=$t->status_isnt(200,'不同状态');

的对面“状态_是”.

测试

$t=$t->测试('is','first value','second value','right value');

呼叫测试::更多函数通过“处理程序”,用于实现测试:Mojo角色。结果将存储在“成功”.

文本_是

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

检查CSS选择器的文本内容,首先匹配HTML/XML元素,以确保与完全匹配Mojo::DOM中的“at”.

文本_插入

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

的对面“文本_是”.

类似文本

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

检查CSS选择器的文本内容,首先匹配HTML/XML元素Mojo::DOM中的“at”.

文本不同

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

的对面“类似文本”.

网络套接字(_O)

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

使用透明握手打开WebSocket连接,参数与Mojo::UserAgent中的“websocket”,回调除外。

#具有permessage-deflate压缩的WebSocket$t->websocket_ok('/'=>{“Sec-websocket-Extensions”=>“permessage-deflate”})->发送(“y”x 50000)->消息_ok->消息_is('z'x 50000)->finish_ok;

另请参阅

Mojolicious公司,Mojolicious::指南,https://mojolicious.org.