测试::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=$t->tx;$t=$t->tx(Mojo::Transaction::HTTP->new);
当前交易,通常是Mojo::Transaction::HTTP或Mojo::Transaction::WebSocket对象。
#更具体的测试是$t->tx->res->json->{foo},“bar”,“right value”;ok$t->tx->res->content->is-multipart,“多部分内容”;是$t->tx->previous->res->code,302,“正确状态”;
我的$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”;
$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”.
$t=$t->attr_isnt('img.cat','alt','Calm cat');$t=$t->attr_isnt('img.cat','alt','Calm cat','不同的alt文本');
的对面“属性_ is”.
$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”.
$t=$t->content_is('工作!');$t=$t->content_is('working!','right content');
从中检索响应内容后,检查其是否完全匹配Mojo::Message中的“text”.
$t=$t->content_isnt('工作!');$t=$t->content_isnt('工作!','不同内容');
的对面“内容_is”.
$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中的“删除”,回调除外。
$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]);
$t=$t->element_exists_not('div.foo[x=y]');$t=$t->element_exists_not('html标题','没有标题');
的对面“元素存在”.
$t=$t->finish_ok;$t=$t->finish_ok(1000);$t=$t->finish_ok(1003=>“无法接受数据!”);
正常关闭WebSocket连接。
$t=$t->finished_ok(1000);
等待WebSocket连接正常关闭并检查状态。
$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’;
$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”.
$t=$t->header_is(ETag=>'“abc321”');$t=$t->header_is(ETag=>'“abc321”','右标题');
检查响应标题是否完全匹配。
$t=$t->header_isnt(Etag=>'“abc321”');$t=$t->header_isnt(ETag=>'“abc321”','不同的头');
的对面“header_is”.
$t=$t->header_like(ETag=>qr/abc/);$t=$t->header_like(ETag=>qr/abc/,'右标题');
检查响应标头是否存在类似匹配。
$t=$t->头部不同(ETag=>qr/abc/);$t=$t->header_unliverse(ETag=>qr/abc/,'不同的头');
的对面“header_like”.
$t=$t->json_has('/foo');$t=$t->json_has('/minibar','has a minibar');
检查JSON响应是否包含可以使用给定的JSON指针识别的值Mojo::JSON::指针.
$t=$t->json_hasnt('/foo');$t=$t->json_hasnt('/minibar','no minibar');
的对面“json_has”.
$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]},'右对象');
$t=$t->json-like('/foo/1'=>qr/^\d+$/);$t=$t->json_like('/foo/1'=>qr/^\d+$/,'右值');
使用给定的JSON指针检查从JSON响应中提取的值Mojo::JSON::指针用于类似匹配。
$t=$t->json_message_has('/foo');$t=$t->json_message_has('/minibar','has a minibar');
检查JSON WebSocket消息是否包含可以使用给定的JSON指针通过Mojo::JSON::指针.
$t=$t->json_message_hasnt('/foo');$t=$t->json_message_hasnt('/minibar','no minibar');
的对面“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::指针,如果省略,则默认为根值。
$t=$t->json_message_like('/foo/1'=>qr/^\d+$/);$t=$t->json_message_like('/foo/1'=>qr/^\d+$/,'正确值');
使用给定的JSON指针检查从JSON WebSocket消息中提取的值Mojo::JSON::指针用于类似匹配。
$t=$t->json消息不一样('/foo/1'=>qr/^\d+$/);$t=$t->json_message_unliverse('/foo/1'=>qr/^\d+$/,'不同的值');
的对面“类似json消息”.
$t=$t->json_unliverse('/foo/1'=>qr/^\d+$/);$t=$t->json_indic('/foo/1'=>qr/^\d+$/,'不同值');
的对面“json_like”.
$t=$t->message_is({binary=>$bytes});$t=$t->message_is({text=>$bytes});$t=$t->message_is(“正在工作!”);$t=$t->message_is('工作!','正确的消息');
检查WebSocket消息是否完全匹配。
$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消息是否存在类似匹配。
$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::插件::JSONConfig和Mojolicious::插件::NotYAMLConfig用于测试。
#加载相对于“t”目录的应用程序脚本使用Mojo::File qw(curfile);my$t=Test::Mojo->new(curfile->dirname->sibling('myapp.pl'));
$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(“标题”)->文本});
$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中的“补丁”,回调除外。
$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=>“世界”});
$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”,回调除外。
$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->重置会话;
重置用户代理会话。
$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=>'I♥ Mojolicious!“}})->消息_ok->json_message_is('/test'=>'I♥ 莫乔利奇!”)->finish_ok;
$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标题');
的对面“类似文本”.
$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.