【问题标题】:Testing stateful Mojolicious apps测试有状态的 Mojolicious 应用程序
【发布时间】:2015-11-26 12:15:38
【问题描述】:

我想测试条目的隐藏和取消隐藏。我在 Mojolicious t/basic.t 中进行了以下测试:

my $t = Test::Mojo->new('AdminApi');
$t->get_ok('/publications/hide/1');
$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);

$t->get_ok('/publications/unhide/1');
$t->get_ok('/read/publications/meta')->content_like(qr/Paper with id 1: <a href/i);
$t->get_ok('/read/publications/meta/1')->content_unlike(qr/Cannot find entry id: 1/i);

我的问题是'/publications/hide/1'和'/publications/unhide/1'这两行不隐藏和取消隐藏条目。条目的状态保持不变。

如果我在浏览器中手动重复这些步骤,一切正常。出于显而易见的原因,我希望通过测试使其自动化。如何做到这一点?

编辑:调用 '/publications/hide/1' 和 '/publications/unhide/1' 改变了数据库的状态 - 只是一个简单的 UPDATE 查询。此更改适用于整个应用程序 - 适用于所有用户。但是需要以用户身份登录才能隐藏/取消隐藏。问题:如何在测试期间模拟登录用户?

“/read/publications/meta”和“/read/publications/meta/1”生成的内容无需登录即可阅读。

Bitbucket Repo

File with test code: basic.t

【问题讨论】:

  • /publications/hide/1/publications/unhide/1 是否改变了服务器上应用程序内部资源的状态?该状态是否与用户有关,或者一般而言与整体应用程序有关? $t 是否有会话 cookie,它是否为它与 get_ok 发出的每个请求保持相同的会话?
  • 我添加了缺少的信息和代码存储库的链接。

标签: perl testing automated-tests mojolicious


【解决方案1】:

正如您已经说过的,您需要登录才能执行hideunhide 操作。

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

您正在这里创建一个新的 UserAgent。 Test::Mojo 类继承自 Mojo::UserAgent。它有一个cookie_jar,从而使会话保持活动状态。您需要它来执行此操作:

$t->get_ok('/publications/hide/1');

但是现在你还没有登录。你需要做的是登录用户。查看code in your repository,您实际上断言您未登录

 $t->get_ok('/')->status_is(200)->content_like(qr/Please login or register/i);

在执行hide 之前,您需要登录用户。在您的代码中挖掘了一下之后,我找到了操作和the template 来执行此操作,所以我知道请求需要是什么样的。

$t->post_ok(
    '/do_login' => { Accept => '*/*' },
    form        => { user   => 'admin', pass => 'hunter2' }
);

现在您的$t UserAgent 应该已登录,您可以执行hide。请注意,get_ok 仅检查是否没有传输错误。因此,实际上现在检查您现在是否已经登录是有意义的。

您可以通过内省应用程序中的会话、检查日志文件(您正在那里写"Login success")或检查页面中是否有一些表明用户已登录的字符串来做到这一点。在templates/display/start.html.ep 那里是欢迎登录用户的文本,因此您可以使用它。

$t->post_ok(
    '/do_login' => { Accept => '*/*' },
    form        => { user   => 'admin', pass => 'hunter2' }
)->text_like(qr/Nice to see you here admin/i);

因为text_like 使用文本节点,所以用户名周围的&lt;em&gt; 在测试中不相关。

好的,现在我们知道您已登录。是时候打开和关闭此功能了。

$t->get_ok('/publications/hide/1');

因为据我所知没有明显的错误,我不知道如何测试它的成功。状态码是一种方式,但内容中可能还有一些您可以测试的内容。

要验证应用程序的状态,您现在需要调用发布。

$t->get_ok('/read/publications/meta')->content_unlike(qr/Paper with id 1:/i);
$t->get_ok('/read/publications/meta/1')->content_like(qr/Cannot find entry id: 1/i);

没错。但是请记住,我们的$t 仍然处于登录状态。也许登录的用户可以看到隐藏的东西以及未隐藏的东西。也许他们不是。

创建第二个未登录的 UserAgent 可能更安全,并与该用户进行检查。

# check with an unauthorized user
my $t_not_logged_in = Test::Mojo->new('AdminApi');
$t_not_logged_in
  ->get_ok('/read/publications/meta')
  ->content_unlike(qr/Paper with id 1:/i);
$t_not_logged_in
  ->get_ok('/read/publications/meta/1')
  ->content_like(qr/Cannot find entry id: 1/i);

现在基本上你通过取消隐藏你的内容并再次测试来重复同样的事情。冲洗并重复。


请记住,除非您使用显式测试数据库(您似乎没有这样做),否则您甚至无法确定是否存在条目 1。或者它的名称是什么。您应该使用固定装置进行测试。例如,您可以使用 sqlite 创建一个新的数据库实例并使用它。

【讨论】:

  • 谢谢!这有很大帮助!现在,我可以正确地完成编写测试了。我有一个单独的服务器用于测试,我可以在其中快速将数据库重置为预定义的状态。我正在使用 bash 脚本执行此操作,但我可能会添加一些 perl 代码以实现更多自动化。
  • 未来:片段“因为text_like使用文本节点,用户名周围的在测试中不相关。”在当前版本中似乎并非如此。你需要在那里使用content_like
  • 我不记得写过这个答案,但我相信你是正确的@Piotr :)
猜你喜欢
  • 2016-05-06
  • 1970-01-01
  • 2011-03-30
  • 2013-11-06
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多