This is modified from the MiniTest docs (under Customizable Test Runner Types).
class Burger
  def initialize
    puts "YOU CREATED A BURGER"
  end
  def has_cheese?
    true
  end
  def has_pickle?
    false
  end
end
gem 'minitest'
require 'minitest/unit'
MiniTest::Unit.autorun
class MyMiniTest
  class Unit < MiniTest::Unit
    def before_suites
      # code to run before the first test
      p "Before everything"
    end
    def after_suites
      # code to run after the last test
      p "After everything"
    end
    def _run_suites(suites, type)
      begin
        before_suites
        super(suites, type)
      ensure
        after_suites
      end
    end
    def _run_suite(suite, type)
      begin
        suite.before_suite if suite.respond_to?(:before_suite)
        super(suite, type)
      ensure
        suite.after_suite if suite.respond_to?(:after_suite)
      end
    end
  end
end
MiniTest::Unit.runner = MyMiniTest::Unit.new
class BurgerTest < MiniTest::Unit::TestCase
  def self.before_suite
    p "hi"
  end
  def self.after_suite
    p "bye"
  end
  def setup
    @burger = Burger.new
  end
  def test_has_cheese
    assert_equal true, @burger.has_cheese?
  end
  def test_has_pickle
    assert_equal false, @burger.has_pickle?
  end
end
Note that you I included gem 'minitest' to use the gem instead of the bundled version which didn't have the MiniTest::Unit.runner method. Here's the output.
Run options: --seed 49053
# Running tests:
"Before everything"
"hi"
YOU CREATED A BURGER
.YOU CREATED A BURGER
."bye"
"After everything"
Finished tests in 0.000662s, 3021.1480 tests/s, 3021.1480 assertions/s.
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
So it calls #setup twice, but .before_suite and .after_suite only once, which is what you are looking for I think.