rspec 测试页面元素

by Parth Modi

由Parth Modi

如何使用共享示例使您的RSpec测试干燥 (How to DRY out your RSpec Tests using Shared Examples)

Give me six hours to chop down a tree and I will spend the first four sharpening the axe.” — Abraham Lincoln

给我六个小时的时间来砍树,我将用头四个时间来削斧头。” - 亚伯拉罕·林肯

When I refactored a project a few weeks ago, I spent most of my time writing specs. After writing several similar test cases for some APIs, I started to wonder whether I might be able to get rid of a lot of this duplication.

几周前重构项目时,我大部分时间都在编写规范。 在为某些API编写了几个类似的测试用例之后,我开始怀疑我是否可以摆脱很多重复。

So I threw myself into reading up on the best practices for DRYing up tests (Don’t Repeat Yourself). And that’s how I came to know of shared examples and shared contexts.

因此,我开始阅读有关烘干测试的最佳做法(不要重复自己)。 这就是我了解shared examplesshared contexts

In my case, I ended up using shared examples. And here’s what I’ve learned so far from applying these.

就我而言,我最终使用了共享示例。 到目前为止,这是我从应用这些知识中学到的。

When you have multiple specs that describe similar behavior, it might be better to extract redundant examples into shared examples and use them in multiple specs.

当您有多个描述相似行为的规范时,将冗余示例提取到shared examples并在多个规范中使用它们可能会更好。

Suppose you have two models User and Post, and a user can have many posts. Users should be able to view list of users and posts. Creating an index action in the users and posts controllers will serve this purpose.

假设您有两个模型UserPost ,一个用户可以有多个帖子。 用户应该能够查看用户列表和帖子。 在用户和发布控制器中创建索引操作将达到此目的。

First, write specs for your index action for the users controller. It will have the responsibility of fetching users and rendering them with proper layout. Then write enough code to make tests pass.

首先,为用户控制器编写索引操作的规范。 它将负责获取用户并以正确的布局呈现用户。 然后编写足够的代码以使测试通过。

# users_controller_spec.rbdescribe "GET #index" do  before do     5.times do      FactoryGirl.create(:user)     end    get :index  end  it {  expect(subject).to respond_with(:ok) }  it {  expect(subject).to render_template(:index) }  it {  expect(assigns(:users)).to match(User.all) }end
# users_controller.rbclass UsersController < ApplicationController  ....  def index    @users = User.all  end  ....end

Typically, the index action of any controller fetches and aggregates data from few resources as required. It also adds pagination, searching, sorting, filtering and scoping.

通常,任何控制器的索引操作都根据需要从很少的资源中获取并聚合数据。 它还增加了分页,搜索,排序,过滤和作用域。

Finally, all these data are presented to views via HTML, JSON, or XML using APIs. To simplify my example, the index actions of controllers will just fetch data, then show them via views.

最后,所有这些数据都使用API​​通过HTML,JSON或XML呈现给视图。 为了简化我的示例,控制器的索引动作将仅获取数据,然后通过视图显示它们。

The same goes for the index action in the posts controller:

posts控制器中的index操作也是如此:

describe "GET #index" do   before do     5.times do      FactoryGirl.create(:post)    end    get :index  end  it {  expect(subject).to respond_with(:ok) }  it {  expect(subject).to render_template(:index) }  it {  expect(assigns(:posts)).to match(Post.all) }end
# posts_controller.rbclass PostsController < ApplicationController  ....  def index    @posts = Post.all  end  ....end

RSpec tests written for both users and posts controller are very similar. In both controllers we have:

为用户和帖子控制器编写的RSpec测试非常相似。 在两个控制器中,我们都有:

  • The response code — should be ‘OK’响应码-应该为“ OK”
  • Both index action should render proper partial or view — in our case index

    两种索引操作都应呈现适当的局部或视图-在我们的案例中是index

  • The data we want to render, such as posts or users我们要呈现的数据,例如帖子或用户

Let’s DRY the specs for our index action by using shared examples.

让我们通过使用shared examples来干燥索引操作的规范。

共享示例放在哪里 (Where to put your shared examples)

I like to place shared examples inside the specs/support/shared_examples directory so that all shared example-related files are loaded automatically.

我喜欢将共享示例放置在specs / support / shared_examples目录中,以便自动shared example所有shared example相关的文件。

You can read about other commonly used conventions for locating your shared examples here: shared examples documentation

您可以在此处了解其他用于查找shared examples常用约定: 共享示例文档

如何定义一个共享的例子 (How to define a shared example)

Your index action should respond with 200 success code (OK) and render your index template.

您的索引操作应以200成功代码(OK)响应,并呈现您的索引模板。

RSpec.shared_examples "index examples" do   it { expect(subject).to respond_with(:ok) }  it { expect(subject).to render_template(:index) }end

Apart from your it blocks — and before and after your hooks — you can add let blocks, context, and describe blocks, which can also be defined inside shared examples.

除了您的it块(在钩子之前和之后)之外,您还可以添加let块,上下文和描述块,它们也可以在shared examples定义。

I personally prefer to keep shared examples simple and concise, and don’t add contexts and let blocks. The shared examples block also accepts parameters, which I’ll cover below.

我个人更喜欢使共享示例简单明了,不要添加上下文和让块。 shared examples块还接受参数,我将在下面介绍。

如何使用共享示例 (How to use shared examples)

Adding include_examples "index examples" to your users and posts controller specs includes “index examples” to your tests.

向您的用户添加include_examples "index examples" ,并发布控制器规范,其中包括对测试的“索引示例”。

# users_controller_spec.rbdescribe "GET #index" do  before do     5.times do      FactoryGirl.create(:user)     end    get :index  end  include_examples "index examples"  it {  expect(assigns(:users)).to match(User.all) }end
# similarly, in posts_controller_spec.rbdescribe "GET #index" do  before do     5.times do      FactoryGirl.create(:post)     end    get :index  end  include_examples "index examples"  it {  expect(assigns(:posts)).to match(Post.all) }end

You can also use it_behaves_like or it_should_behaves_like instead of include_examples in this case. it_behaves_like and it_should_behaves_like are actually aliases, and work in same manner, so they can be used interchangeably. But include_examples and it_behaves_like are different.

在这种情况下,您也可以使用it_behaves_likeit_should_behaves_like代替include_examplesit_behaves_likeit_should_behaves_like实际上是别名,并且以相同的方式工作,因此可以互换使用。 但是include_examplesit_behaves_like是不同的。

As stated in the official documentation:

如官方文档中所述:

  • include_examples — includes examples in the current context

    include_examples在当前上下文中包含示例

  • it_behaves_like and it_should_behave_like include the examples in a nested context

    it_behaves_likeit_should_behave_like将示例包含在嵌套上下文中

为什么这种区别很重要? (Why does this distinction matter?)

RSpec’s documentation gives a proper answer:

RSpec的文档给出了正确的答案:

When you include parameterized examples in the current context multiple times, you may override previous method definitions and last declaration wins.

当您在当前上下文中多次包含参数化示例时,您可以覆盖以前的方法定义,最后声明会获胜。

So when you face situation where parameterized examples contain methods that conflict with other methods in same context, you can replace include_examples with it_behaves_like method. This will create a nested context and avoid this kind of situations.

因此,当遇到参数化示例包含与同一上下文中其他方法冲突的方法的情况时,可以使用it_behaves_like方法替换include_examples 。 这将创建一个嵌套的上下文并避免这种情况。

Check out the following line in your users controller specs, and posts controller specs:

在用户控制器规范中查看以下行,并发布控制器规范:

it { expect(assigns(:users)).to match(User.all) }it { expect(assigns(:posts)).to match(Post.all) }

Now your controller specs can be re-factored further by passing parameters to shared example as below:

现在,可以通过将参数传递给共享示例来进一步重构控制器规格,如下所示:

# specs/support/shared_examples/index_examples.rb
# here assigned_resource and resource class are parameters passed to index examples block RSpec.shared_examples "index examples" do |assigned_resource, resource_class|   it { expect(subject).to respond_with(:ok) }  it { expect(subject).to render_template(:index) }  it {  expect(assigns(assigned_resource)).to match(resource_class.all)   }end

Now, make following changes to your users and posts controller specs:

现在,对您的用户进行以下更改并发布控制器规格:

# users_controller_spec.rbdescribe "GET #index" do  before do     ...  end  include_examples "index examples", :users, User.allend
# posts_controller_spec.rbdescribe "GET #index" do  before do     ...  end  include_examples "index examples", :posts, Post.allend

Now controller specs look clean, less redundant and more importantly, DRY. Furthermore, these index examples can serve as basic structures for designing the index action of other controllers.

现在,控制器规格看起来很整洁,减少了冗余,更重要的是DRY。 此外,这些索引示例可以用作设计其他控制器的索引动作的基本结构。

结论 (Conclusion)

By moving common examples into a separate file, you can eliminate duplication and improve the consistency of your controller actions throughout your application. This is very useful in case of designing APIs, as you can use the existing structure of RSpec tests to design tests and create APIs that adhere to your common response structure.

通过将常见示例移到单独的文件中,您可以消除重复并提高整个应用程序中控制器操作的一致性。 这在设计API时非常有用,因为您可以使用RSpec测试的现有结构来设计测试并创建符合您的通用响应结构的API。

Mostly, when I work with APIs, I use shared examples to provide me with a common structure to design similar APIs.

通常,当我使用API​​时,我会使用shared examples为我提供一个通用的结构来设计相似的API。

Feel free to share how you DRY up your specs by using shared examples.

通过使用shared examples随时分享您如何干燥规格。

翻译自: https://www.freecodecamp.org/news/how-to-dry-out-your-rspec-tests-using-shared-examples-d5cc5d33fd76/

rspec 测试页面元素

rspec 测试页面元素_如何使用共享示例使您的RSpec测试干燥相关推荐

  1. rspec 测试页面元素_如何使用RSpec对Go应用进行黑盒测试

    rspec 测试页面元素 by Dmitriy Lutsko 德米特里·卢茨科(Dmitriy Lutsko) 如何使用RSpec对Go应用进行黑盒测试 (How to black box test ...

  2. html鼠标元素效果,如何使用CSS实现鼠标移动控制页面元素效果?(代码示例)...

    本篇文章给大家介绍一下使用css映射的鼠标位置,实现通过鼠标移动控制页面元素效果的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 映射鼠标位置或实现拖拽效果,我们可以在 Jav ...

  3. 红外测试操作步骤_红外传感实验操作步骤及数据分析(无测试实图)

    红外传感实验操作步骤及数据分析(无测试实图) 1. 启动红外传感模块 红外传感模块工作实图 ( 1 ) 将 NEWlab 实验硬件平台通电并与电脑链接. ( 2 ) 将红外传感模块放置在 NEWlab ...

  4. 超准中医体质测试 源码_可能是史上“最准”的抑郁症测试,试试你有没有患上抑郁症...

    越来越多的公众人物被爆因抑郁症自杀,很多人对这种疾病产生了恐惧感.并且从抑郁出现到如今,随着各方面压力不断增加,患抑郁症的人越来越多,所以我们要时刻做好预防,下面的测试题你敢试试吗? 最准的抑郁症心理 ...

  5. 微信小程序第五篇:页面弹出效果及共享元素动画

    系列文章传送门: 微信小程序第一篇:自定义组件详解 微信小程序第二篇:七种主流通信方法详解 微信小程序第三篇:获取页面节点信息 微信小程序第四篇:生成图片并保存到手机相册 目录 一.page-caon ...

  6. (转)selenium页面元素定位八大方法_琉璃

    2019独角兽企业重金招聘Python工程师标准>>> 转自:https://www.cnblogs.com/qingchunjun/p/4208159.html 在使用seleni ...

  7. eclipse在网页进入时显示重定向过多_使用eclipse快速开发jsp以及编码问题、jsp页面元素、request对象学习的粗略记录...

    人老了真是什么都会忘记啊orz,早上发现学过去的东西好多都还没记录复盘... ...(懒虫作祟) 在开始之前,俺认为还是很有必要了解一下jsp的执行流程,俺发现CSDN上的"陈小哥cw&qu ...

  8. angular跳转指定页面_通过 angular CDK 实现页面元素拖放

    通过导入@angular/cdk/drag-drop模块我们可以轻松实现元素在页面中得拖放功能,如元素在页面中随意拖动.在特定区域内拖动亦或对列表进行拖放排序等等. 通过 angular CDK 实现 ...

  9. php 改变页面元素,动态更改网页HTML元素(对象)内容_经验交流

    动态HTML的出现为用户提供了一种基于传统标准HTML来创建交互式页面的机制.本文主要针对IE 5.0谈谈如何通过其提供的HTML文档对象(DOM)模型使用脚本添加.删除.修改页面中的HTML元素(对 ...

最新文章

  1. WordPress自动升级插件时需要填写FTP信息的解决
  2. 多层陶瓷电容器用处_陶瓷材料|MLCC片式多层陶瓷电容器应用及制作工艺介绍...
  3. 显示此文稿缺少字体_打开CAD图纸后,显示缺少SHX文件?这个解决方法你一定要知道...
  4. 虚拟化系列-VMware vSphere 5.1 虚拟机管理
  5. javascript中变量和函数的使用
  6. python部署thrift服务以及客户端
  7. python绘制立体扇形_你不知道的4种方法:python方法绘制扇形
  8. MAC上Maven下载及安装
  9. spss20安装许可证代码_SPSS23安装教程
  10. 迅雷VIP帐号获取小工具
  11. 将python文件转成exe文件
  12. pay.onzan.en app.php,IBOS 协同办公平台PHP版 v1.0
  13. linux下查看显卡和驱动版本
  14. 这苦日子B站熬出头了?
  15. Python 打地鼠小游戏
  16. Ubuntu下安装rar软件,解压rar压缩文件方法
  17. PDF转换成Word转换器下载 PDF如何转成Word
  18. 群体智能——激发更多潜能
  19. 外包企业邮箱服务怎么选?哪家外包企业邮箱服务好?
  20. python实现猜数字游戏_python如何实现猜数字游戏

热门文章

  1. 做图形处理Linux小型主机,8个优秀的linux图形图像工具
  2. jupyter notebook出现cannot import name 'create_prompt_application'问题(Died Kernel)
  3. backbone学习总结(二)
  4. 【文章】本站收集与转载文章目录
  5. 改变myeclipse北京颜色
  6. 分享一个mysql 复杂查询的例子
  7. Forefront_TMG_2010-TMG发布Web服务器
  8. 使用SVN+Axure RP 8.0创建团队项目
  9. 填报表中也可以添加 html 事件
  10. [asp.net core]SignalR一个例子