我有一个包含博客功能的rails应用。
在一个单一的功能测试中(使用Capybara :: Rails :: TestCase,对于博客使用ruby测试(断言/反驳),即不是规范),我想测试添加帖子,添加评论,编辑帖子,作为单独的测试 - 每个测试都建立在最后一个测试的基础上,因为第一个测试中创建的帖子在第二个测试中被评论,依此类推。
我看过哪些帖子显示了在单元测试中执行此操作的解决方法(全局变量,使用setup / teardown),但我想知道是否有更直接的方法在功能测试中执行此操作,因为它可能更多在这里很常见。
理想情况下,我希望登录会话保持不变,以及在先前测试中创建的数据库记录在TestCase中的每个测试中保持不变。设置和拆解可以用于每次登录,但不能用于为帖子,评论等创建的中间记录。
我想要类似的东西:
class BlogTest< Capybara::Rails::TestCase
test 'can sign in' do
user = User.create!(name: "user",
email: "user@example.com",
password: "passw0rd!", password_confirmation: "passw0rd!")
visit new_user_session_path
fill_in('Login', :with => user.email)
fill_in('Password', :with => user.password)
check('Remember me')
click_button('Sign in')
end
test 'can create post' do
visit new_post_path # how can I have user logged in?
fill_in "Title", with: "My first post title!"
fill_in "Body", with: "My first post body!"
click_button "Publish"
end
test 'can comment on post' do
visit post_path(Post.first) # should go to post created in last test
click_button "Add comment"
...
end
end
我听说这可能在Cucumber中有用,但是出于其他原因选择不使用Cucumber,所以希望它与Minitest和Capybara合作。
答案 0 :(得分:1)
Capybara::Rails::TestCase
继承自ActiveSupport::TestCase
。 ActiveSupport::TestCase
的主要功能之一是它在数据库事务中运行每个测试。有办法解决这个问题,但我不推荐它们。
相反,我建议您使用rails测试类的行为。在这种情况下,您希望在测试之间共享操作。我建议您将这些操作提取到方法中,并在测试中调用这些方法。以下是我将如何使用您的测试代码实现此功能:
class BlogTest< Capybara::Rails::TestCase
def user
@user ||= User.create!(name: "user",
email: "user@example.com",
password: user_password,
password_confirmation: user_password)
end
def user_password
"passw0rd!"
end
def sign_in(email, password)
visit new_user_session_path
fill_in('Login', :with => email)
fill_in('Password', :with => password)
check('Remember me')
click_button('Sign in')
end
def create_post(title = "My first post title!",
body = "My first post body!")
visit new_post_path # how can I have user logged in?
fill_in "Title", with: title
fill_in "Body", with: body
click_button "Publish"
end
def comment_on_post(post, comment)
visit post_path(post)
click_button "Add comment"
# ...
end
test "can sign in" do
sign_in(user.email, user_password)
# add assertions here that you are signed in correctly
end
test "can't sign in with a bad password" do
sign_in(user.email, "Not the real password")
# add assertions here that you are not signed in
end
test "can create post when signed in" do
sign_in(user.email, user_password)
create_post
# add assertions here that post was created correctly
end
test "can't create post when not signed in" do
create_post
# add assertions here that post was not created
end
test "can comment on post when signed in" do
sign_in(user.email, user_password)
create_post
post = user.posts.order(:created_at).last
comment_on_post(post, "I can comment because I'm signed in!")
# add assertions here that comment was created correctly
end
test "can't comment on post when not signed in" do
post = Post.first
comment_on_post(post, "I can't comment because I'm not signed in!")
# add assertions here that comment was not created
end
end
每个操作都有一个好名字,您可以将这些操作重用于不同类型的测试。每个测试都在数据库事务中执行,因此每次运行每个测试方法时,数据库看起来都是一样的。