測試有狀態的 Mojolicious 應用程序 (Testing stateful Mojolicious apps)


問題描述

測試有狀態的 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 查詢。此更改適用於整個應用程序 ‑ 適用於所有用戶。但是需要以用戶身份登錄才能隱藏/取消隱藏。問題:如何在測試期間模擬登錄用戶?


參考解法

方法 1:

As you have already said, you need to be logged in to perform the hide and unhide action.

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

You are creating a new UserAgent here. The Test::Mojo class inherits from Mojo::UserAgent. It has a cookie_jar and thus keeps a session alive. You need that to perform this action:

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

But right now you are not logged in. What you need to do is log in the user. Looking at the code in your repository, you actually assert that you are not logged in.

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

Before you perform the hide, you need to log in the user. After digging a bit in your code I found the action and the template to do that, so I know what the request needs to look like.

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

Now your $t UserAgent should be logged in and you can do the hide. Note that get_ok only checks if there was no transport error. So in fact it would make sense to now check if in fact you are now logged in.

You could do that by introspecting the session in the application, by checking the logfile (you are writing "Login success" there) or by checking the page for some string that says that the user is logged in. In templates/display/start.html.ep there is a text that welcomes the logged‑in user, so you can use that.

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

Because text_like uses the text‑nodes, the <em> around the username is not relevant in the test.

Right, now we know you are logged in. Time to switch the thing on and off.

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

Because there is no obvious error thrown for that as far as I can tell, I don't see how to test the success of that. Status code is one way, but there might be something in the content as well that you could test.

To verify the state of the application, you would now call the publication.

$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);

Right. But remember, our $t is still logged in. Maybe the logged‑in user is allowed to see hidden stuff as well as unhidden stuff. Maybe they are not.

It's probably safer to make a second UserAgent that's not logged in, and check with that one as well.

# 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);

Now basically you repeat the same thing by unhiding your content and testing again. Rinse and repeat.


Keep in mind that unless you are using an explicit testing database (which you seem not to do), you cannot be sure that there even is an entry 1. Or what the name of that is. You should use fixtures for the tests. You could, for example, create a fresh instance of the DB using sqlite and work with that.

(by vikin9simbabque)

參考文件

  1. Testing stateful Mojolicious apps (CC BY‑SA 2.5/3.0/4.0)

#perl #automated-tests #Testing #mojolicious






相關問題

保持特定位數的簡單 Perl 數學 (simple Perl math while keeping a specific number of digits)

如何在 Windows 批處理腳本或 Perl 中將文件移動到回收站? (How can I move files to the Recycle Bin in a Windows batch script or Perl?)

從子程序返回數組 (Return array from subroutine)

我可以以與操作系統無關的方式限制 Perl 進程使用的內存嗎? (Can I Iimit the memory used by a Perl process in an OS-agnostic way?)

$# 在 perl 中接受什麼作為輸入? (what does $# accept as input in perl?)

Perl Text::CSV_XS 從字符串中讀取 (Perl Text::CSV_XS read from string)

使用 excel 2010 更新批處理文件中的變量 (use excel 2010 to update variables in batch file)

在 perl 中為哈希添加值 (Adding value to an hash in perl)

為什麼 perl 會忽略我的正則表達式中的多餘字符? (Why does perl ignore extra characters in my regex?)

boost::regex - \bb? (boost::regex - \bb?)

如果小於 X 天,如何從磁盤讀取文件,如果舊,則重新獲取 html 文件 (How to read a file from the disk if less than X days old, if older, refetch the html file)

使用 Devel-Cover 獲取覆蓋率報告 (Using Devel-Cover to get coverage reports)







留言討論