Skip to content
  • Edouard CHIN's avatar
    1cf8b6c2
    `SetupAndTeardown` has few caveats that breaks libraries: · 1cf8b6c2
    Edouard CHIN authored
    - In #32472 I introduced a fix in order for all `after_teardown` method provided by libraries and Rails to run, even if the application's `teardown` method raised an error (That's the default minitest behavior). However this change wasn't enough and doesn't take in consideration the ancestors chain.
      If a library's module containing an `after_teardown` method get included after the `SetupAndTeardown` module (one example is the [ActiveRecord::TestFixtures module](https://github.com/rails/rails/blob/7d2400ab61c8e3ed95e14d03ba3844e8ba2e36e4/activerecord/lib/active_record/fixtures.rb#L855-L856), then the ancestors of the test class would look something like
      ```ruby
        class MyTest < ActiveSupport::TestCase
        end
    
        puts MyTest.ancestors # [MyTest, ActiveSupport::TestCase, ActiveRecord::TestFixtures, ActiveSupport::Testing::SetupAndTeardown]
      ```
      Any class/module in the ancestors chain that are **before** the `ActiveSupport::Testing::SetupAndTeardown` will behave incorrectly:
        - Their `before_setup` method will get called **after** all regular setup method
        - Their `after_teardown` method won't even get called in case an exception is raised inside a regular's test `teardown`
    
      A simple reproduction script of the problem here https://gist.github.com/Edouard-chin/70705542a59a8593f619b02e1c0a188c
    
    - One solution to this problem is to have the `AS::SetupAndTeardown` module be the very first in the ancestors chain. By doing that we ensure that no `before_setup` / `after_teardown` get executed prior to running the teardown callbacks
    1cf8b6c2
    `SetupAndTeardown` has few caveats that breaks libraries:
    Edouard CHIN authored
    - In #32472 I introduced a fix in order for all `after_teardown` method provided by libraries and Rails to run, even if the application's `teardown` method raised an error (That's the default minitest behavior). However this change wasn't enough and doesn't take in consideration the ancestors chain.
      If a library's module containing an `after_teardown` method get included after the `SetupAndTeardown` module (one example is the [ActiveRecord::TestFixtures module](https://github.com/rails/rails/blob/7d2400ab61c8e3ed95e14d03ba3844e8ba2e36e4/activerecord/lib/active_record/fixtures.rb#L855-L856), then the ancestors of the test class would look something like
      ```ruby
        class MyTest < ActiveSupport::TestCase
        end
    
        puts MyTest.ancestors # [MyTest, ActiveSupport::TestCase, ActiveRecord::TestFixtures, ActiveSupport::Testing::SetupAndTeardown]
      ```
      Any class/module in the ancestors chain that are **before** the `ActiveSupport::Testing::SetupAndTeardown` will behave incorrectly:
        - Their `before_setup` method will get called **after** all regular setup method
        - Their `after_teardown` method won't even get called in case an exception is raised inside a regular's test `teardown`
    
      A simple reproduction script of the problem here https://gist.github.com/Edouard-chin/70705542a59a8593f619b02e1c0a188c
    
    - One solution to this problem is to have the `AS::SetupAndTeardown` module be the very first in the ancestors chain. By doing that we ensure that no `before_setup` / `after_teardown` get executed prior to running the teardown callbacks
Loading