如何使用 ActiveRecord 插入可预测的 ID 进行测试

发布于 2024-07-26 06:15:34 字数 700 浏览 1 评论 0原文

我正在尝试进行一些 Cucumber 测试,如下所示:

Given I am logged in as admin
When I go to the article page
Then I should see "Edit Article"
And I should see "Article Title"

文章页面的路径是“articles/1”或一些已知的 id。问题是,当我使用步骤定义插入数据时,

Article.create(:name => "Article Title")

我无法提前知道time 插入记录时的 id 是什么。

本质上,我要么需要

a) 能够插入可预测的 id。 我已经尝试过这个问题的答案中提到的方法,但它没有似乎对我不起作用 - 它总是插入不同的 ID。

或者

b)以这样的方式编写我的黄瓜步骤,以便我可以为我的文章 id 传递一个参数。

我见过的所有黄瓜教程都对这种类型的场景进行了一些掩饰 - 它总是会出现在所有文章或其他内容的列表中,从来没有特定的详细信息页面。

任何帮助,将不胜感激。 谢谢!

I am trying to do some Cucumber testing like the following:

Given I am logged in as admin
When I go to the article page
Then I should see "Edit Article"
And I should see "Article Title"

where the path to the article page is "articles/1" or some known id.The problem is that when I insert my data using my step definition

Article.create(:name => "Article Title")

I can't know ahead of time what the id will be when the record is inserted.

Essentially, I either need

a) to be able to insert predictable ids. I've tried the method mentioned in the answer of this question but it doesn't seem to work for me - it always inserts a different id.

or

b) write my cucumber steps in such a way that I can pass in a parameter for my Article id

All Cucumber tutorials I've seen sort of gloss over this type of scenario - it's always going to the list of all Articles or whatever, never a specific detail page.

Any help would be appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱花落人离去 2024-08-02 06:15:34

以用户的方式导航到文章页面怎么样? 您的步骤

When I go to the article page

可以更改为

When I go to the page for the "Article Title" article

,您的步骤定义将转到文章概述,找到带有“文章标题”的链接并以这种方式导航到页面。

您可以获得更多的测试覆盖范围,并且不必担心 ID。

How about navigating to the article page in the way a user would do it? Your step

When I go to the article page

could be changed to

When I go to the page for the "Article Title" article

and your step definition goes to an article overview, finds a link with "Article Title" and navigates to the page that way.

You get more test coverage, and don't have to worry about IDs.

万劫不复 2024-08-02 06:15:34

有两种方法可以创建可预测的 ID 值。 第一个是在创建时手动设置 ID:

model = Model.new(options)
model.id = DESIRED_ID
model.save

这里的问题是传递给 new、create 或 update_attributes 的选项不会影响 id 值,这就是为什么需要调用 model.id 的原因。

另一种方法是在运行测试之前重置整个表。 如果需要,可以更改此值以考虑固定装置。 例如:

class Model < ActiveRecord::Base
  def self.reset!
    connection.execute("DELETE FROM #{table_name}")
    connection.execute("ALTER TABLE #{table_name} AUTO_INCREMENT=1")
  end
end

这会将插入的第一行的 ID 设置为可预测的 1。

There are two ways to create predictable ID values. The first is to manually set the ID on create:

model = Model.new(options)
model.id = DESIRED_ID
model.save

The catch here is that options passed to either new, create, or update_attributes will not affect the id value which is why the call to model.id is, unfortunately, required.

An alternative is to reset the whole table before running your tests. This can be altered to account for fixtures if required. For example:

class Model < ActiveRecord::Base
  def self.reset!
    connection.execute("DELETE FROM #{table_name}")
    connection.execute("ALTER TABLE #{table_name} AUTO_INCREMENT=1")
  end
end

This will set the ID of the first row inserted to be a predictable 1.

悍妇囚夫 2024-08-02 06:15:34

如何让“转到文章页面”转到“/articles/#{Article.first.id}”

How about making "Go to the Article Page" go to "/articles/#{Article.first.id}"

病毒体 2024-08-02 06:15:34

这就是我的用处:

# feature
Scenario: creator archives fragment
  When fragment 1 exists
  And I am the fragment owner
  And I am on fragment 1

#steps
def create_fragment(attribs)
  force_id = attribs[:force_id]
  attribs.delete(:force_id) if force_id
  fragment = Fragment.create!({ :owner_id => @current_user.id, :originator_id => @current_user.id}.merge(attribs))
  if force_id
    fragment.id = force_id.to_i
    fragment.save!
  end
  fragment
end

When /^fragment (.*) exists$/ do |frag|
  @fragment = Fragment.find_by_id(frag)
  @fragment.destroy if @fragment
  @fragment = create_fragment(:force_id => frag.to_i,:description => "test fragment #{frag}",:narrative => "narrative for fragment #{frag}")
end


# paths.rb
when /fragment (.*)/
fragment_path($1)

玩得开心。

This is what I use:

# feature
Scenario: creator archives fragment
  When fragment 1 exists
  And I am the fragment owner
  And I am on fragment 1

#steps
def create_fragment(attribs)
  force_id = attribs[:force_id]
  attribs.delete(:force_id) if force_id
  fragment = Fragment.create!({ :owner_id => @current_user.id, :originator_id => @current_user.id}.merge(attribs))
  if force_id
    fragment.id = force_id.to_i
    fragment.save!
  end
  fragment
end

When /^fragment (.*) exists$/ do |frag|
  @fragment = Fragment.find_by_id(frag)
  @fragment.destroy if @fragment
  @fragment = create_fragment(:force_id => frag.to_i,:description => "test fragment #{frag}",:narrative => "narrative for fragment #{frag}")
end


# paths.rb
when /fragment (.*)/
fragment_path($1)

Have fun.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文