测试有状态的 Mojolicious 应用程序

Testing stateful Mojolicious apps

我想测试条目的隐藏和取消隐藏。我在 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 查询。更改适用于整个应用程序 - 适用于所有用户。但是需要以 hide/unhide 的用户身份登录。问题:如何在测试期间模拟登录用户?

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

Bitbucket Repo

File with test code: basic.t

如您所说,您需要登录才能执行 hideunhide 操作。

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

您正在此处创建一个新的 UserAgent。 Test::Mojo class 继承自 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使用文本节点,用户名周围的<em>在测试中不相关。

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

$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 创建一个新的数据库实例并使用它。