diff --git a/scripts/TagInfoExtract.groovy b/scripts/TagInfoExtract.groovy
index 828e325..0bb00a7 100644
--- a/scripts/TagInfoExtract.groovy
+++ b/scripts/TagInfoExtract.groovy
@@ -370,7 +370,6 @@ class TagInfoExtract {
      * Initialize the script.
      */
     def init() {
-        Main.initApplicationPreferences()
         Main.determinePlatformHook()
         Main.pref.enableSaveOnPut(false)
         Main.setProjection(Projections.getProjectionByCode("EPSG:3857"))
diff --git a/src/org/openstreetmap/josm/Main.java b/src/org/openstreetmap/josm/Main.java
index 85245aa..01d0378 100644
--- a/src/org/openstreetmap/josm/Main.java
+++ b/src/org/openstreetmap/josm/Main.java
@@ -167,7 +167,7 @@ public abstract class Main {
     /**
      * Global application preferences
      */
-    public static Preferences pref;
+    public static final Preferences pref = new Preferences();
 
     /**
      * The MapFrame. Use {@link Main#setMapFrame} to set or clear it.
@@ -514,14 +514,6 @@ public abstract class Main {
     public static volatile PlatformHook platform;
 
     /**
-     * Initializes {@code Main.pref} in normal application context.
-     * @since 6471
-     */
-    public static void initApplicationPreferences() {
-        Main.pref = new Preferences();
-    }
-
-    /**
      * Set or clear (if passed <code>null</code>) the map.
      * <p>
      * To be removed any time
diff --git a/src/org/openstreetmap/josm/data/Preferences.java b/src/org/openstreetmap/josm/data/Preferences.java
index 6c738e9..e145cac 100644
--- a/src/org/openstreetmap/josm/data/Preferences.java
+++ b/src/org/openstreetmap/josm/data/Preferences.java
@@ -778,6 +778,24 @@ public class Preferences {
         }
     }
 
+    /**
+     * Resets the preferences to their initial state. This resets all values and file associations.
+     * The default values and listeners are not removed.
+     * <p>
+     * It is meant to be called before {@link #init(boolean)}
+     */
+    public void resetToInitialState() {
+        resetToDefault();
+        preferencesDir = null;
+        cacheDir = null;
+        userdataDir = null;
+        saveOnPut = true;
+        initSuccessful = false;
+    }
+
+    /**
+     * Reset all values stored in this map to the default values. This clears the preferences.
+     */
     public final void resetToDefault() {
         settingsMap.clear();
     }
diff --git a/src/org/openstreetmap/josm/gui/MainApplication.java b/src/org/openstreetmap/josm/gui/MainApplication.java
index ea120a1..e42444a 100644
--- a/src/org/openstreetmap/josm/gui/MainApplication.java
+++ b/src/org/openstreetmap/josm/gui/MainApplication.java
@@ -325,8 +325,6 @@ public class MainApplication extends Main {
             Main.info(tr("Printing debugging messages to console"));
         }
 
-        initApplicationPreferences();
-
         Policy.setPolicy(new Policy() {
             // Permissions for plug-ins loaded when josm is started via webstart
             private PermissionCollection pc;
diff --git a/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java b/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java
index fab7dde..0789584 100644
--- a/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java
+++ b/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java
@@ -19,25 +19,28 @@ import javax.json.spi.JsonProvider;
 
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.JOSMFixture;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.Version;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
  * Tests the {@link HttpClient} using the webservice <a href="https://httpbin.org/">https://httpbin.org/</a>.
  */
 public class HttpClientTest {
 
-    private ProgressMonitor progress;
+    /**
+     *
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences();
 
-    @BeforeClass
-    public static void setUpBeforeClass() {
-        JOSMFixture.createFunctionalTestFixture().init();
-    }
+    private ProgressMonitor progress;
 
     @Before
     public void setUp() {
@@ -172,7 +175,6 @@ public class HttpClientTest {
      */
     @Test
     public void testOpenUrlGzip() throws IOException {
-        Main.initApplicationPreferences();
         final URL url = new URL("https://www.openstreetmap.org/trace/1613906/data");
         try (BufferedReader x = HttpClient.create(url).connect().uncompress(true).getContentReader()) {
             Assert.assertTrue(x.readLine().startsWith("<?xml version="));
@@ -185,7 +187,6 @@ public class HttpClientTest {
      */
     @Test
     public void testOpenUrlBzip() throws IOException {
-        Main.initApplicationPreferences();
         final URL url = new URL("https://www.openstreetmap.org/trace/785544/data");
         try (BufferedReader x = HttpClient.create(url).connect().uncompress(true).getContentReader()) {
             Assert.assertTrue(x.readLine().startsWith("<?xml version="));
@@ -198,7 +199,6 @@ public class HttpClientTest {
      */
     @Test
     public void testTicket9660() throws IOException {
-        Main.initApplicationPreferences();
         final URL url = new URL("http://www.openstreetmap.org/trace/1350010/data");
         try (BufferedReader x = HttpClient.create(url).connect()
                 .uncompress(true).uncompressAccordingToContentDisposition(true).getContentReader()) {
diff --git a/test/unit/org/openstreetmap/josm/JOSMFixture.java b/test/unit/org/openstreetmap/josm/JOSMFixture.java
index 81d579b..f9bcc23 100644
--- a/test/unit/org/openstreetmap/josm/JOSMFixture.java
+++ b/test/unit/org/openstreetmap/josm/JOSMFixture.java
@@ -90,7 +90,7 @@ public class JOSMFixture {
         }
         System.setProperty("josm.home", josmHome);
         TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
-        Main.initApplicationPreferences();
+        Main.pref.resetToInitialState();
         Main.pref.enableSaveOnPut(false);
         I18n.init();
         // initialize the plaform hook, and
diff --git a/test/unit/org/openstreetmap/josm/actions/mapmode/SelectActionTest.java b/test/unit/org/openstreetmap/josm/actions/mapmode/SelectActionTest.java
index 0c0ae11..3e52858 100644
--- a/test/unit/org/openstreetmap/josm/actions/mapmode/SelectActionTest.java
+++ b/test/unit/org/openstreetmap/josm/actions/mapmode/SelectActionTest.java
@@ -16,7 +16,6 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.openstreetmap.josm.JOSMFixture;
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
@@ -32,20 +31,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  */
 public class SelectActionTest {
 
-    /**
-     * Override some configuration variables without change in preferences.xml
-     */
-    static class PreferencesMock extends Preferences {
-        @Override
-        public synchronized int getInteger(String key, int def) {
-            if ("edit.initial-move-delay".equals(key)) {
-                return 0;
-            } else {
-                return super.getInteger(key, def);
-            }
-        }
-    }
-
     boolean nodesMerged;
 
     class SelectActionMock extends SelectAction {
@@ -103,7 +88,7 @@ public class SelectActionTest {
         dataSet.addSelected(n2);
         dataSet.addSelected(w);
 
-        Main.pref = new PreferencesMock();
+        Main.pref.put("edit.initial-move-delay", "0");
         Main.getLayerManager().addLayer(layer);
         try {
             SelectAction action = new SelectActionMock(Main.map, dataSet, layer);
diff --git a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorterTest.java b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorterTest.java
index d58ebf7..159a7fe 100644
--- a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorterTest.java
+++ b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/RelationSorterTest.java
@@ -7,16 +7,18 @@ import java.io.InputStream;
 import java.util.List;
 
 import org.junit.Assert;
-import org.junit.BeforeClass;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.io.OsmReader;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
  * Unit tests of {@link RelationSorter} class.
@@ -24,14 +26,26 @@ import org.openstreetmap.josm.io.OsmReader;
 public class RelationSorterTest {
 
     private final RelationSorter sorter = new RelationSorter();
-    private static DataSet testDataset;
+    private DataSet testDataset;
+
+    /**
+     * Use Mercator projection
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences().projection();
 
-    @BeforeClass
-    public static void loadData() throws IllegalDataException, IOException {
-        Main.initApplicationPreferences();
-        Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
-        try (InputStream fis = new FileInputStream("data_nodist/relation_sort.osm")) {
-            testDataset = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
+    /**
+     * Load the test data set
+     * @throws IllegalDataException
+     * @throws IOException
+     */
+    @Before
+    public void loadData() throws IllegalDataException, IOException {
+        if (testDataset == null) {
+            try (InputStream fis = new FileInputStream("data_nodist/relation_sort.osm")) {
+                testDataset = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
+            }
         }
     }
 
diff --git a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/WayConnectionTypeCalculatorTest.java b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/WayConnectionTypeCalculatorTest.java
index c9ee5b1..536867d 100644
--- a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/WayConnectionTypeCalculatorTest.java
+++ b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/sort/WayConnectionTypeCalculatorTest.java
@@ -8,15 +8,17 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Assert;
-import org.junit.BeforeClass;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.io.OsmReader;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
  * Unit tests of {@link WayConnectionTypeCalculator} class.
@@ -25,14 +27,26 @@ public class WayConnectionTypeCalculatorTest {
 
     private RelationSorter sorter = new RelationSorter();
     private WayConnectionTypeCalculator wayConnectionTypeCalculator = new WayConnectionTypeCalculator();
-    private static DataSet testDataset;
-
-    @BeforeClass
-    public static void loadData() throws IllegalDataException, IOException {
-        Main.initApplicationPreferences();
-        Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
-        try (InputStream fis = new FileInputStream("data_nodist/relation_sort.osm")) {
-            testDataset = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
+    private DataSet testDataset;
+
+    /**
+     * Use Mercator projection
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences().projection();
+
+    /**
+     * Load the test data set
+     * @throws IllegalDataException
+     * @throws IOException
+     */
+    @Before
+    public void loadData() throws IllegalDataException, IOException {
+        if (testDataset == null) {
+            try (InputStream fis = new FileInputStream("data_nodist/relation_sort.osm")) {
+                testDataset = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
+            }
         }
     }
 
diff --git a/test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java b/test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java
index 634b625..49b6536 100644
--- a/test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java
+++ b/test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java
@@ -200,7 +200,7 @@ public class JOSMTestRules implements TestRule {
 
         // Add preferences
         if (usePreferences) {
-            Main.initApplicationPreferences();
+            Main.pref.resetToInitialState();
             Main.pref.enableSaveOnPut(false);
             // No pref init -> that would only create the preferences file.
             // We force the use of a wrong API server, just in case anyone attempts an upload
@@ -246,7 +246,7 @@ public class JOSMTestRules implements TestRule {
     private void cleanUpFromJosmFixture() {
         MemoryManagerTest.resetState(true);
         Main.getLayerManager().resetState();
-        Main.pref = null;
+        Main.pref.resetToInitialState();
         Main.platform = null;
         System.gc();
     }
@@ -267,7 +267,7 @@ public class JOSMTestRules implements TestRule {
         MemoryManagerTest.resetState(allowMemoryManagerLeaks);
 
         // TODO: Remove global listeners and other global state.
-        Main.pref = null;
+        Main.pref.resetToInitialState();;
         Main.platform = null;
         // Parts of JOSM uses weak references - destroy them.
         System.gc();
