diff --git a/spec/tooling/lib/tooling/find_tests_spec.rb b/spec/tooling/lib/tooling/find_tests_spec.rb
index 997d9d9a746dd6bac36e08cd372abebffb8e0471..e531fb9548e791d71ed6c447129e296ed6abd563 100644
--- a/spec/tooling/lib/tooling/find_tests_spec.rb
+++ b/spec/tooling/lib/tooling/find_tests_spec.rb
@@ -50,15 +50,17 @@
     subject { instance.execute }
 
     context 'when the matching_tests_paths file does not exist' do
-      before do
-        allow(File).to receive(:exist?).and_return(false)
-        allow(File).to receive(:write).with(matching_tests_paths, any_args)
-      end
+      let(:instance)                 { described_class.new(non_existing_output_file, matching_tests_paths) }
+      let(:non_existing_output_file) { 'tmp/another_file.out' }
 
-      it 'creates an empty file' do
-        expect(File).to receive(:write).with(matching_tests_paths, '')
+      around do |example|
+        example.run
+      ensure
+        FileUtils.rm_rf(non_existing_output_file)
+      end
 
-        subject
+      it 'creates the file' do
+        expect { subject }.to change { File.exist?(non_existing_output_file) }.from(false).to(true)
       end
     end
 
diff --git a/spec/tooling/lib/tooling/helpers/file_handler_spec.rb b/spec/tooling/lib/tooling/helpers/file_handler_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7c8310c4bd958e52cfc98564721e0e0a2bf25b3e
--- /dev/null
+++ b/spec/tooling/lib/tooling/helpers/file_handler_spec.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+require 'tempfile'
+require_relative '../../../../../tooling/lib/tooling/helpers/file_handler'
+
+class MockClass # rubocop:disable Gitlab/NamespacedClass
+  include Tooling::Helpers::FileHandler
+end
+
+RSpec.describe Tooling::Helpers::FileHandler, feature_category: :tooling do
+  attr_accessor :input_file_path, :output_file_path
+
+  around do |example|
+    input_file  = Tempfile.new('input')
+    output_file = Tempfile.new('output')
+
+    self.input_file_path  = input_file.path
+    self.output_file_path = output_file.path
+
+    # See https://ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/
+    #     Tempfile.html#class-Tempfile-label-Explicit+close
+    begin
+      example.run
+    ensure
+      output_file.close
+      input_file.close
+      output_file.unlink
+      input_file.unlink
+    end
+  end
+
+  let(:instance)        { MockClass.new }
+  let(:initial_content) { 'previous_content1 previous_content2' }
+
+  before do
+    # We write into the temp files initially, to later check how the code modified those files
+    File.write(input_file_path, initial_content)
+    File.write(output_file_path, initial_content)
+  end
+
+  describe '#read_array_from_file' do
+    subject { instance.read_array_from_file(input_file_path) }
+
+    context 'when the input file does not exist' do
+      let(:non_existing_input_file) { 'tmp/another_file.out' }
+
+      subject { instance.read_array_from_file(non_existing_input_file) }
+
+      around do |example|
+        example.run
+      ensure
+        FileUtils.rm_rf(non_existing_input_file)
+      end
+
+      it 'creates the file' do
+        expect { subject }.to change { File.exist?(non_existing_input_file) }.from(false).to(true)
+      end
+    end
+
+    context 'when the input file is not empty' do
+      let(:initial_content) { 'previous_content1 previous_content2' }
+
+      it 'returns the content of the file in an array' do
+        expect(subject).to eq(initial_content.split(' '))
+      end
+    end
+  end
+
+  describe '#write_array_to_file' do
+    let(:content_array) { %w[new_entry] }
+
+    subject { instance.write_array_to_file(output_file_path, content_array) }
+
+    context 'when the output file does not exist' do
+      let(:non_existing_output_file) { 'tmp/another_file.out' }
+
+      subject { instance.write_array_to_file(non_existing_output_file, content_array) }
+
+      around do |example|
+        example.run
+      ensure
+        FileUtils.rm_rf(non_existing_output_file)
+      end
+
+      it 'creates the file' do
+        expect { subject }.to change { File.exist?(non_existing_output_file) }.from(false).to(true)
+      end
+    end
+
+    context 'when the output file is empty' do
+      let(:initial_content) { '' }
+
+      it 'writes the correct content to the file' do
+        expect { subject }.to change { File.read(output_file_path) }.from('').to(content_array.join(' '))
+      end
+    end
+
+    context 'when the output file is not empty' do
+      let(:initial_content) { 'previous_content1 previous_content2' }
+
+      it 'appends the correct content to the file' do
+        expect { subject }.to change { File.read(output_file_path) }
+        .from(initial_content)
+        .to((initial_content.split(' ') + content_array).join(' '))
+      end
+    end
+  end
+end
diff --git a/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb b/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb
index 375be001bd1885551883e3739425edb853f31794..30965ed985da6382c0b5d166bc92b949aefef82b 100644
--- a/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb
+++ b/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb
@@ -52,8 +52,8 @@
     end
 
     context 'when no partials were modified' do
-      it 'empties the output file' do
-        expect { subject }.to change { File.read(output_file) }.from(output_file_content).to('')
+      it 'does not change the output file' do
+        expect { subject }.not_to change { File.read(output_file) }
       end
     end
 
@@ -76,8 +76,8 @@
           File.write("#{view_base_folder}/my_view.html.haml", "render 'another_partial'")
         end
 
-        it 'empties the output file' do
-          expect { subject }.to change { File.read(output_file) }.from(output_file_content).to('')
+        it 'does not change the output file' do
+          expect { subject }.not_to change { File.read(output_file) }
         end
       end
 
@@ -89,7 +89,7 @@
         it 'writes the view including the partial to the output' do
           expect { subject }.to change { File.read(output_file) }
                             .from(output_file_content)
-                            .to("#{view_base_folder}/my_view.html.haml")
+                            .to(output_file_content + " #{view_base_folder}/my_view.html.haml")
         end
       end
     end
diff --git a/tooling/lib/tooling/find_tests.rb b/tooling/lib/tooling/find_tests.rb
index 4acbb5fcd6aea5a4e5f6da336f02aa4340ade011..b63b207c58bb081bba60850eee7ed4233fd6dca6 100644
--- a/tooling/lib/tooling/find_tests.rb
+++ b/tooling/lib/tooling/find_tests.rb
@@ -1,16 +1,15 @@
 # frozen_string_literal: true
 
 require 'test_file_finder'
+require_relative 'helpers/file_handler'
 
 module Tooling
   class FindTests
+    include Helpers::FileHandler
+
     def initialize(changes_file, matching_tests_paths)
       @matching_tests_paths = matching_tests_paths
-      @changed_files        = File.read(changes_file).split(' ')
-
-      File.write(matching_tests_paths, '') unless File.exist?(matching_tests_paths)
-
-      @matching_tests = File.read(matching_tests_paths).split(' ')
+      @changed_files        = read_array_from_file(changes_file)
     end
 
     def execute
@@ -22,8 +21,7 @@ def execute
         end
       end
 
-      new_matching_tests = tff.test_files.uniq
-      File.write(matching_tests_paths, (matching_tests + new_matching_tests).join(' '))
+      write_array_to_file(matching_tests_paths, tff.test_files.uniq)
     end
 
     private
diff --git a/tooling/lib/tooling/helpers/file_handler.rb b/tooling/lib/tooling/helpers/file_handler.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ec4f42ea3637a9e031ffee26b119db9ea5edf305
--- /dev/null
+++ b/tooling/lib/tooling/helpers/file_handler.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'fileutils'
+
+module Tooling
+  module Helpers
+    module FileHandler
+      def read_array_from_file(file)
+        FileUtils.touch file
+
+        File.read(file).split(' ')
+      end
+
+      def write_array_to_file(file, content_array)
+        FileUtils.touch file
+
+        output_content = (File.read(file).split(' ') + content_array).join(' ')
+
+        File.write(file, output_content)
+      end
+    end
+  end
+end
diff --git a/tooling/lib/tooling/mappings/base.rb b/tooling/lib/tooling/mappings/base.rb
index 93d3a967114fe3cc23432845e989479a2e7a06d7..3db4d1dbb9dfcb78d45d77cb99a271eddf676cf9 100644
--- a/tooling/lib/tooling/mappings/base.rb
+++ b/tooling/lib/tooling/mappings/base.rb
@@ -1,11 +1,14 @@
 # frozen_string_literal: true
 
 require_relative '../../../../lib/gitlab_edition'
+require_relative '../helpers/file_handler'
 
 # Returns system specs files that are related to the JS files that were changed in the MR.
 module Tooling
   module Mappings
     class Base
+      include Helpers::FileHandler
+
       # Input: A list of space-separated files
       # Output: A list of space-separated specs files (JS, Ruby, ...)
       def execute(changed_files)
diff --git a/tooling/lib/tooling/mappings/partial_to_views_mappings.rb b/tooling/lib/tooling/mappings/partial_to_views_mappings.rb
index c0cf378b53b0bee88f2c4202c23172e0169c2303..3109da685f1f0cb9c6a44d98128d473b5a555409 100644
--- a/tooling/lib/tooling/mappings/partial_to_views_mappings.rb
+++ b/tooling/lib/tooling/mappings/partial_to_views_mappings.rb
@@ -9,7 +9,7 @@ module Mappings
     class PartialToViewsMappings < Base
       def initialize(changes_file, output_file, view_base_folder: 'app/views')
         @output_file       = output_file
-        @changed_files     = File.read(changes_file).split(' ')
+        @changed_files     = read_array_from_file(changes_file)
         @view_base_folders = folders_for_available_editions(view_base_folder)
       end
 
@@ -28,7 +28,7 @@ def execute
           end
         end
 
-        File.write(output_file, views_including_modified_partials.join(' '))
+        write_array_to_file(output_file, views_including_modified_partials)
       end
 
       def filter_files