rspec 测试页面元素_如何使用共享示例使您的RSpec测试干燥
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 examples
和shared 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.
假设您有两个模型User和Post ,一个用户可以有多个帖子。 用户应该能够查看用户列表和帖子。 在用户和发布控制器中创建索引操作将达到此目的。
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_like
或it_should_behaves_like
代替include_examples
。 it_behaves_like
和it_should_behaves_like
实际上是别名,并且以相同的方式工作,因此可以互换使用。 但是include_examples
和it_behaves_like
是不同的。
As stated in the official documentation:
如官方文档中所述:
include_examples
— includes examples in the current contextinclude_examples
在当前上下文中包含示例it_behaves_like
andit_should_behave_like
include the examples in a nested contextit_behaves_like
和it_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 测试页面元素
相关文章:

Windows搭建以太坊的私有链环境
Windows搭建以太坊的私有链环境 1、下载Geth.exe 运行文件,并安装https://github.com/ethereum/go-ethereum/releases/下载后,只有一个Geth.exe的文件2、cmd进入按章目录运行:geth -help看看是否可用geth命令3、在Geth安装目录下放置初始化创…

前50个斐波那契数
它有一个递推关系,f(1)1f(2)1f(n)f(n-1)f(n-2),其中n>23f(n)f(n2)f(n-2)-------------------------------------------- F(1) 1 F(2) 1 F(3) 2 F(4) 3 F(5) 5 F(6) 8 F(7) 13 F(8) 21 F(9) 34 F(10) 55 F(11) 89 F(12) 144 F(13) 233 F(14) 377 F(…

RAC -代替OC 中的代理
学以致用, 有的时候学习了很多理论 却还是忘了实践 OC 中代替代理 简洁编程 #import "ViewController.h" #import <ReactiveObjC.h> #import "SKView.h" interface ViewController ()endimplementation ViewController- (void)viewDidL…

深度学习 免费课程_深入学习深度学习,提供15项免费在线课程
深度学习 免费课程by David Venturi大卫文图里(David Venturi) 深入学习深度学习,提供15项免费在线课程 (Dive into Deep Learning with 15 free online courses) Every day brings new headlines for how deep learning is changing the world around us. A few e…

《音乐商店》第4集:自动生成StoreManager控制器
一、自动生成StoreManager控制器 二、查看 StoreManager 控制器的代码 现在,Store Manager 控制器中已经包含了一定数量的代码,我们从头到尾重新过一下。 1.访问数据库代码 首先,在控制器中包含了标准的 MVC 控制器的代码,为了使用…

StringUtils
/需要导入第三方jar包pinyin4j.jarimport net.sourceforge.pinyin4j.PinyinHelper;import java.util.regex.Matcher; import java.util.regex.Pattern;public class StringUtils {protected static final String TAG StringUtils.class.getSimpleName();/*** 增加空白*/public…

微信支付invalid total_fee 的报错
因为我的测试商品是0.01的 原因是微信支付的金额是不能带小数点的 直接在提交的时候 乘以 100操作 ,因为里面设置参数的时候是 以分为单位的 [packageParams setObject: price forKey:"total_fee"]; //订单金额,单位为分

帧编码 场编码_去年,我帮助举办了40场编码活动。 这是我学到的。
帧编码 场编码by Florin Nitu通过弗洛林尼图 去年,我帮助举办了40场编码活动。 这是我学到的。 (I helped host 40 coding events last year. Here’s what I learned.) Our local freeCodeCamp study group in Brasov, Romania just held its 40th event. We even…

HDU 4540 威威猫系列故事――打地鼠(DP)
D - 威威猫系列故事――打地鼠Time Limit:100MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4540Description 威威猫最近不务正业,每天沉迷于游戏“打地鼠”。 每当朋友们劝他别太着迷游戏,应该好好工…

iOS 在每一个cell上添加一个定时器的方案
1 首先创建一个数组,用来创建所有的定时器的时间 - (NSMutableArray *)totalLastTime {if (!_totalLastTime) {_totalLastTime [NSMutableArray array];}return _totalLastTime; }2 当从网络请求过来时间之后,循环遍历,行数和时间作为Key&a…

用字符串生成二维码
需要导入Zxing.jar包import android.graphics.Bitmap;import com.google.zxing.BarcodeFormat; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix;public class ZxingCode {/** * 用字符串生成…

在JavaScript中重复字符串的三种方法
In this article, I’ll explain how to solve freeCodeCamp’s “Repeat a string repeat a string” challenge. This involves repeating a string a certain number of times.在本文中,我将解释如何解决freeCodeCamp的“ 重复字符串重复字符串 ”挑战。 这涉及重…

杭电2099 整除的尾数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid2099 解题思路:将a扩大100倍之后,再给它从加上i(i从0到99),一个一个的看哪一个能整除 反思:末两位是00的时候输出的是00(这种情况题目里面的测试数据给…

iOS 验证码倒计时按钮
具体使用 [SmsTimerManager sharedManager].second (int)time; [[SmsTimerManager sharedManager] resetTime]; [SmsTimerManager sharedManager].delegate self; [strongSelf updateTime];设置代理方法 更新按钮的标题 (void)updateTime { if ([SmsTimerManager sharedMan…

树莓派centos安装的基本配置
萌新再发一帖,这篇文章呢主要是为大家在树莓派上安装centos以后提供一个问题的解决方案。 首先我呢觉得好奇就在某宝上花了两百来块钱买了一套树莓派,很多人喜欢在树莓派上安装Debian,我呢更青睐用Red Hat的系统,毕竟对Red Hat更熟…

token拦截器阻止连接_如何防止广告拦截器阻止您的分析数据
token拦截器阻止连接TL;DR Theres dataunlocker.com service coming soon (subscribe!), along with the open-sourced prototype you can use for Google Analytics or Google Tag Manager (2020 update).TL; DR即将推出dataunlocker.com服务 (订阅!),以…

使用Fiddler手机抓包https-----重要
Fiddler不仅可以对手机进行抓包,还可以抓取别的电脑的请求包,今天就想讲一讲使用Fiddler手机抓包! 使用Fiddler手机抓包有两个条件: 一:手机连的网络或WiFi必须和电脑(使用fiddler)连的网络或Wi…

strtok和strtok_r
strtok和strtok_r原型:char *strtok(char *s, char *delim); 功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。 说明:首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。 …

iOS 标签自动布局
导入SKTagFrame SKTagFrame *frame [[SKTagFrame alloc] init];frame.tagsArray self.bigModel.Tags;// 添加标签CGFloat first_H 0;CGFloat total_H 0;for (NSInteger i 0; i< self.bigModel.Tags.count; i) {UIButton *tagsBtn [UIButton buttonWithType:UIButtonT…

引导分区 pbr 数据分析_如何在1小时内引导您的分析
引导分区 pbr 数据分析by Tim Abraham蒂姆亚伯拉罕(Tim Abraham) 如何在1小时内引导您的分析 (How to bootstrap your analytics in 1 hour) Even though most startups understand how critical data is to their success, they tend to shy away from analytics — especial…

SSL 1460——最小代价问题
Description 设有一个nm(小于100)的方格(如图所示),在方格中去掉某些点,方格中的数字代表距离(为小于100的数,如果为0表示去掉的点),试找出一条从A(左上角)到B(右下角&am…

在Windows 7下面IIS7的安装和 配置ASP的正确方法
在Windows 7下如何安装IIS7,以及IIS7在安装过程中的一些需要注意的设置,以及在IIS7下配置ASP的正确方法。 一、进入Windows 7的 控制面板,选择左侧的打开或关闭Windows功能 。二、打开后可以看到Windows功能的界面,注意选择的项目…

适配iOS 13 tabbar 标题字体不显示以及返回变蓝色的为问题
// 适配iOS 13 tabbar 标题字体不显示以及返回变蓝色的为问题 if (available(iOS 13.0, *)) {//[[UITabBar appearance] setUnselectedItemTintColor:Color_666666];}

企业不要求工程师资格认证_谁说工程师不能成为企业家?
企业不要求工程师资格认证by Preethi Kasireddy通过Preethi Kasireddy 谁说工程师不能成为企业家? (Who says engineers can’t become entrepreneurs?) A lot of people warned me not to walk away from my great position at Andreessen Horowitz to pursue so…

BestCoder Round #92 比赛记录
上午考完试后看到了晚上的BestCoder比赛,全机房都来参加 感觉压力好大啊QAQ,要被虐了. 7:00 比赛开始了,迅速点进了T1 大呼这好水啊!告诉了同桌怎么看中文题面 然后就开始码码码,4分16秒AC了第一题 7:05 开始看第二题 诶诶诶!!~~~~直接爆搜不久能过吗? 交了一发爆搜上去,AC了,…

[cocos2dx UI] CCLabelAtlas 为什么不显示最后一个字
CClabelAtlas优点,基本用法等我就不说了,这里说一个和美术配合时的一个坑!就是图片的最后一位怎么也不显示,如下图中的冒号不会显示 查了ASCII码表,这个冒号的值为58,就是在9(57)的后…

iOS 13 适配TextField 崩溃问题
iOS 13 之后直接通过以下方式修改Textfield的时候会出现报错信息 [_accountText setValue:Color_666666 forKeyPath:"_placeholderLabel.textColor"]; 报错信息 Access to UITextField’s _placeholderLabel ivar is prohibited. This is an application bug 解决…

测试django_如何像专业人士一样测试Django Signals
测试djangoby Haki Benita通过Haki Benita 如何像专业人士一样测试Django Signals (How to test Django Signals like a pro) For a better reading experience, check out this article on my website.为了获得更好的阅读体验,请在我的网站上查看此文章 。 Djang…

C#中静态方法的运用和字符串的常用方法(seventh day)
又来到了今天的总结时间,由于昨天在云和学院学的知识没有弄懂,今天老师又专门给我们非常详细地讲了一遍,在这里非常谢谢老师。O(∩_∩)O 话不多说,下面就开始为大家总结一下静态方法的运用和字符串的常用方法。 理论:静…

raid 磁盘阵列
mkdir /uuu #建挂载目录echo "- - -" > /sys/class/scsi_host/host2/scan #扫描新硬盘 lsblk #查看 parted /dev/sdb #分区 parted /dev/sdc lsblk mdadm -Cv /dev/md1 -l1 -n2 -c128 /dev/sd[b,c]1 #raid1配置, /dev/md1名字&#…