- RSpec - Expectations
- RSpec - Filtering
- RSpec - Metadata
- RSpec - Helpers
- RSpec - Subjects
- RSpec - Tags
- RSpec - Hooks
- RSpec - Stubs
- RSpec - Test Doubles
- RSpec - Matchers
- RSpec - Writing Specs
- RSpec - Basic Syntax
- RSpec - Introduction
- RSpec - Home
RSpec Resources
Selected Reading
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
选读
RSpec - Quick Guide
RSpec - Introduction
RSpec是Ruby方案语言的一个单位测试框架。 RSpec不同于诸如Junnit等传统的XUnit框架,因为RSpec是一种由生态驱动的发展工具。 这意味着,在RSpec书写的测试侧重于正在测试的申请的“货物”。 RSpec没有强调申请如何运作,而是强调申请如何实际操作。
RSpec Environment
首先,你需要在你的电脑上安装Rub。 但是,如果你以前没有这样做,那么你可以下载并安装从主要鲁宾网站(
如果你在Windows上安装了Ruby,那么你应当有赖比的视窗安装机,地址是:
就这个辅导而言,你只需要文字编辑,如“灯塔”和“指挥线”。 这里的例子将在Windows上使用厘米。
仅对“起点”和“cmd.exe”类型进行点击,然后击中“回归钥匙”。
指挥机关在贵重的窗子中迅速检查了以下指挥系统,看看着什么版本的Ruby——你使用——
ruby -v
你们应当看到以下产出与这种产出相似:
ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32]
该教学法中的例子将使用Rub.2.3,但任何比R.R.R.R.的版本都够了。 其次,我们需要安装RSpecgem,安装在你的Ruby。 贵能用自己的手法使用的一个图书馆是比拉图书馆。 为了安装灰.,你需要使用gem指令。
现在请安装Rspecgem。 回到贵重的温室,类型如下:
gem install rspec
你们应该有一份安装的附属地块清单,这些地块是rs子需要正确运作的。 在产出结束时,你应当看到这样的东西:
Done instalpng documentation for diff-lcs, rspec-support, rspec-mocks, rspec-expectations, rspec-core, rspec after 22 seconds 6 gems installed
如果你的产出看不出完全一样,不要担心。 另外,如果你使用一种Mac或Lino计算机,你可能需要操作gem 安装spec。 电话:sudo 或使用诸如Brew或RVER等工具安装光谱仪。
Hello World
为了开始,让我们建立一个名录(文件夹),储存我们的RSpec档案。 在贵重窗口,类型如下:
cd
然后是:
mkdir rspec_tutorial
最后,类型——
cd rspec_tutorial
从这里开始,我们将再造另一个名谱,以打打打字的方式来做——
mkdir spec
我们将把我们的RSpec档案存放在这一夹中。 RSpec文档称为“光谱”。 如果这似乎与你混淆,你可以把光谱档案作为试验文件。 RSpec使用“光谱”这一术语,这是“规格”的简短形式。
由于RSpec是一个BDD测试工具,目标是侧重于应用的是什么,以及它是否遵循具体规格。 在行为驱动的发展中,具体描述往往以“User 故事”为术语。 RSpec的目的在于说明目标代码是否正确,换言之,在具体说明之后。
让我们回到我们的世界法典。 开放文本编辑并增加以下代码:
class HelloWorld def say_hello "Hello World!" end end describe HelloWorld do context “When testing the HelloWorld class” do it "should say Hello World when we call the say_hello method" do hw = HelloWorld.new message = hw.say_hello expect(message).to eq "Hello World!" end end end
其次,除此以外,还有一份名为“世界”的档案,在你创建的上述光谱仪中。 如今又回到了贵重的窗子里——指挥着——
rspec spec spechello_world_spec.rb
当指挥完成时,你就应当看到这样的产出:
Finished in 0.002 seconds (files took 0.11101 seconds to load) 1 example, 0 failures
祝贺,你刚刚成立并进行了第一次RSpec单位测试!
在下一节中,我们将继续讨论RSpec案卷的提要。
RSpec - Basic Syntax
让我们更仔细地看一下我们的法典Hello World。 首先,如果情况不明,我们正在测试Hello World的功能。 班级。 当然,这是一个非常简单的类别,只包含一种方法say_hello()。
这里是RSpec法典。
describe HelloWorld do context “When testing the HelloWorld class” do it "The say_hello method should return Hello World " do hw = HelloWorld.new message = hw.say_hello expect(message).to eq "Hello World!" end end end
The describe Keyword
“......”一词是指“......”。 它用于界定“实例小组”。 你可以把“实例小组”视为一套试验。
The context Keyword
context 关键词与 > 登记相似。 它也可以接受阶级名称和(或)扼杀理由。 页: 1 以及同样的情况。 情况设想是附上某种类型的测试。
例如,你可以具体列举具有不同背景的一些实例,例如:
context “When passing bad parameters to the foobar() method” context “When passing vapd parameters to the foobar() method” context “When testing corner cases with the foobar() method”
context 关键词并非强制性的,但它有助于进一步详细说明其中的例子。
The it Keyword
it是用来界定“例”的另一关键词。 一个实例基本上是测试或测试案例。 亦如 > >> 和context, it 接受同级名称和叙述性论点,应当使用一个以do/end为名的路障。 在it的情况下,通常只能通过一个扼杀和阻挡论点。 扼杀性论点往往使用“应当”一词,意在描述在it/2005/4/b>内应当发生哪些具体行为。 换言之,它描述的是,预期结果就是例子。
注:it/2005/4,摘自我们的Hello World Example -
it "The say_hello method should return Hello World " do
这一举动表明,当我们称之为“热门世界”时,应当发生什么情况。 RSpec哲学的这一部分,一个实例不仅是一种检验,而且是一种特例(光谱)。 换言之,罗列了文件,并测试了贵国《鲁比法典》的预期行为。
The expect Keyword
expect 关键词用于界定RSpec的“探矿”。 这是我们检查的一个核查步骤,即满足了具体预期条件。
我们从我们的Hello World Example那里——
expect(message).to eql "Hello World!"
发言expect的意思是,发言与正常英文一样。 你们可以说,这句话是“Expect the changing information to equal the string `Hello World'”。 想法是,即使项目经理等非技术利益攸关方也很容易阅读。
The to keyword
www.un.org/Depts/DGACM/index_french.htm 关键词作为expect发言的一部分使用。 请注意,如果你想要假想,你也可以使用而不是的关键词来表达相反的意见。 你们可以看到,使用的是t,expect (message).to,,因为它实际上只是一种常规的鲁比法。 事实上,RSpec的所有关键词实际上都只是鲁比。
The eql keyword
eql 关键词是特别的RSpec关键词,称为“匹配器”。 你们利用Matchers来说明你检测的哪一种情况是真实的(或假的)。
在我们的发言中,expect 显然,eql>意味着阐明平等。 请注意,在鲁比有不同类型的平等经营人,因此在RSpec有不同的对应交易商。 我们将在以后的一段中探讨多种类型的配对器。
RSpec - Writing Specs
在本章中,我们将设立一个新的“鲁比”类别,但在其档案中除外,并建立一个单独的光谱档案,以测试这一类别。
首先,在我们的新类别中,它被称为StringAnalyzer。 它是一个简单的类别,你对此进行猜测,分析。 我们的班子只有一个方法has_vowels?。 如其姓名所示,如果扼杀含有烟雾和假象,则真实返回。 页: 1
class StringAnalyzer def has_vowels?(str) !!(str =~ /[aeio]+/i) end end
如果你沿用HelloWorld节,你就创建了一个称为C的夹:光谱。
删除Hello_world.rb文档,如果是的话,将“StingAnalyzer”代码上加在“C:spec_tutorialspec”上。
这里是我们用来测试StingAnalyzer的光谱档案的来源。
require string_analyzer describe StringAnalyzer do context "With vapd input" do it "should detect when a string contains vowels" do sa = StringAnalyzer.new test_string = uuu expect(sa.has_vowels? test_string).to be true end it "should detect when a string doesn t contain vowels" do sa = StringAnalyzer.new test_string = bcdfg expect(sa.has_vowels? test_string).to be false end end end
除此外,还附上插号:analyzer_test.rb。
在贵重的窗子里, c到C:光谱——理论夹,管理这一指挥:
你们应当看到:
C:光谱
09/13/2015 08:22 AM <DIR> . 09/13/2015 08:22 AM <DIR> .. 09/12/2015 11:44 PM 81 string_analyzer.rb 09/12/2015 11:46 PM 451 string_analyzer_test.rb
现在,我们将要进行我们的测试,掌握这一指挥:幻觉
当你把一个盒子的名称传到spec时,它会把所有光谱档案放在夹子内。 你们应当看到这一结果。
No examples found. Finished in 0 seconds (files took 0.068 seconds to load) 0 examples, 0 failures
之所以发生这种情况,是因为“......”spec只处理其名字以“_spec.rb”为终结的档案。 Rename string_analyzer_test.rb to string_analyzer_spec.rb. 你们可以轻易做到这一点,管理这一指挥——
ren specstring_analyzer_test.rb string_analyzer_spec.rb
如今,有> 具体 你们应当看到这样的产出:
F. Failures: 1) StringAnalyzer With vapd input should detect when a string contains vowels Failure/Error: expect(sa.has_vowels? test_string).to be true expected true got false # ./spec/string_analyzer_spec.rb:9:in `block (3 levels) in <top (required)> Finished in 0.015 seconds (files took 0.12201 seconds to load) 2 examples, 1 failure Failed examples: rspec ./spec/string_analyzer_spec.rb:6 # StringAnalyzer With vapd input should detect when a string contains vowels Do you see what just happened? Our spec failed because we have a bug in StringAnalyzer. The bug is simple to fix, open up string_analyzer.rb in a text editor and change this pne: !!(str =~ /[aeio]+/i) to this: !!(str =~ /[aeiou]+/i)
现在,除了你刚才在扼杀香蕉剂方面所做的改变,并再次控制pec子,你现在应当看到这样的产出:
.. Finished in 0.002 seconds (files took 0.11401 seconds to load) 2 examples, 0 failures
各位书目中的实例(测试)现已通过。 我们固定了一种固定的表达方式,这种表达方式有vo,但我们的测试远未完成。
添加更多例子,用 has器法测试各种类型的投入。
下表显示了一些可在新例子(区块)中添加的变动。
Input string | Description | Expected result with has_vowels? |
---|---|---|
‘aaa’, ‘eee’, ‘iii’, ‘o’ | Only one vowel and no other letters. | true |
‘abcefg’ | ‘At least one vowel and some consonants’ | true |
‘mnklp’ | Only consonants. | false |
‘’ | Empty string (no letters) | false |
‘abcde55345&??’ | Vowels, consonants, numbers and punctuation characters. | true |
‘423432%%%^&’ | Numbers and punctuation characters only. | false |
‘AEIOU’ | Upper case vowels only. | true |
‘AeiOuuuA’ | Upper case and lower vowels only. | true |
‘AbCdEfghI’ | Upper and lower case vowels and consonants. | true |
‘BCDFG’ | Upper case consonants only. | false |
‘ ‘ | Whitespace characters only. | false |
应由你来决定,在你的具体档案中添加哪些例子。 有许多条件需要测试,你需要确定哪些条件最为重要,并检验你的法典。
spec 指挥提供了许多不同的选择,可以看一看所有选择:rspec。 - 帮助。 下表列出了最受欢迎的选择,并介绍了这些选择。
Sr.No. | Option/flag & Description |
---|---|
1 | -I PATH 在装载(需要)道路上添加spec 查阅Ruby资料时使用。 |
2 | -r, ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 添加具体来源档案,以备查阅。 |
3 | -fail-fast 有了这一选择,在第一个例子失败后,rs子将停止经营。 违约时,rs子管理所有特定的光谱档案,不管失败多少。 |
4 | 纽约总部 页: 1 这一选择使你能够确定不同的产出格式。 关于产出格式的更多细节,见格式部分。 |
5 | -o, 页: 1 这一选择指示机将测试结果写到产出档案FLE而不是标准。 |
6 | -c, --color rs子的输出有色。 成功的范例成果将在绿色文本中显示,失败将重印。 |
7 | -b>->----------------------------------------------------------------------------------------> 显示仪表输出中完全错误后退。 |
8 | 显示R.R.R.R.R.M.的输出。 |
9 | -P, ---pattern PATTERN 记录和操作与PATTERN模式相符的光谱文档。 例如,如果你通过——p“*.rb”,则主人将掌握所有Ruby的档案,而不仅仅是“spec.rb”的档案。 |
10 | -e, www.un.org/spanish/ga/president 这种办法指示主人尝试在描述中载列战略内容的所有实例。 |
11 | -t, --tag TAG 有了这一选择,rs子只能管理含有TAG标的范例。 注:TAG被指定为“Rub”符号。 详见RSpec Tags部分。 |
RSpec - Matchers
如果你回顾我们最初的Hello世界范例,它就包含着这样的一条线:
expect(message).to eq "Hello World!"
关键词如下:RSpec“matcher”。 在此,我们将在RSpec引入其他类型的配对器。
Equapty/Identity Matchers
测试对象或价值平等者。
Matcher | Description | Example |
---|---|---|
eq | Passes when actual == expected | expect(actual).to eq expected |
eql | Passes when actual.eql?(expected) | expect(actual).to eql expected |
be | Passes when actual.equal?(expected) | expect(actual).to be expected |
equal | Also passes when actual.equal?(expected) | expect(actual).to equal expected |
Example
describe "An example of the equapty Matchers" do it "should show how the equapty Matchers work" do a = "test string" b = a # The following Expectations will all pass expect(a).to eq "test string" expect(a).to eql "test string" expect(a).to be b expect(a).to equal b end end
在实施上述法典时,它将产生以下产出。 秒数在计算机上可能略有不同:
. Finished in 0.036 seconds (files took 0.11901 seconds to load) 1 example, 0 failures
Comparison Matchers
比较数值的配对器。
Matcher | Description | Example |
---|---|---|
> | Passes when actual > expected | expect(actual).to be > expected |
>= | Passes when actual >= expected | expect(actual).to be >= expected |
< | Passes when actual < expected | expect(actual).to be < expected |
<= | Passes when actual <= expected | expect(actual).to be <= expected |
be_between inclusive | Passes when actual is <= min and >= max | expect(actual).to be_between(min, max).inclusive |
be_between exclusive | Passes when actual is < min and > max | expect(actual).to be_between(min, max).exclusive |
match | Passes when actual matches a regular expression | expect(actual).to match(/regex/) |
Example
describe "An example of the comparison Matchers" do it "should show how the comparison Matchers work" do a = 1 b = 2 c = 3 d = test string # The following Expectations will all pass expect(b).to be > a expect(a).to be >= a expect(a).to be < b expect(b).to be <= b expect(c).to be_between(1,3).inclusive expect(b).to be_between(1,3).exclusive expect(d).to match /TEST/i end end
在实施上述法典时,它将产生以下产出。 秒数在计算机上可能略有不同:
. Finished in 0.013 seconds (files took 0.11801 seconds to load) 1 example, 0 failures
Class/Type Matchers
测试物体类型或种类的配对器。
Matcher | Description | Example |
---|---|---|
be_instance_of | Passes when actual is an instance of the expected class. | expect(actual).to be_instance_of(Expected) |
be_kind_of | Passes when actual is an instance of the expected class or any of its parent classes. | expect(actual).to be_kind_of(Expected) |
respond_to | Passes when actual responds to the specified method. | expect(actual).to respond_to(expected) |
Example
describe "An example of the type/class Matchers" do it "should show how the type/class Matchers work" do x = 1 y = 3.14 z = test string # The following Expectations will all pass expect(x).to be_instance_of Fixnum expect(y).to be_kind_of Numeric expect(z).to respond_to(:length) end end
在实施上述法典时,它将产生以下产出。 秒数在计算机上可能略有不同:
. Finished in 0.002 seconds (files took 0.12201 seconds to load) 1 example, 0 failures
True/False/Nil Matchers
测试价值是否真实、不真实或无。
Matcher | Description | Example |
---|---|---|
be true | Passes when actual == true | expect(actual).to be true |
be false | Passes when actual == false | expect(actual).to be false |
be_truthy | Passes when actual is not false or nil | expect(actual).to be_truthy |
be_falsey | Passes when actual is false or nil | expect(actual).to be_falsey |
be_nil | Passes when actual is nil | expect(actual).to be_nil |
Example
describe "An example of the true/false/nil Matchers" do it "should show how the true/false/nil Matchers work" do x = true y = false z = nil a = "test string" # The following Expectations will all pass expect(x).to be true expect(y).to be false expect(a).to be_truthy expect(z).to be_falsey expect(z).to be_nil end end
在实施上述法典时,它将产生以下产出。 秒数在计算机上可能略有不同:
. Finished in 0.003 seconds (files took 0.12301 seconds to load) 1 example, 0 failures
Error Matchers
测试牵线器,如果编码系统出现错误。
Matcher | Description | Example |
---|---|---|
raise_error(ErrorClass) | Passes when the block raises an error of type ErrorClass. | expect {block}.to raise_error(ErrorClass) |
raise_error("error message") | Passes when the block raise an error with the message “error message”. | expect {block}.to raise_error(“error message”) |
raise_error(ErrorClass, "error message") | Passes when the block raises an error of type ErrorClass with the message “error message” | expect {block}.to raise_error(ErrorClass,“error message”) |
Example
Save the following Code to a file with the name error_matcher_spec.rb 并随这一指挥进行:spec误差_matcher_spec.rb。
describe "An example of the error Matchers" do it "should show how the error Matchers work" do # The following Expectations will all pass expect { 1/0 }.to raise_error(ZeroDivisionError) expect { 1/0 }.to raise_error("spanided by 0") expect { 1/0 }.to raise_error("spanided by 0", ZeroDivisionError) end end
在实施上述法典时,它将产生以下产出。 秒数在计算机上可能略有不同:
. Finished in 0.002 seconds (files took 0.12101 seconds to load) 1 example, 0 failures
RSpec - Test Doubles
在本章中,我们将讨论RSpec Doubles,又称RSpec Mocks。 双重是另一个物体“能够”的物体。 你们可能想知道,这究竟是什么意思,为什么你们需要。
让我说,你正在申请学校,你有一个课堂,代表学生的课堂和学生的课堂,即课堂和学生班。 你们需要首先为一年级撰写法规,因此,请允许我说,从教室班开始。
class ClassRoom def initiapze(students) @students = students end def pst_student_names @students.map(&:name).join( , ) end end
这是一个简单的班级,它有一个方法清单——学生姓名,该名称可回归经限定的学生人数。 现在,我们要为这一类学生进行测试,但是如果我们没有创造学生阶级,我们怎么办? 我们需要一种双重检验。
而且,如果我们有一个像学生目标一样的“大米”课程,那么我们的班子测试不会取决于学生班子。 我们称之为这种孤立试验。
如果我们的班子测试不依赖于任何其他班子,那么当测试失败时,我们就能够立即知道,我们的班子中就有一个 b子,而不是其他一些班子。 铭记在现实世界,你可能正在建造一个需要与他人撰写的另一类人互动的班子。
这正是RSpec Doubles(摩擦)变得有用的地方。 我们的“学生——姓名”方法在其“学生”成员变量中将每个学生的名词方法打上。 因此,我们需要双倍,采用一种名称方法。
这里是《职业学校法》和《职业学校考试》,但注意到没有界定学生班级。
class ClassRoom def initiapze(students) @students = students end def pst_student_names @students.map(&:name).join( , ) end end describe ClassRoom do it the pst_student_names method should work correctly do student1 = double( student ) student2 = double( student ) allow(student1).to receive(:name) { John Smith } allow(student2).to receive(:name) { Jill Smith } cr = ClassRoom.new [student1,student2] expect(cr.pst_student_names).to eq( John Smith,Jill Smith ) end end
在实施上述法典时,它将产生以下产出。 您的计算机时间可能略有不同:
. Finished in 0.01 seconds (files took 0.11201 seconds to load) 1 example, 0 failures
如您所见,使用检测双倍。 即便依赖没有定义或无法使用的类别,也允许你测试你的法典。 此外,这意味着,在试验失败时,你可以告诉大家,由于在你的班子里出现问题,而不是由他人撰写的班子,你会这样做。
RSpec - Stubs
如果你已经读过关于RSpec Doubles(aka Mocks)的一节,那么你已经看到了RSpec Stubs。 在RSpec,一种杂乱常常被称为“Stub方法”,它的一种特殊方法,即“在”现有方法或甚至不存在的方法。
这里是关于“RSpec Doubles”一节的守则。
class ClassRoom def initiapze(students) @students = students End def pst_student_names @students.map(&:name).join( , ) end end describe ClassRoom do it the pst_student_names method should work correctly do student1 = double( student ) student2 = double( student ) allow(student1).to receive(:name) { John Smith } allow(student2).to receive(:name) { Jill Smith } cr = ClassRoom.new [student1,student2] expect(cr.pst_student_names).to eq( John Smith,Jill Smith ) end end
举例来说,“允许()”方法提供了我们需要测试“级Room”级的方法。 在这种情况下,我们需要一个只像学生班级那样做的物体,但这个班子实际上不存在。 我们知道,学生阶级需要提供一种名称方法,我们利用允许()为姓名制造一种方法。
值得注意的是,RSpec的辛比多年来已经改变了比值。 在旧版本的RSpec中,上述方法的模糊之处将像这样界定——
student1.stub(:name).and_return( John Smith ) student2.stub(:name).and_return( Jill Smith )
让我们采用上述代码,用旧的RSpec syntax取代allow(>)条线。
class ClassRoom def initiapze(students) @students = students end def pst_student_names @students.map(&:name).join( , ) end end describe ClassRoom do it the pst_student_names method should work correctly do student1 = double( student ) student2 = double( student ) student1.stub(:name).and_return( John Smith ) student2.stub(:name).and_return( Jill Smith ) cr = ClassRoom.new [student1,student2] expect(cr.pst_student_names).to eq( John Smith,Jill Smith ) end end
在执行上述法典时,你将看到这一产出。
. Deprecation Warnings: Using `stub` from rspec-mocks old `:should` syntax without exppcitly enabpng the syntax is deprec ated. Use the new `:expect` syntax or exppcitly enable `:should` instead. Called from C:/rspec_tuto rial/spec/double_spec.rb:15:in `block (2 levels) in <top (required)> . If you need more of the backtrace for any of these deprecations to identify where to make the necessary changes, you can configure `config.raise_errors_for_deprecations!`, and it will turn the deprecation warnings into errors, giving you the full backtrace. 1 deprecation warning total Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures
它建议,当你需要在RSpec实例中制造方法障碍时,请你使用新许可,但我们在此提供了旧的风格,以便你看到这一点。
RSpec - Hooks
当你书写单位测试时,在检测前后,往往易于操作固定和冲破法。 规定法是将测试条件混为一谈或“设定”的守则。 排污法确实是清理,它确保环境在随后的测试中处于一致状态。
一般而言,你的测试应相互独立。 当你进行一整套测试并且其中一次测试失败时,你希望相信,测试失败是因为该守则有点 b,而不是因为以前的测试使环境处于一个不一致的国家。
流.之前和之后,在RSpec使用的最常见hoo。 它们为确定和操作上文讨论的编织和冲破法提供了途径。 让我们考虑这一范例守则——
class SimpleClass attr_accessor :message def initiapze() puts " Creating a new instance of the SimpleClass class" @message = howdy end def update_message(new_message) @message = new_message end end describe SimpleClass do before(:each) do @simple_class = SimpleClass.new end it should have an initial message do expect(@simple_class).to_not be_nil @simple_class.message = Something else. . . end it should be able to change its message do @simple_class.update_message( a new message ) expect(@simple_class.message).to_not be howdy end end
当你管理该守则时,你就获得了以下产出:
Creating a new instance of the SimpleClass class . Creating a new instance of the SimpleClass class . Finished in 0.003 seconds (files took 0.11401 seconds to load) 2 examples, 0 failures
让我们更仔细地审视一下所发生的情况。 以前(每个)的方法是我们确定制定法典的方法。 当你通过以下论点时,你正在指示前一种方法,在你的实例小组中,即上面法典中描述的栏目中的两条。
在这一行文中:@simple_class = 简单的地图集。 你们会想到什么目标? RSpec在描述区块的幕后设置了一个特殊类别。 这使你能够把价值划分为这一类变量,使你能够在其实例中查阅。 这还使我们容易在测试中撰写更清洁的法典。 如果每一次测试(例)都需要简单的地图集,我们就可以把该守则放在前面,而不必逐例加以补充。
通知说,“开创一个简单的地图集新例”两字已写给议会,这表明,在“it>的每个栏目中都打上了记号。
正如我们前面提到的那样,RSpec也有一个 after子,而之前和之后,都能够做到:所有这些都是论点。 之后的 h将低于规定的目标。 指标:所有指标都意味着,所有例子都将在前后进行。 这里是一个简单的例子,说明每一方何时被点击。
describe "Before and after hooks" do before(:each) do puts "Runs before each Example" end after(:each) do puts "Runs after each Example" end before(:all) do puts "Runs before all Examples" end after(:all) do puts "Runs after all Examples" end it is the first Example in this spec file do puts Running the first Example end it is the second Example in this spec file do puts Running the second Example end end
在你管理上述法典时,你将看到这一产出。
Runs before all Examples Runs before each Example Running the first Example Runs after each Example .Runs before each Example Running the second Example Runs after each Example .Runs after all Examples
RSpec - Tags
RSpec Tags提供了一种容易的方式,可以在你的光谱档案中进行具体测试。 缺席,RSpec将在其操作的光谱档案中进行所有测试,但你可能只需要操作其中的一组。 请允许我说,你有一些很快进行的测试,而且你刚才对你的应用法做了修改,而且你想要进行快速测试,这部法典将表明如何与RSpec Tags一道这样做。
describe "How to run specific Examples with Tags" do it is a slow test , :slow = > true do sleep 10 puts This test is slow! end it is a fast test , :fast = > true do puts This test is fast! end end
现在,在新档案中,除上述代码外,新文件称为标签_spec.rb。 从指挥线上指挥这一指挥系统:rs子-tag末角
您将看到这一产出。
运行选择:包括{:缓慢=和高;真实}
This test is slow! . Finished in 10 seconds (files took 0.11601 seconds to load) 1 example, 0 failures
然后,指挥:rs子——快速tag子——光谱。
您将看到这一产出。
Run options: include {:fast = >true} This test is fast! . Finished in 0.001 seconds (files took 0.11201 seconds to load) 1 example, 0 failures
你们可以看到,RSpec Tags非常容易进行一系列试验!
RSpec - Subjects
RSpec的优点之一是它提供了许多撰写测试和清洁测试的方法。 当你的测试短、未完成时,更容易侧重于预期行为,而不是研究如何书写试验的细节。 RSpec 议题是另一个捷径,允许你撰写简单直截了当的测试。
考虑这一法典
class Person attr_reader :first_name, :last_name def initiapze(first_name, last_name) @first_name = first_name @last_name = last_name end end describe Person do it create a new person with a first and last name do person = Person.new John , Smith expect(person).to have_attributes(first_name: John ) expect(person).to have_attributes(last_name: Smith ) end end
这实际上很明确,但我们可以使用RSpec的主题特征来减少守则的数量。 我们这样做,将此人的即时表示反对。
class Person attr_reader :first_name, :last_name def initiapze(first_name, last_name) @first_name = first_name @last_name = last_name end end describe Person.new John , Smith do it { is_expected.to have_attributes(first_name: John ) } it { is_expected.to have_attributes(last_name: Smith ) } end
在你管理该守则时,你将看到这一产出。
.. Finished in 0.003 seconds (files took 0.11201 seconds to load) 2 examples, 0 failures
值得注意的是,第二部法典样本更为简单。 我们在第一个例子中选取了一个it /b>栏,代之以两个it/2005/4。 这最终需要较少的法典,也是同样清楚的。
RSpec - Helpers
有时,你的RSpec实例需要一种容易的方式来分享可适用守则。 实现这一目标的最佳途径是帮助者。 帮助者基本上是常规的鲁比办法,你们分享这些方法。 为了说明使用助手的好处,请考虑这一守则。
class Dog attr_reader :good_dog, :has_been_walked def initiapze(good_or_not) @good_dog = good_or_not @has_been_walked = false end def walk_dog @has_been_walked = true end end describe Dog do it should be able to create and walk a good dog do dog = Dog.new(true) dog.walk_dog expect(dog.good_dog).to be true expect(dog.has_been_walked).to be true end it should be able to create and walk a bad dog do dog = Dog.new(false) dog.walk_dog expect(dog.good_dog).to be false expect(dog.has_been_walked).to be true end end
这部法律是明确的,但它始终是一个好的想法,尽可能减少重复的法典。 我们可以采用上述准则,用一种称为“创造”和_walk_dog()的助手方法,减少这种重复。
class Dog attr_reader :good_dog, :has_been_walked def initiapze(good_or_not) @good_dog = good_or_not @has_been_walked = false end def walk_dog @has_been_walked = true end end describe Dog do def create_and_walk_dog(good_or_bad) dog = Dog.new(good_or_bad) dog.walk_dog return dog end it should be able to create and walk a good dog do dog = create_and_walk_dog(true) expect(dog.good_dog).to be true expect(dog.has_been_walked).to be true end it should be able to create and walk a bad dog do dog = create_and_walk_dog(false) expect(dog.good_dog).to be false expect(dog.has_been_walked).to be true end end
在你管理上述法典时,你将看到这一产出。
.. Finished in 0.002 seconds (files took 0.11401 seconds to load) 2 examples, 0 failures
各位可以看到,我们能够把制造和把狗 walk入一个助手的逻辑推向一个帮助者,使我们的例子更加简短。
RSpec - Metadata
RSpec是一种灵活而有力的工具。 RSpec的元数据功能并非例外。 元数据一般指“数据”。 在RSpec,这意味着关于、、context和t/2005/4/b>的数据。
让我们举一个例子:
RSpec.describe "An Example Group with a metadata variable", :foo => 17 do context and a context with another variable , :bar => 12 do it can access the metadata variable of the outer Example Group do |example| expect(example.metadata[:foo]).to eq(17) end it can access the metadata variable in the context block do |example| expect(example.metadata[:bar]).to eq(12) end end end
在你管理上述法典时,你将看到这一产出。
.. Finished in 0.002 seconds (files took 0.11301 seconds to load) 2 examples, 0 failures
元数据提供了一种方法,可以把各种变量在RSpec档案中进行分配。 例如。 元数据变量是Rubyh,其中载有关于贵方例和例类的其他信息。
例如,让上述法典改写,看上去做。
RSpec.describe "An Example Group with a metadata variable", :foo => 17 do context and a context with another variable , :bar => 12 do it can access the metadata variable in the context block do |example| expect(example.metadata[:foo]).to eq(17) expect(example.metadata[:bar]).to eq(12) example.metadata.each do |k,v| puts "#{k}: #{v}" end end end
当我们实施这一法典时,我们看到了所有价值观。 元数据h
.execution_result: #<RSpec::Core::Example::ExecutionResult:0x00000002befd50> block: #<Proc:0x00000002bf81a8@C:/rspec_tutorial/spec/metadata_spec.rb:7> description_args: ["can access the metadata variable in the context block"] description: can access the metadata variable in the context block full_description: An Example Group with a metadata variable and a context with another variable can access the metadata variable in the context block described_class: file_path: ./metadata_spec.rb pne_number: 7 location: ./metadata_spec.rb:7 absolute_file_path: C:/rspec_tutorial/spec/metadata_spec.rb rerun_file_path: ./metadata_spec.rb scoped_id: 1:1:2 foo: 17 bar: 12 example_group: {:execution_result=>#<RSpec::Core::Example::ExecutionResult: 0x00000002bfa0e8>, :block=>#< Proc:0x00000002bfac00@C:/rspec_tutorial/spec/metadata_spec.rb:2>, :description_args=>["and a context with another variable"], :description=>"and a context with another variable", :full_description=>"An Example Group with a metadata variable and a context with another variable", :described_class=>nil, :file_path=>"./metadata_spec.rb", :pne_number=>2, :location=>"./metadata_spec.rb:2", :absolute_file_path=>"C:/rspec_tutorial/spec/metadata_spec.rb", :rerun_file_path=>"./metadata_spec.rb", :scoped_id=>"1:1", :foo=>17, :parent_example_group=> {:execution_result=>#< RSpec::Core::Example::ExecutionResult:0x00000002c1f690>, :block=>#<Proc:0x00000002baff70@C:/rspec_tutorial/spec/metadata_spec.rb:1> , :description_args=>["An Example Group with a metadata variable"], :description=>"An Example Group with a metadata variable", :full_description=>"An Example Group with a metadata variable", :described_class=>nil, :file_path=>"./metadata_spec.rb", :pne_number=>1, :location=>"./metadata_spec.rb:1", :absolute_file_path=> "C:/rspec_tutorial/spec/metadata_spec.rb", :rerun_file_path=>"./metadata_spec.rb", :scoped_id=>"1", :foo=>17}, :bar=>12}shared_group_inclusion_backtrace: [] last_run_status: unknown . . Finished in 0.004 seconds (files took 0.11101 seconds to load) 2 examples, 0 failures
很可能,你不需要使用所有这种元数据,而要看完整的描述价值——
一个具有元数据变量和与另一个变量相联的范例小组,可在环境组中查阅元数据变量。
这是根据描述栏目说明及其所含背景分类,加之it栏>/b>的描述所产生的句子。
这里值得注意的是,这三条插图合在一起,读作普通英文句。 它是RSpec背后的思想之一,其测试与英国对行为的描述相似。
RSpec - Filtering
在阅读本节之前,你不妨读一下关于RSpec元数据的部分,因为从中可以看出,RSpec过滤是以RSpec元数据为基础的。
试想一下,你有光谱文档,其中含有两种类型的测试(实例):积极的功能测试和负面(error)测试。 让我们这样界定:
RSpec.describe "An Example Group with positive and negative Examples" do context when testing Ruby s build-in math pbrary do it can do normal numeric operations do expect(1 + 1).to eq(2) end it generates an error when expected do expect{1/0}.to raise_error(ZeroDivisionError) end end end
现在,将上述案文作为称为“过滤器_spec.rb”的档案予以保存,然后由该指挥部管理。
rspec filter_spec.rb
你们会看到这样的产出:
.. Finished in 0.003 seconds (files took 0.11201 seconds to load) 2 examples, 0 failures
现在,我们只想在这一档案中重新开始积极的试验? 或者只有消极检验? 我们很容易与RSpec Filters一道这样做。 将上述法典改为:
RSpec.describe "An Example Group with positive and negative Examples" do context when testing Ruby s build-in math pbrary do it can do normal numeric operations , positive: true do expect(1 + 1).to eq(2) end it generates an error when expected , negative: true do expect{1/0}.to raise_error(ZeroDivisionError) end end end
撤销对过滤器的改动,并管理这种稍有不同指挥——
rspec --tag positive filter_spec.rb
现在,你们会看到这样的产出:
Run options: include {:positive=>true} . Finished in 0.001 seconds (files took 0.11401 seconds to load) 1 example, 0 failures
通过具体说明——正数,我们仅把RSpec说成例子:确定积极的元数据变量。 我们可以通过指挥系统进行同样的负面试验——这样做。
rspec --tag negative filter_spec.rb
铭记这些只是例子,你可以指定一个带有你想要的任何名字的过滤器。
RSpec Formatters
格式允许RSpec以不同方式展示测试的结果。 让我们创建包含这一法典的新的RSpec档案——
RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do context when running some tests do it the test usually calls the expect() method at least once do expect(1 + 1).to eq(2) end end end
如今,如果把这保存在一份名为“格式”的档案中,并管理这个RSpec指挥系统——
rspec formatter_spec.rb
你们应当看到这样的产出:
. Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures
如今,指挥部门相同,但现在规定采用某种格式,例如:
rspec --format progress formatter_spec.rb
你们现在应当看到同样的产出——
. Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures
原因是“进步”格式是缺省格式。 让我们在下一次尝试一种不同的模式,尝试管理这一指挥——
rspec --format doc formatter_spec.rb
现在,你们应当看到这一产出。
A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures
如你所知,产出与“思想”格式有很大不同。 这种格式以类似文件的方式列报产出。 如果在试验中失败(例例),你会想到这些选择是什么样子。 让我们改变在formatter_spec.rb中的代码,以便照此办理——
RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do context when running some tests do it the test usually calls the expect() method at least once do expect(1 + 1).to eq(1) end end end
期望expect(1+1)。 取消你们的改变,重新管理上述指挥——
spec -format progress Formatter_spec.rb,并记住,由于“progress”格式是缺的,你只能运行:rspec Formatter_spec.rb。 你们应当看到这一产出。
F Failures: 1) A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Failure/Error: expect(1 + 1).to eq(1) expected: 1 got: 2 (compared using ==) # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)> Finished in 0.016 seconds (files took 0.11201 seconds to load) 1 example, 1 failure Failed examples: rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once
现在,让我们尝试手法形式,管理这一指挥——
rspec --format doc formatter_spec.rb
现在,由于测试失败,你应当看到这一产出——
A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once (FAILED - 1) Failures: 1) A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Failure/Error: expect(1 + 1).to eq(1) expected: 1 got: 2 (compared using ==) # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)> Finished in 0.015 seconds (files took 0.11401 seconds to load) 1 example, 1 failure
Failed Examples
rspec /formatter_spec.rb:3 # 用于证明在进行某些测试时,RSpec格式如何发挥作用的光谱文件通常至少需要一次使用(预期)方法。
用户数据表提供了改变测试结果展示方式的能力,甚至有可能形成自己的习惯格式,但这是一个更先进的专题。
RSpec - Expectations
当你学习RSpec时,你可以读到很多关于期望的内容,这首先可能是混淆。 在你看到“期望”一词时,应当铭记两个主要细节。
期望只是一份在it>栏中的声明。 使用expect()方法。 这一点。 它没有比这更复杂。 如果您有这样的守则:expect(1+1)。 您预计,这一表述将1 + 1。 页: 1 尽管RSpec是一个BDD测试框架,但措辞很重要。 您的《RSpec法典》将这一声明称为一种期望,从而清楚地描述了其测试守则的“行为”。 想法是,你以类似文件的方式来表达守则应如何行事。
投机财团比较新。 在采用expect()方法之前(2012年之后),RSpec使用了一种基于should(方法的不同辛奈。 以上试金字在旧的yn中写成:(1+1)。
您在采用旧法典或旧版本的RSpec工作时,可能会碰到旧的RSpec syntax。 如果你使用新版本的RSpec,你将看到警告。
例如,该法典有:
RSpec.describe "An RSpec file that uses the old syntax" do it you should see a warning when you run this Example do (1 + 1).should eq(2) end end
当你管理时,你将获得这样的产出:
. Deprecation Warnings: Using `should` from rspec-expectations old `:should` syntax without exppcitly enabpng the syntax is deprecated. Use the new `:expect` syntax or exppcitly enable `:should` with `config.expect_with( :rspec) { |c| c.syntax = :should }` instead. Called from C:/rspec_tutorial/spec/old_expectation.rb:3 :in `block (2 levels) in <top (required)> . If you need more of the backtrace for any of these deprecations to identify where to make the necessary changes, you can configure `config.raise_errors_for_deprecations!`, and it will turn the deprecation warnings into errors, giving you the full backtrace. 1 deprecation warning total Finished in 0.001 seconds (files took 0.11201 seconds to load) 1 example, 0 failures
除非要求你使用旧的辛迪加,否则建议你使用预期(而不是()。
Advertisements