diff --git a/gem/.gitignore b/gem/.gitignore
index 0186f37f..0b551674 100644
--- a/gem/.gitignore
+++ b/gem/.gitignore
@@ -7,6 +7,7 @@ InstalledFiles
 lib/bundler/man
 rdoc
 spec/reports
+spec/examples.txt
 test/tmp
 test/version_tmp
 tmp
diff --git a/gem/.rspec b/gem/.rspec
new file mode 100644
index 00000000..c99d2e73
--- /dev/null
+++ b/gem/.rspec
@@ -0,0 +1 @@
+--require spec_helper
diff --git a/gem/Gemfile b/gem/Gemfile
index 211317f3..8c70fa23 100644
--- a/gem/Gemfile
+++ b/gem/Gemfile
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
 
 # Specify your gem's dependencies in meterpreter_binaries.gemspec
 gemspec
+
+group :test do
+  gem 'rspec'
+end
diff --git a/gem/lib/metasploit-payloads.rb b/gem/lib/metasploit-payloads.rb
index a8ecb28c..cd7519fb 100644
--- a/gem/lib/metasploit-payloads.rb
+++ b/gem/lib/metasploit-payloads.rb
@@ -1,6 +1,8 @@
 # -*- coding:binary -*-
 
+require 'openssl' unless defined? OpenSSL::Digest
 require 'metasploit-payloads/version' unless defined? MetasploitPayloads::VERSION
+require 'metasploit-payloads/error' unless defined? MetasploitPayloads::Error
 
 #
 # This module dispenses Metasploit payload binary files
@@ -10,6 +12,56 @@ module MetasploitPayloads
   METERPRETER_SUBFOLDER = 'meterpreter'
   USER_DATA_SUBFOLDER   = 'payloads'
 
+  #
+  # @return [Array<Hash<String, Symbol>>] An array of filenames with warnings. Provides a file name and error.
+  #  Empty if all needed Meterpreter files exist and have the correct hash.
+  def self.manifest_errors
+    manifest_errors = []
+
+    begin
+      manifest_contents = ::File.binread(manifest_path)
+    rescue => e
+      return [{ path: manifest_path, error: e }]
+    end
+
+    begin
+      manifest_uuid_contents = ::File.binread(manifest_uuid_path)
+    rescue => e
+      manifest_errors.append({ path: manifest_uuid_path, error: e })
+    end
+
+    # Check if the hash of the manifest file is correct.
+    if manifest_uuid_contents
+      manifest_digest = ::OpenSSL::Digest.new('SHA3-256', manifest_contents)
+      uuid_matches = (manifest_uuid_contents.chomp == manifest_digest.to_s)
+      unless uuid_matches
+        e = ::MetasploitPayloads::HashMismatchError.new(manifest_path)
+        manifest_errors.append({ path: manifest_path, error: e })
+      end
+    end
+
+    manifest_contents.each_line do |line|
+      filename, hash_type, hash = line.chomp.split(':')
+      begin
+        # self.path prepends the gem data directory, which is already present in the manifest file.
+        out_path = self.path(filename.sub('./data/', ''))
+        # self.path can return a path to the gem data, or user's local data.
+        bundled_file = out_path.start_with?(data_directory)
+        if bundled_file
+          file_hash_match = (::OpenSSL::Digest.new(hash_type, ::File.binread(out_path)).to_s == hash)
+          unless file_hash_match
+            e = ::MetasploitPayloads::HashMismatchError.new(out_path)
+            manifest_errors.append({ path: e.path, error: e })
+          end
+        end
+      rescue ::MetasploitPayloads::NotFoundError, ::MetasploitPayloads::NotReadableError => e
+        manifest_errors.append({ path: e.path, error: e })
+      end
+    end
+
+    manifest_errors
+  end
+
   #
   # Get the path to an extension based on its name (no prefix).
   #
@@ -17,6 +69,14 @@ module MetasploitPayloads
     path(METERPRETER_SUBFOLDER, "#{EXTENSION_PREFIX}#{ext_name}.#{binary_suffix}")
   end
 
+  #
+  # Get the path for the first readable path in the provided arguments.
+  # Start with the provided `extra_paths` then fall back to the `gem_path`.
+  #
+  # @param [String] gem_path a path to the gem
+  # @param [Array<String>] extra_paths a path to any extra paths that should be evaluated for local files before `gem_path`
+  # @raise [NotReadableError] if the user doesn't have read permissions for the currently-evaluated path
+  # @return [String,nil] A readable path or nil
   def self.readable_path(gem_path, *extra_paths)
     # Try the MSF path first to see if the file exists, allowing the MSF data
     # folder to override what is in the gem. This is very helpful for
@@ -24,12 +84,18 @@ module MetasploitPayloads
     # each time. We only do this is MSF is installed.
     extra_paths.each do |extra_path|
       if ::File.readable? extra_path
-        warn_local_path(extra_path) if ::File.readable? gem_path
+        warn_local_path(extra_path)
         return extra_path
+      else
+        # Raise rather than falling back;
+        # If there is a local file present, let's assume that the user wants to use it (e.g. local dev. changes)
+        # rather than having MSF Console falling back to the files in the gem
+        raise ::MetasploitPayloads::NotReadableError, extra_path, caller if ::File.exist?(extra_path)
       end
     end
 
     return gem_path if ::File.readable? gem_path
+    raise ::MetasploitPayloads::NotReadableError, gem_path, caller if ::File.exist?(gem_path)
 
     nil
   end
@@ -37,21 +103,36 @@ module MetasploitPayloads
   #
   # Get the path to a meterpreter binary by full name.
   #
+  # @param [String] name The name of the requested binary without any file extensions
+  # @param [String] binary_suffix The binary extension, without the leading '.' char (e.g. `php`, `jar`)
+  # @param [Boolean] debug Request a debug version of the binary. This adds a
+  #  leading '.debug' to the extension if looking for a DLL file.
   def self.meterpreter_path(name, binary_suffix, debug: false)
     binary_suffix = binary_suffix&.gsub(/dll$/, 'debug.dll') if debug
     path(METERPRETER_SUBFOLDER, "#{name}.#{binary_suffix}".downcase)
   end
 
   #
-  # Get the full path to any file packaged in this gem by local path and name.
+  # Get the full path to any file packaged in this gem or other Metasploit Framework directories by local path and name.
   #
+  # @param [Array<String>] path_parts requested path parts that will be joined
+  # @raise [NotFoundError] if the requested path/file does not exist
+  # @raise [NotReadableError] if the requested file exists but the user doesn't have read permissions
+  # @return [String,nil] A path or nil
   def self.path(*path_parts)
     gem_path = expand(data_directory, ::File.join(path_parts))
     if metasploit_installed?
       user_path = expand(Msf::Config.config_directory, ::File.join(USER_DATA_SUBFOLDER, path_parts))
       msf_path = expand(Msf::Config.data_directory, ::File.join(path_parts))
+      out_path = readable_path(gem_path, user_path, msf_path)
+    else
+      out_path = readable_path(gem_path)
     end
-    readable_path(gem_path, user_path, msf_path)
+
+    return out_path unless out_path.nil?
+    raise ::MetasploitPayloads::NotFoundError, ::File.join(gem_path), caller unless ::File.exist?(gem_path)
+
+    nil
   end
 
   #
@@ -61,7 +142,7 @@ module MetasploitPayloads
     file_path = path(path_parts)
     if file_path.nil?
       full_path = ::File.join(path_parts)
-      fail RuntimeError, "#{full_path} not found", caller
+      raise ::MetasploitPayloads::NotFoundError, full_path, caller
     end
 
     ::File.binread(file_path)
@@ -203,5 +284,13 @@ module MetasploitPayloads
 
       things
     end
+
+    def manifest_path
+      ::File.realpath(::File.join(::File.dirname(__FILE__), '..', 'manifest'))
+    end
+
+    def manifest_uuid_path
+      ::File.realpath(::File.join(::File.dirname(__FILE__), '..', 'manifest.uuid'))
+    end
   end
 end
diff --git a/gem/lib/metasploit-payloads/error.rb b/gem/lib/metasploit-payloads/error.rb
new file mode 100644
index 00000000..3ddc1114
--- /dev/null
+++ b/gem/lib/metasploit-payloads/error.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module MetasploitPayloads
+  class Error < StandardError
+  end
+
+  # Error raised when a Metasploit Payloads file doesn't exist.
+  class NotFoundError < Error
+    attr_reader :path
+
+    def initialize(path = '')
+      @path = path
+      super("Meterpreter path #{@path} not found. Ensure antivirus is not enabled, or reinstall Metasploit.")
+    end
+  end
+
+  # Error raised when the user does not have read permissions for a Metasploit Payloads file
+  class NotReadableError < Error
+    attr_reader :path
+
+    def initialize(path = '')
+      @path = path
+      super("Meterpreter path #{@path} is not readable. Check if you have read access and try again.")
+    end
+  end
+
+  # Error raised when a Metasploit Payloads file's hash does not match what is defined in the manifest file.
+  class HashMismatchError < Error
+    attr_reader :path
+
+    def initialize(path = '')
+      @path = path
+      super("Meterpreter path #{@path} does not match the hash defined in the Metasploit Payloads manifest file.")
+    end
+  end
+end
diff --git a/gem/spec/metasploit_payloads/metasploit_payloads_spec.rb b/gem/spec/metasploit_payloads/metasploit_payloads_spec.rb
new file mode 100644
index 00000000..540d6228
--- /dev/null
+++ b/gem/spec/metasploit_payloads/metasploit_payloads_spec.rb
@@ -0,0 +1,249 @@
+# frozen_string_literal: true
+
+require 'metasploit-payloads'
+
+RSpec.describe ::MetasploitPayloads do
+  describe '::VERSION' do
+    it 'has a version number' do
+      expect(::MetasploitPayloads::VERSION).not_to be nil
+    end
+  end
+
+  describe '::Error' do
+    it 'has an Error class' do
+      expect(::MetasploitPayloads::Error.superclass).to be(::StandardError)
+    end
+
+    it 'has a NotFoundError class' do
+      expect(::MetasploitPayloads::NotFoundError.superclass).to be(::MetasploitPayloads::Error)
+    end
+
+    it 'has a NotReadableError class' do
+      expect(::MetasploitPayloads::NotReadableError.superclass).to be(::MetasploitPayloads::Error)
+    end
+
+    it 'has a HashMismatchError class' do
+      expect(::MetasploitPayloads::HashMismatchError.superclass).to be(::MetasploitPayloads::Error)
+    end
+  end
+
+  describe '#readable_path' do
+    let(:sample_file) { { name: 'meterpreter/meterpreter.py' } }
+
+    before :each do
+      allow(::File).to receive(:exist?).and_call_original
+      allow(::File).to receive(:readable?).and_call_original
+    end
+
+    context 'when the path is not readable' do
+      it 'raises a ::MetasploitPayloads::NotReadableError' do
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(true)
+        allow(::File).to receive(:readable?).with(sample_file[:name]).and_return(false)
+
+        expect { subject.readable_path(sample_file[:name]) }.to raise_error(::MetasploitPayloads::NotReadableError)
+      end
+    end
+
+    context 'when the path does not exist' do
+      it 'returns nil' do
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(false)
+        allow(::File).to receive(:readable?).with(sample_file[:name]).and_return(false)
+
+        expect(subject.readable_path(sample_file[:name])).to eq(nil)
+      end
+    end
+
+    context 'when the path exists and is readable' do
+      it 'returns the correct path' do
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(true)
+        allow(::File).to receive(:readable?).with(sample_file[:name]).and_return(true)
+
+        expect(subject.readable_path(sample_file[:name])).to eq(sample_file[:name])
+      end
+    end
+  end
+
+  describe '#path' do
+    let(:sample_file) { { name: 'meterpreter/meterpreter.py' } }
+
+    before :each do
+      allow(::File).to receive(:exist?).and_call_original
+      allow(::File).to receive(:readable?).and_call_original
+      allow(::MetasploitPayloads).to receive(:expand).and_call_original
+
+      allow(::MetasploitPayloads).to receive(:expand)
+        .with(::MetasploitPayloads.data_directory, sample_file[:name])
+        .and_return(sample_file[:name])
+    end
+
+    [
+      { context: 'is not readable', exist: true, readable: false, expected: ::MetasploitPayloads::NotReadableError },
+      { context: 'does not exist', exist: false, readable: false, expected: ::MetasploitPayloads::NotFoundError }
+    ].each do |test|
+      context "when the path #{test[:context]}" do
+        it "raises #{test[:expected]}" do
+          allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(test[:exist])
+          allow(::File).to receive(:readable?).with(sample_file[:name]).and_return(test[:readable])
+
+          expect { subject.path(sample_file[:name]) }.to raise_error(test[:expected])
+        end
+      end
+    end
+
+    context 'when the path exists and is readable' do
+      it 'returns the correct path' do
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(true)
+        allow(::File).to receive(:readable?).with(sample_file[:name]).and_return(true)
+
+        expect(subject.path(sample_file[:name])).to eq(sample_file[:name])
+      end
+    end
+  end
+
+  describe '#manifest_errors' do
+    let(:hash_type) { 'SHA3-256' }
+    let(:hash) { { type: hash_type, value: '92e931e6b47caad6df4249cc263fdbe5d2975c4163f5b06963208163b7af97b5' } }
+    let(:sample_file) { { name: 'meterpreter/ext_server_stdapi.php', contents: 'sample_data', hash: hash } }
+    let(:manifest_values) { ["./data/#{sample_file[:name]}", sample_file[:hash][:type], sample_file[:hash][:value]] }
+    let(:manifest) { manifest_values.join(':') }
+    let(:manifest_uuid) { ::OpenSSL::Digest.new(hash_type, manifest).to_s }
+    let(:manifest_path) { 'manifest' }
+    let(:manifest_uuid_path) { 'manifest.uuid' }
+
+    before :each do
+      allow(::MetasploitPayloads).to receive(:manifest_path).and_call_original
+      allow(::MetasploitPayloads).to receive(:manifest_path).and_return(manifest_path)
+
+      allow(::MetasploitPayloads).to receive(:manifest_uuid_path).and_call_original
+      allow(::MetasploitPayloads).to receive(:manifest_uuid_path).and_return(manifest_uuid_path)
+
+      allow(::File).to receive(:binread).and_call_original
+      allow(::File).to receive(:binread).with(sample_file[:name]).and_return(sample_file[:contents])
+      allow(::File).to receive(:binread).with(::MetasploitPayloads.send(:manifest_path)).and_return(manifest)
+      allow(::File).to receive(:binread).with(::MetasploitPayloads.send(:manifest_uuid_path)).and_return(manifest_uuid)
+
+      allow(::OpenSSL::Digest).to receive(:new).and_call_original
+      allow(::OpenSSL::Digest).to receive(:new).with(hash_type,
+                                                     sample_file[:contents]).and_return(sample_file[:hash][:value])
+    end
+
+    context 'when manifest hash does not match' do
+      it 'result includes the manifest file' do
+        allow(::File).to receive(:binread).with(::MetasploitPayloads.send(:manifest_uuid_path))
+                                          .and_return('mismatched_manifest_hash')
+        path = ::MetasploitPayloads.send(:manifest_path)
+        e = ::MetasploitPayloads::HashMismatchError.new(path)
+
+        expect(subject.manifest_errors).to include({ path: path, error: e })
+      end
+    end
+
+    context 'when manifest hash does match' do
+      it 'result does not include manifest' do
+        path = ::MetasploitPayloads.send(:manifest_uuid_path)
+        e = ::MetasploitPayloads::HashMismatchError.new(path)
+
+        expect(subject.manifest_errors).not_to include({ path: path, error: e })
+      end
+    end
+
+    context 'when there are no file warnings' do
+      it 'returns an empty array' do
+        allow(::MetasploitPayloads).to receive(:path).with(sample_file[:name]).and_return(sample_file[:name])
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(true)
+        full_file_path = ::MetasploitPayloads.expand(::MetasploitPayloads.data_directory, sample_file[:name])
+        allow(::File).to receive(:readable?).with(full_file_path).and_return(true)
+        allow(::File).to receive(:binread).with(full_file_path).and_return(sample_file[:contents])
+
+        expect(subject.manifest_errors).to eq([])
+      end
+    end
+
+    [
+      { context: 'does not exist', error_class: ::MetasploitPayloads::NotFoundError },
+      { context: 'is not readable', error_class: ::MetasploitPayloads::NotReadableError }
+    ].each do |test|
+      context "when a file #{test[:context]}" do
+        it 'includes the correct error' do
+          error = test[:error_class].new(sample_file[:name])
+          allow(::MetasploitPayloads).to receive(:path).with(sample_file[:name]).and_raise(error)
+
+          expect(subject.manifest_errors).to include({ path: sample_file[:name], error: error })
+        end
+      end
+    end
+
+    context 'when a bundled file hash does not match' do
+      it 'includes the correct error' do
+        allow(::File).to receive(:exist?).with(sample_file[:name]).and_return(true)
+        full_file_path = ::MetasploitPayloads.expand(::MetasploitPayloads.data_directory, sample_file[:name])
+        allow(::File).to receive(:readable?).with(full_file_path).and_return(true)
+        allow(::File).to receive(:binread).with(full_file_path).and_return('mismatched_file_contents')
+        e = ::MetasploitPayloads::HashMismatchError.new(full_file_path)
+
+        expect(subject.manifest_errors).to include({ path: full_file_path, error: e })
+      end
+    end
+
+    context 'when the manifest file' do
+      context 'does not exist' do
+        it 'only includes the manifest error' do
+          # path = ::MetasploitPayloads.send(:manifest_path)
+          e = ::Errno::ENOENT.new(manifest_path)
+          allow(::File).to receive(:binread).with(manifest_path).and_raise(e)
+
+          expect(subject.manifest_errors).to eq([{ path: manifest_path, error: e }])
+        end
+      end
+
+      context 'cannot be read' do
+        it 'only includes the manifest error' do
+          e = ::Errno::EACCES.new(manifest_path)
+          allow(::File).to receive(:binread).with(manifest_path).and_raise(e)
+
+          expect(subject.manifest_errors).to eq([{ path: manifest_path, error: e }])
+        end
+      end
+    end
+
+    context 'when the manifest.uuid file' do
+      context 'does not exist' do
+        it 'includes the correct error' do
+          e = ::Errno::ENOENT.new(manifest_uuid_path)
+          allow(::File).to receive(:binread).with(manifest_uuid_path).and_raise(e)
+
+          expect(subject.manifest_errors).to include({ path: manifest_uuid_path, error: e })
+        end
+      end
+    end
+
+    context 'when manifest is readable and manifest.uuid is not readable' do
+      before :each do
+        allow(::File).to receive(:binread).with(manifest_uuid_path).and_raise(::Errno::EACCES.new(manifest_uuid_path))
+      end
+
+      it 'correctly evaluates a file hash mismatch' do
+        bundled_file_path = ::MetasploitPayloads.expand(::MetasploitPayloads.data_directory, sample_file[:name])
+        error = ::MetasploitPayloads::HashMismatchError.new(bundled_file_path)
+        allow(::MetasploitPayloads).to receive(:path).with(sample_file[:name]).and_return(bundled_file_path)
+        allow(::File).to receive(:binread).with(bundled_file_path).and_return('sample_mismatched_contents')
+
+        expect(subject.manifest_errors).to include({ path: bundled_file_path, error: error })
+      end
+
+      it 'correctly evaluates a missing file' do
+        error = ::MetasploitPayloads::NotFoundError.new(sample_file[:name])
+        allow(::MetasploitPayloads).to receive(:path).with(sample_file[:name]).and_raise(error)
+
+        expect(subject.manifest_errors).to include({ path: sample_file[:name], error: error })
+      end
+
+      it 'correctly evaluates an unreadable file' do
+        error = ::MetasploitPayloads::NotReadableError.new(sample_file[:name])
+        allow(::MetasploitPayloads).to receive(:path).with(sample_file[:name]).and_raise(error)
+
+        expect(subject.manifest_errors).to include({ path: sample_file[:name], error: error })
+      end
+    end
+  end
+end
diff --git a/gem/spec/spec_helper.rb b/gem/spec/spec_helper.rb
new file mode 100644
index 00000000..d12ba095
--- /dev/null
+++ b/gem/spec/spec_helper.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'metasploit_payloads/metasploit_payloads_spec'
+
+# This file was generated by the `rspec --init` command. Conventionally, all
+# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
+# The generated `.rspec` file contains `--require spec_helper` which will cause
+# this file to always be loaded, without a need to explicitly require it in any
+# files.
+#
+# Given that it is always loaded, you are encouraged to keep this file as
+# light-weight as possible. Requiring heavyweight dependencies from this file
+# will add to the boot time of your test suite on EVERY test run, even for an
+# individual file that may not need all of that loaded. Instead, consider making
+# a separate helper file that requires the additional dependencies and performs
+# the additional setup, and require it from the spec files that actually need
+# it.
+#
+# The `.rspec` file also contains a few flags that are not defaults but that
+# users commonly want.
+#
+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+  # rspec-expectations config goes here. You can use an alternate
+  # assertion/expectation library such as wrong or the stdlib/minitest
+  # assertions if you prefer.
+  config.expect_with :rspec do |expectations|
+    # This option will default to `true` in RSpec 4. It makes the `description`
+    # and `failure_message` of custom matchers include text for helper methods
+    # defined using `chain`, e.g.:
+    #     be_bigger_than(2).and_smaller_than(4).description
+    #     # => "be bigger than 2 and smaller than 4"
+    # ...rather than:
+    #     # => "be bigger than 2"
+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+  end
+
+  # rspec-mocks config goes here. You can use an alternate test double
+  # library (such as bogus or mocha) by changing the `mock_with` option here.
+  config.mock_with :rspec do |mocks|
+    # Prevents you from mocking or stubbing a method that does not exist on
+    # a real object. This is generally recommended, and will default to
+    # `true` in RSpec 4.
+    mocks.verify_partial_doubles = true
+  end
+
+  # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
+  # have no way to turn it off -- the option exists only for backwards
+  # compatibility in RSpec 3). It causes shared context metadata to be
+  # inherited by the metadata hash of host groups and examples, rather than
+  # triggering implicit auto-inclusion in groups with matching metadata.
+  config.shared_context_metadata_behavior = :apply_to_host_groups
+
+  # The settings below are suggested to provide a good initial experience
+  # with RSpec, but feel free to customize to your heart's content.
+  # This allows you to limit a spec run to individual examples or groups
+  # you care about by tagging them with `:focus` metadata. When nothing
+  # is tagged with `:focus`, all examples get run. RSpec also provides
+  # aliases for `it`, `describe`, and `context` that include `:focus`
+  # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
+  config.filter_run_when_matching :focus
+
+  # Allows RSpec to persist some state between runs in order to support
+  # the `--only-failures` and `--next-failure` CLI options. We recommend
+  # you configure your source control system to ignore this file.
+  config.example_status_persistence_file_path = 'spec/examples.txt'
+
+  # Limits the available syntax to the non-monkey patched syntax that is
+  # recommended. For more details, see:
+  # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
+  config.disable_monkey_patching!
+
+  # This setting enables warnings. It's recommended, but in some cases may
+  # be too noisy due to issues in dependencies.
+  config.warnings = true
+
+  # Many RSpec users commonly either run the entire suite or an individual
+  # file, and it's useful to allow more verbose output when running an
+  # individual spec file.
+  if config.files_to_run.one?
+    # Use the documentation formatter for detailed output,
+    # unless a formatter has already been configured
+    # (e.g. via a command-line flag).
+    config.default_formatter = 'doc'
+  end
+
+  # Print the 10 slowest examples and example groups at the
+  # end of the spec run, to help surface which specs are running
+  # particularly slow.
+  config.profile_examples = 10
+
+  # Run specs in random order to surface order dependencies. If you find an
+  # order dependency and want to debug it, you can fix the order by providing
+  # the seed, which is printed after each run.
+  #     --seed 1234
+  config.order = :random
+
+  # Seed global randomization in this process using the `--seed` CLI option.
+  # Setting this allows you to use `--seed` to deterministically reproduce
+  # test failures related to randomization by passing the same `--seed` value
+  # as the one that triggered the failure.
+  Kernel.srand config.seed
+end