【问题标题】:How to organize minitest/unit tests?如何组织小测试/单元测试?
【发布时间】:2012-12-25 04:33:07
【问题描述】:

在将 RSpec 用于多个项目之后,我将尝试使用 minitest/unit。到目前为止我很喜欢它,但我想念使用描述/上下文块以合乎逻辑的方式对我的测试/规范进行分组。

我知道 minitest/spec 提供了这个功能,但我喜欢 minitest/unit 感觉更接近准系统 Ruby。

是否有任何 gem 为 minitest/unit 提供描述/上下文支持?或者,我应该只在 minitest/unit 中处理我冗长、杂乱无章的测试文件吗?

【问题讨论】:

    标签: ruby-on-rails ruby minitest


    【解决方案1】:

    我知道有几个从 RSpec 来到 minitest 的人在同一个问题上苦苦挣扎。他们喜欢使用描述/上下文块进行嵌套的能力,并希望继续进行 minitest。有几种解决方案:

    1. 使用 minitest 的规范 DSL:虽然存在细微差别,但规范 DSL 为您提供了 rspec DSL 的大部分(全部?)优点。最大的不同是缺少context 块。但您也可以轻松地使用 describe 代替它,一切都会如您所愿。
    2. 使用目录和文件:我更喜欢这个选项。我不喜欢滚动浏览一个 300 行的测试文件,无论它使用的是规范 DSL 还是经典的 xUnit 风格。我发现嵌套无关测试没有帮助。代码理解的相同规则适用于测试。所以分手吧。创建一个目录并在其中放置多个文件。

    以下是我的测试文件组织方式的示例:

    test/
         models/
                user/
                     authentication_test.rb
                     email_test.rb
                     reservation_test.rb
                     user_test.rb
                     username_test.rb
    

    无论我使用的是规范 DSL 还是 xUnit 样式,我都使用这种结构。使用规范 DSL 时,我会在描述块中指定要测试的内容,如下所示:

    require "minitest_helper"
    
    describe User, :authentications do
    
      before do
        # ...
    

    【讨论】:

      【解决方案2】:

      您还可以将多个类放入一个测试文件中:

      module PizzaTest
        class Isolation < ActiveSupport::TestCase
          test "is awesome by default" do
            assert Pizza.new.awesome?
          end
        end
      
        class Integration < ActiveSupport::TestCase
          fixtures :all
      
          test "is awesome too" do
            pizzas('one-with-everything').awesome?
          end
        end
      end
      

      甚至嵌套测试类:

      class PizzaTest < ActiveSupport::TestCase
        test "is awesome by default" do
          assert Pizza.new.awesome?
        end
      
        class Integration < ActiveSupport::TestCase
          fixtures :all
      
          test "is awesome too" do
            assert pizzas('one-with-everything').awesome?
          end
        end
      end
      

      【讨论】:

        【解决方案3】:

        我更喜欢这种方式(只是一点点),但我认为它更容易遵循:

        class ConventionalNameTest < ActiveSupport::TestCase
          class ContextTest < ConventionalNameTest
            # so much stuff...
          end
          class AnotherContextTest < ConventionalNameTest
            # and some more...
          end
        

        【讨论】:

        • 能够在一个测试文件中多次定义setup,并远离规范DSL
        • 这是我尝试过的方法。我发现的问题是 Minitest 最终会在每个嵌套类上运行从 ConventionalNameTest 继承的所有测试用例。
        • @YuriGhensev 同样,我很想知道如何解决这个问题。
        • @RafałCieślak 只是不要在父类中定义测试,只在子类中。父类只能有setup/teardown
        • @SandroL 谢谢,这就是我最终要做的!这种方法唯一的小不便是,当我决定需要在一个类中嵌套测试时,我必须将所有现有的测试提取到一个单独的测试中。但它仍然有效。