Rubocop 25行块大小和RSpec测试
一个典型的RSpec单元测试广泛使用嵌套的Ruby块来构建代码并利用DSL“魔术”使规范阅读像BDD语句:
describe Foo do
context "with a bar" do
before :each do
subject { Foo.new().add_bar }
end
it "looks like a baz" do
expect # etc
在理想的规格中,每个例子都可以相对简短和精确。 然而,通常有外部块增长到100行以上,因为RSpec结构以这种方式工作,并且不需要很多规范示例,其中每个示例可能具有几行特定设置,以便describe
块与所描述主题的代码相同或更大。
最近Rubocop的升级带来了一个新规则,即块应该不超过25行。 我不确定它的基本原理,因为它没有在Ruby风格指南中列出。 我可以看到它为什么会是一件好事,并添加到默认规则集中。 但是,在升级之后,我们的Rubocop测试多次尝试失败,并显示诸如tests/component_spec.rb:151:3: C: Block has too many lines. [68/25]
tests/component_spec.rb:151:3: C: Block has too many lines. [68/25]
通过Rubocop等代码度量工具,我喜欢有一个“使用默认值,链接到样式指南,完成工作”的策略。 (主要是因为辩论制表符vs空间和其他细节是在浪费时间,而IME从来没有得到解决)。这显然是不可能的,我们的两个核心数据质量工具不同意代码布局方法 - 或者至少我是这样解释结果的,我没有看到我们如何编写规格有任何内在的错误。
作为回应,我们简单地将Rubocop块大小规则设置为高阈值。 但这让我想知道 - 我错过了什么? RSpec是否使用了一种现在不受信任的代码布局方法,以及我有哪些合理的选项来减少RSpec测试中的块大小? 我可以看到重构代码以避免大块的方法,但它们无一例外都是纯粹符合Rubocop规则的丑陋黑客,例如将所有块分解为辅助函数:
def looks_like_a_baz
it "looks like a baz" do
expect # etc
end
end
def bar_context
context "with a bar" do
before :each do
subject { Foo.new().add_bar }
end
looks_like_a_baz
end
end
describe Foo do
bar_context
# etc
。 。 。 我的意思是,这是可行的,但以这种方式将一堆规范示例转换为辅助函数似乎与RSpec设计鼓励的可读方法相反。
除了想办法忽略它之外,还有什么可以做的吗?
我能找到关于这个主题的最接近的现存问题是RSpec&Rubocop / Ruby Style Guide,通过编辑测试模板可以解决这个问题。
最近Rubocop的升级带来了一个新规则,即块应该不超过25行。 我不确定它的基本原理,因为它没有在Ruby风格指南中列出。
过去,所有的警察都是以Ruby风格指南为基础的,而RuboCop是一种坚持社区规定的做法。
从那时起,方向发生了变化,RuboCop的范围也扩大了,以帮助开发人员确保其代码库的一致性。 这导致了两件事情:
这个警察属于第二类。
RSpec是否使用了一种现在不受信任的代码布局方法,以及我有哪些合理的选项来减少RSpec测试中的块大小?
简短的回答是否定的。 DSL仍然很酷。 :-)
这个警察在命令式编程意义上是针对大块的。 作为一般指南,它不适用于通常是声明式的DSL。 例如,在Rails中有一个很长的routes.rb
文件是非常好的。 这只是大型应用程序的自然结果,而不是风格违规。 (并且有很多测试纯粹是太棒了。)
现在,RuboCop非常聪明,但它不知道什么是DSL,所以我们不能自动忽略它们。 有人可能会争辩说我们可以排除流行框架的DSL入口方法,如Rails路由和RSpec规范。 不这样做的原因主要是:
/spec
目录是礼貌的,直到我们有一个适当的扩展系统,这可以通过rubocop-rspec
gem来处理。) 我的意思是,这是可行的,但以这种方式将一堆规范示例转换为辅助函数似乎与RSpec设计鼓励的可读方法相反。
底线是:RuboCop可以帮助我们编写更好的代码。 如果我们的应用程序设计是完全合理的,并且我们发现自己为了取悦RuboCop而让事情变得不可读,那么我们应该过滤,配置或禁用警察。 :-)
作为回应,我们简单地将Rubocop块大小规则设置为高阈值。 但这让我想知道 - 我错过了什么?
这是一个相当直率的工具,正如你暗示的那样,你可能会因为它而产生一些误报。 该警察有两种误报:
aasm
状态机声明。 在第一种情况下,最好的解决方案是排除文件或目录,并在第二种情况下使用内联禁用。
在你的情况下,你应该更新你的.rubocop.yml
:
Metrics/BlockLength:
Exclude:
- 'Rakefile'
- '**/*.rake'
- 'test/**/*.rb'
(请注意,您需要重新从默认配置迭代基本排除项,因为列表将被覆盖。)
免责声明:我是RuboCop的一位经常参与者,但不是维护者。 我从基础知识和基于以下许多问题的角度出发,充分了解了上述内容。
我没有在rubocop的默认配置中看到Style / Blocklength选项,所以我在.rubocop.yml中使用了这个解决方案:
Metrics/BlockLength:
ExcludedMethods: ['describe', 'context']
链接地址: http://www.djcxy.com/p/59307.html
上一篇: Rubocop 25 line block size and RSpec tests
下一篇: ruby