This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 659e00a4383001144490d928f32bd5aa3d03ba59
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Jul 6 16:27:16 2023 +0200

    All tests shall open resource files from the module containing the 
resources.
    This is necessary for making possible to execute those tests in JPMS 
context.
---
 .../apache/sis/console/MimeTypeCommandTest.java    |  14 +--
 .../sis/internal/jaxb/gco/MultiplicityTest.java    |  22 +++--
 .../sis/internal/jaxb/lan/PT_LocaleTest.java       |  27 +++---
 .../java/org/apache/sis/metadata/Assertions.java   |   3 +-
 .../metadata/iso/citation/DefaultCitationTest.java |  32 ++++---
 .../sis/metadata/iso/extent/DefaultExtentTest.java |  32 +++++--
 .../DefaultServiceIdentificationTest.java          |  18 ++--
 .../iso/lineage/DefaultProcessStepTest.java        |  21 +++--
 .../quality/AbstractPositionalAccuracyTest.java    |  22 +++--
 .../org/apache/sis/metadata/xml/TestUsingFile.java |  52 +++++++++--
 .../apache/sis/test/xml/DocumentComparator.java    |   8 +-
 .../java/org/apache/sis/test/xml/TestCase.java     | 104 ++++++++++-----------
 .../java/org/apache/sis/test/xml/package-info.java |   2 +-
 .../sis/parameter/ParameterMarshallingTest.java    |  43 +++++++--
 .../referencing/crs/DefaultCompoundCRSTest.java    |  14 ++-
 .../sis/referencing/crs/DefaultDerivedCRSTest.java |  14 ++-
 .../referencing/crs/DefaultGeodeticCRSTest.java    |  14 ++-
 .../referencing/crs/DefaultProjectedCRSTest.java   |  20 ++--
 .../sis/referencing/cs/DefaultCartesianCSTest.java |  14 ++-
 .../referencing/cs/DefaultEllipsoidalCSTest.java   |  14 ++-
 .../referencing/datum/DefaultEllipsoidTest.java    |  24 ++---
 .../datum/DefaultGeodeticDatumTest.java            |  12 ++-
 .../datum/DefaultPrimeMeridianTest.java            |  15 ++-
 .../datum/DefaultTemporalDatumTest.java            |  14 ++-
 .../datum/DefaultVerticalDatumTest.java            |  25 ++---
 .../DefaultConcatenatedOperationTest.java          |  14 ++-
 .../operation/DefaultPassThroughOperationTest.java |  14 ++-
 .../operation/SingleOperationMarshallingTest.java  |  17 +++-
 .../sis/test/integration/MetadataVerticalTest.java |  15 ++-
 .../java/org/apache/sis/test/TestUtilities.java    |  16 ++--
 .../profile/fra/DirectReferenceSystemTest.java     |  13 ++-
 .../internal/storage/xml/MimeTypeDetectorTest.java |   6 +-
 .../sis/internal/storage/gpx/ReaderTest.java       |  27 +++---
 .../apache/sis/internal/storage/gpx/TestData.java  |  91 ++++++++++++++++++
 .../sis/internal/storage/gpx/WriterTest.java       |  35 ++++---
 35 files changed, 564 insertions(+), 264 deletions(-)

diff --git 
a/application/sis-console/src/test/java/org/apache/sis/console/MimeTypeCommandTest.java
 
b/application/sis-console/src/test/java/org/apache/sis/console/MimeTypeCommandTest.java
index fd54857d7e..9b3f7e896e 100644
--- 
a/application/sis-console/src/test/java/org/apache/sis/console/MimeTypeCommandTest.java
+++ 
b/application/sis-console/src/test/java/org/apache/sis/console/MimeTypeCommandTest.java
@@ -17,13 +17,13 @@
 package org.apache.sis.console;
 
 import java.net.URL;
-import org.apache.sis.internal.storage.gpx.MetadataTest;
-import org.apache.sis.metadata.xml.TestUsingFile;
+import org.apache.sis.internal.storage.gpx.TestData;
+import org.apache.sis.metadata.iso.extent.DefaultExtentTest;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
-import static org.apache.sis.metadata.iso.extent.DefaultExtentTest.FILENAME;
 
 
 /**
@@ -34,7 +34,7 @@ import static 
org.apache.sis.metadata.iso.extent.DefaultExtentTest.FILENAME;
  * @since   0.4
  */
 @DependsOn(CommandRunnerTest.class)
-public final class MimeTypeCommandTest extends TestUsingFile {
+public final class MimeTypeCommandTest extends TestCase {
     /**
      * Tests the sub-command on a metadata file.
      *
@@ -42,7 +42,7 @@ public final class MimeTypeCommandTest extends TestUsingFile {
      */
     @Test
     public void testWithMetadataXML() throws Exception {
-        final URL url = TestUsingFile.class.getResource(XML2007+FILENAME);
+        final URL url = DefaultExtentTest.getTestFileURL();
         final MimeTypeCommand test = new MimeTypeCommand(0, 
CommandRunner.TEST, url.toString());
         test.run();
         final String output = test.outputBuffer.toString().trim();
@@ -56,8 +56,8 @@ public final class MimeTypeCommandTest extends TestUsingFile {
      */
     @Test
     public void testWithMetadataGPX() throws Exception {
-        final URL url = MetadataTest.class.getResource("1.1/metadata.xml");
-        assertNotNull("1.1/metadata.xml", url);
+        final URL url = TestData.V1_1.getURL(TestData.METADATA);
+        assertNotNull(url);
         final MimeTypeCommand test = new MimeTypeCommand(0, 
CommandRunner.TEST, url.toString());
         test.run();
         final String output = test.outputBuffer.toString().trim();
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/gco/MultiplicityTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/gco/MultiplicityTest.java
index 8e739c4e4d..f02ab47223 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/gco/MultiplicityTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/gco/MultiplicityTest.java
@@ -17,9 +17,9 @@
 package org.apache.sis.internal.jaxb.gco;
 
 import java.util.Map;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBException;
-import org.apache.sis.util.Version;
 import org.apache.sis.util.iso.Names;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.metadata.xml.TestUsingFile;
@@ -41,9 +41,14 @@ import static org.junit.Assert.*;
  */
 public final class MultiplicityTest extends TestUsingFile {
     /**
-     * An XML file containing multiplicity declarations.
+     * Opens the stream to the XML file containing multiplicity declarations.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "Multiplicity.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("Multiplicity.xml");
+    }
 
     /**
      * A poll of configured {@code Marshaller} and {@code Unmarshaller}.
@@ -94,10 +99,11 @@ public final class MultiplicityTest extends TestUsingFile {
     /**
      * Tests marshalling of a few multiplicity using the specified version of 
metadata schema.
      *
-     * @param  filename  name of the file containing expected result.
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
      */
-    private void marshalAndCompare(final String filename, final Version 
version) throws JAXBException {
-        assertMarshalEqualsFile(filename, create(0), version, "xmlns:*", 
"xsi:*");
+    private void marshalAndCompare(final Format format) throws JAXBException {
+        FeatureAttributeMock metadata = create(0);
+        assertMarshalEqualsFile(openTestFile(format), metadata, 
format.schemaVersion, "xmlns:*", "xsi:*");
     }
 
     /**
@@ -107,7 +113,7 @@ public final class MultiplicityTest extends TestUsingFile {
      */
     @Test
     public void testMarshallingLegacy() throws JAXBException {
-        marshalAndCompare(XML2007+FILENAME, VERSION_2007);
+        marshalAndCompare(Format.XML2007);
     }
 
     /**
@@ -117,7 +123,7 @@ public final class MultiplicityTest extends TestUsingFile {
      */
     @Test
     public void testUnmarshallingLegacy() throws JAXBException {
-        final FeatureAttributeMock metadata = 
unmarshalFile(FeatureAttributeMock.class, XML2007+FILENAME);
+        final FeatureAttributeMock metadata = 
unmarshalFile(FeatureAttributeMock.class, openTestFile(Format.XML2007));
         assertEquals(create(1).cardinality.range(), 
metadata.cardinality.range());
     }
 }
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/lan/PT_LocaleTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/lan/PT_LocaleTest.java
index 1494b28353..1926aad98d 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/lan/PT_LocaleTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/internal/jaxb/lan/PT_LocaleTest.java
@@ -18,9 +18,9 @@ package org.apache.sis.internal.jaxb.lan;
 
 import java.util.Map;
 import java.util.Locale;
+import java.io.InputStream;
 import java.nio.charset.Charset;
 import jakarta.xml.bind.JAXBException;
-import org.apache.sis.util.Version;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.metadata.xml.TestUsingFile;
 import org.junit.Test;
@@ -38,9 +38,14 @@ import static org.junit.Assert.*;
  */
 public final class PT_LocaleTest extends TestUsingFile {
     /**
-     * An XML file containing localized strings.
+     * Opens the stream to the XML file containing localized strings.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "Locales.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("Locales.xml");
+    }
 
     /**
      * The locales to use for the tests. For better test coverage we need at 
least:
@@ -57,10 +62,10 @@ public final class PT_LocaleTest extends TestUsingFile {
     /**
      * Tests marshalling of a few locales using the specified version of 
metadata schema.
      *
-     * @param filename      name of the file containing expected result.
+     * @param format        whether to use the 2007 or 2016 version of ISO 
19115.
      * @param ignoredNodes  the fully-qualified names of the nodes to ignore.
      */
-    private void marshalAndCompare(final String filename, final Version 
version, final String... ignoredNodes)
+    private void marshalAndCompare(final Format format, final String... 
ignoredNodes)
             throws JAXBException
     {
         final DefaultMetadata metadata = new DefaultMetadata();
@@ -68,7 +73,7 @@ public final class PT_LocaleTest extends TestUsingFile {
         for (final Locale locale : locales) {
             lc.put(locale, null);
         }
-        assertMarshalEqualsFile(filename, metadata, version, STRICT, 
ignoredNodes,
+        assertMarshalEqualsFile(openTestFile(format), metadata, 
format.schemaVersion, STRICT, ignoredNodes,
                 new String[] {"xmlns:*", "xsi:*"});
     }
 
@@ -79,8 +84,7 @@ public final class PT_LocaleTest extends TestUsingFile {
      */
     @Test
     public void testMarshalling() throws JAXBException {
-        marshalAndCompare(XML2016+FILENAME, VERSION_2014,
-                          "mdb:contact", "mdb:dateInfo", 
"mdb:identificationInfo");
+        marshalAndCompare(Format.XML2016, "mdb:contact", "mdb:dateInfo", 
"mdb:identificationInfo");
     }
 
     /**
@@ -90,8 +94,7 @@ public final class PT_LocaleTest extends TestUsingFile {
      */
     @Test
     public void testMarshallingLegacy() throws JAXBException {
-        marshalAndCompare(XML2007+FILENAME, VERSION_2007,
-                          "gmd:contact", "gmd:dateStamp", 
"gmd:identificationInfo");
+        marshalAndCompare(Format.XML2007, "gmd:contact", "gmd:dateStamp", 
"gmd:identificationInfo");
     }
 
     /**
@@ -101,7 +104,7 @@ public final class PT_LocaleTest extends TestUsingFile {
      */
     @Test
     public void testUnmarshalling() throws JAXBException {
-        final DefaultMetadata metadata = unmarshalFile(DefaultMetadata.class, 
XML2016+FILENAME);
+        final DefaultMetadata metadata = unmarshalFile(DefaultMetadata.class, 
openTestFile(Format.XML2016));
         assertArrayEquals(locales, 
metadata.getLocalesAndCharsets().keySet().toArray());
     }
 
@@ -112,7 +115,7 @@ public final class PT_LocaleTest extends TestUsingFile {
      */
     @Test
     public void testUnmarshallingLegacy() throws JAXBException {
-        final DefaultMetadata metadata = unmarshalFile(DefaultMetadata.class, 
XML2007+FILENAME);
+        final DefaultMetadata metadata = unmarshalFile(DefaultMetadata.class, 
openTestFile(Format.XML2007));
         assertArrayEquals(locales, 
metadata.getLocalesAndCharsets().keySet().toArray());
     }
 }
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/Assertions.java 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/Assertions.java
index ba020777f9..ae7c4427cf 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/Assertions.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/Assertions.java
@@ -133,8 +133,9 @@ public final class Assertions extends Static {
      *
      * <ul>
      *   <li>{@link org.w3c.dom.Node}: used directly without further 
processing.</li>
+     *   <li>{@link java.io.InputStream}: the stream is parsed as an XML 
document, then closed.</li>
      *   <li>{@link java.nio.file.Path}, {@link java.io.File}, {@link 
java.net.URL} or {@link java.net.URI}:
-     *       the stream is opened and parsed as a XML document.</li>
+     *       the stream is opened, parsed as an XML document, then closed.</li>
      *   <li>{@link String}: The string content is parsed directly as a XML 
document.</li>
      * </ul>
      *
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
index ad282973a3..67e0df0623 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.CitationDate;
@@ -44,7 +45,6 @@ import org.apache.sis.metadata.iso.DefaultIdentifier;
 import org.apache.sis.metadata.xml.TestUsingFile;
 import org.apache.sis.util.SimpleInternationalString;
 import org.apache.sis.util.DefaultInternationalString;
-import org.apache.sis.util.Version;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestUtilities;
 import org.junit.Test;
@@ -64,9 +64,14 @@ import static org.junit.Assert.*;
  */
 public final class DefaultCitationTest extends TestUsingFile {
     /**
-     * An XML file containing a citation.
+     * Opens the stream to the XML file containing a citation.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "Citation.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("Citation.xml");
+    }
 
     /**
      * Creates a citation with an arbitrary title, presentation form and other 
properties.
@@ -214,7 +219,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
      */
     @Test
     public void testMarshalling() throws JAXBException {
-        testMarshalling(XML2016+FILENAME, VERSION_2014);
+        testMarshalling(Format.XML2016);
     }
 
     /**
@@ -228,16 +233,15 @@ public final class DefaultCitationTest extends 
TestUsingFile {
     @Test
     @DependsOnMethod("testMarshalling")
     public void testMarshallingLegacy() throws JAXBException {
-        testMarshalling(XML2007+FILENAME, VERSION_2007);
+        testMarshalling(Format.XML2007);
     }
 
     /**
      * Tests XML marshalling for the given metadata version.
      *
-     * @param  file     file containing the expected metadata.
-     * @param  version  the metadata version to marshal.
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
      */
-    private void testMarshalling(final String file, final Version version) 
throws JAXBException {
+    private void testMarshalling(final Format format) throws JAXBException {
         final DefaultOnlineResource rs = new 
DefaultOnlineResource(URI.create("https://tools.ietf.org/html/rfc1149";));
         rs.setName(new SimpleInternationalString("IP over Avian Carriers"));
         rs.setDescription(new SimpleInternationalString("High delay, low 
throughput, and low altitude service."));
@@ -256,7 +260,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
         /*
          * Check that XML file built by the marshaller is the same as the 
example file.
          */
-        assertMarshalEqualsFile(file, c, version, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(format), c, format.schemaVersion, 
"xmlns:*", "xsi:schemaLocation");
     }
 
     /**
@@ -269,7 +273,7 @@ public final class DefaultCitationTest extends 
TestUsingFile {
      */
     @Test
     public void testUnmarshalling() throws JAXBException {
-        testUnmarshalling(XML2016+FILENAME);
+        testUnmarshalling(Format.XML2016);
     }
 
     /**
@@ -283,17 +287,17 @@ public final class DefaultCitationTest extends 
TestUsingFile {
     @Test
     @DependsOnMethod("testUnmarshalling")
     public void testUnmarshallingLegacy() throws JAXBException {
-        testUnmarshalling(XML2007+FILENAME);
+        testUnmarshalling(Format.XML2007);
     }
 
     /**
      * Tests XML unmarshalling for a metadata version.
      * The version is not specified since it should be detected automatically.
      *
-     * @param  file  file containing the metadata to unmarshal.
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
      */
-    private void testUnmarshalling(final String file) throws JAXBException {
-        final DefaultCitation c = unmarshalFile(DefaultCitation.class, file);
+    private void testUnmarshalling(final Format format) throws JAXBException {
+        final DefaultCitation c = unmarshalFile(DefaultCitation.class, 
openTestFile(format));
         assertTitleEquals("title", "Fight against poverty", c);
 
         final CitationDate date = getSingleton(c.getDates());
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
index b325afa413..2f4953d107 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java
@@ -17,9 +17,10 @@
 package org.apache.sis.metadata.iso.extent;
 
 import java.util.List;
+import java.net.URL;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.extent.Extent;
-import org.apache.sis.util.Version;
 import org.apache.sis.util.SimpleInternationalString;
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.xml.Namespaces;
@@ -45,9 +46,24 @@ import static org.apache.sis.test.TestUtilities.date;
 @DependsOn(DefaultGeographicBoundingBoxTest.class)
 public final class DefaultExtentTest extends TestUsingFile {
     /**
-     * An XML file containing extent information.
+     * Opens the stream to the XML file containing extent information.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    public static final String FILENAME = "Extent.xml";
+    public static InputStream openTestFile(final Format format) {
+        return format.openTestFile("Extent.xml");
+    }
+
+    /**
+     * Returns the URL to an arbitrary test file.
+     * This is an accessor for tests in other modules.
+     *
+     * @return URL to an arbitrary test file.
+     */
+    public static URL getTestFileURL() {
+        return Format.XML2007.getURL("Extent.xml");
+    }
 
     /**
      * Tests {@link DefaultExtent#intersect(Extent)}.
@@ -91,7 +107,7 @@ public final class DefaultExtentTest extends TestUsingFile {
      */
     @Test
     public void testXML() throws JAXBException {
-        roundtrip(XML2016+FILENAME, VERSION_2014);
+        roundtrip(Format.XML2016);
     }
 
     /**
@@ -101,13 +117,13 @@ public final class DefaultExtentTest extends 
TestUsingFile {
      */
     @Test
     public void testLegacyXML() throws JAXBException {
-        roundtrip(XML2007+FILENAME, VERSION_2007);
+        roundtrip(Format.XML2007);
     }
 
     /**
      * Compares the marshalling and unmarshalling of a {@link DefaultExtent} 
with XML in the given file.
      */
-    private void roundtrip(final String filename, final Version version) 
throws JAXBException {
+    private void roundtrip(final Format format) throws JAXBException {
         final DefaultGeographicBoundingBox bbox = new 
DefaultGeographicBoundingBox(-99, -79, 14.9844, 31);
         bbox.getIdentifierMap().put(IdentifierSpace.ID, "bbox");
         final DefaultTemporalExtent temporal = new DefaultTemporalExtent();
@@ -116,8 +132,8 @@ public final class DefaultExtentTest extends TestUsingFile {
             temporal.setBounds(date("2010-01-27 13:26:10"), date("2010-08-27 
13:26:10"));
         }
         final DefaultExtent extent = new DefaultExtent(null, bbox, null, 
temporal);
-        assertMarshalEqualsFile(filename, extent, version, "xmlns:*", 
"xsi:schemaLocation");
-        assertEquals(extent, unmarshalFile(DefaultExtent.class, filename));
+        assertMarshalEqualsFile(openTestFile(format), extent, 
format.schemaVersion, "xmlns:*", "xsi:schemaLocation");
+        assertEquals(extent, unmarshalFile(DefaultExtent.class, 
openTestFile(format)));
     }
 
     /**
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
index 98c87b2420..1fd98a22af 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultServiceIdentificationTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.metadata.iso.identification;
 
 import java.util.Set;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.util.NameFactory;
 import org.opengis.parameter.ParameterDirection;
@@ -53,9 +54,14 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
 })
 public final class DefaultServiceIdentificationTest extends TestUsingFile {
     /**
-     * An XML file containing a service identification.
+     * Opens the stream to the XML file containing a service identification.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "ServiceIdentification.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("ServiceIdentification.xml");
+    }
 
     /**
      * Creates the service identification to use for testing purpose.
@@ -110,7 +116,7 @@ public final class DefaultServiceIdentificationTest extends 
TestUsingFile {
      */
     @Test
     public void testUnmarshal() throws JAXBException {
-        final ServiceIdentification id = 
unmarshalFile(ServiceIdentification.class, XML2016+FILENAME);
+        final ServiceIdentification id = 
unmarshalFile(ServiceIdentification.class, openTestFile(Format.XML2016));
         verify(id);
         final CoupledResource resource = 
getSingleton(id.getCoupledResources());
         assertTitleEquals("resourceReference", "WMS specification", 
getSingleton(resource.getResourceReferences()));
@@ -123,7 +129,7 @@ public final class DefaultServiceIdentificationTest extends 
TestUsingFile {
      */
     @Test
     public void testUnmarshalLegacy() throws JAXBException {
-        final ServiceIdentification id = 
unmarshalFile(ServiceIdentification.class, XML2007+FILENAME);
+        final ServiceIdentification id = 
unmarshalFile(ServiceIdentification.class, openTestFile(Format.XML2007));
         verify(id);
         final CoupledResource resource = 
getSingleton(id.getCoupledResources());
         assertEquals("scopedName", "mySpace:ABC-123", 
String.valueOf(resource.getScopedName()));
@@ -136,7 +142,7 @@ public final class DefaultServiceIdentificationTest extends 
TestUsingFile {
      */
     @Test
     public void testMarshal() throws JAXBException {
-        assertMarshalEqualsFile(XML2016+FILENAME, create(), "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(Format.XML2016), create(), 
"xmlns:*", "xsi:schemaLocation");
     }
 
     /**
@@ -146,6 +152,6 @@ public final class DefaultServiceIdentificationTest extends 
TestUsingFile {
      */
     @Test
     public void testMarshalLegacy() throws JAXBException {
-        assertMarshalEqualsFile(XML2007+FILENAME, create(), VERSION_2007, 
"xmlns:*", "xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(Format.XML2007), create(), 
VERSION_2007, "xmlns:*", "xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java
index 92341398c2..6127b1981c 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java
@@ -16,12 +16,12 @@
  */
 package org.apache.sis.metadata.iso.lineage;
 
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.apache.sis.util.SimpleInternationalString;
 import org.apache.sis.internal.jaxb.gmi.LE_ProcessStep;
 import org.apache.sis.metadata.iso.DefaultIdentifier;
 import org.apache.sis.metadata.xml.TestUsingFile;
-import org.apache.sis.util.Version;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -38,9 +38,14 @@ import static org.opengis.test.Assert.assertInstanceOf;
  */
 public final class DefaultProcessStepTest extends TestUsingFile {
     /**
-     * An XML file containing process step information.
+     * Opens the stream to the XML file containing process step information.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "ProcessStep.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("ProcessStep.xml");
+    }
 
     /**
      * Tests the (un)marshalling of a metadata mixing elements from ISO 19115 
and ISO 19115-2 standards.
@@ -49,7 +54,7 @@ public final class DefaultProcessStepTest extends 
TestUsingFile {
      */
     @Test
     public void testXML() throws JAXBException {
-        roundtrip(XML2016+FILENAME, VERSION_2014);
+        roundtrip(Format.XML2016);
     }
 
     /**
@@ -60,13 +65,13 @@ public final class DefaultProcessStepTest extends 
TestUsingFile {
      */
     @Test
     public void testLegacyXML() throws JAXBException {
-        roundtrip(XML2007+FILENAME, VERSION_2007);
+        roundtrip(Format.XML2007);
     }
 
     /**
      * Tests (un)marshalling in the given version.
      */
-    private void roundtrip(final String filename, final Version version) 
throws JAXBException {
+    private void roundtrip(final Format format) throws JAXBException {
         final DefaultProcessing  processing  = new DefaultProcessing();
         final DefaultProcessStep processStep = new DefaultProcessStep("Some 
process step.");
         processing.setProcedureDescription(new SimpleInternationalString("Some 
procedure."));
@@ -75,14 +80,14 @@ public final class DefaultProcessStepTest extends 
TestUsingFile {
         /*
          * XML marshalling, and compare with the content of "ProcessStep.xml" 
file.
          */
-        assertMarshalEqualsFile(filename, processStep, version, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(format), processStep, 
format.schemaVersion, "xmlns:*", "xsi:schemaLocation");
         /*
          * XML unmarshalling: ensure that we didn't lost any information.
          * Note that since the XML uses the <gmi:…> namespace, we got an 
instance of LE_ProcessStep, which
          * in SIS implementation does not carry any useful information; it is 
just a consequence of the way
          * namespaces are managed. We will convert to the parent 
DefaultProcessStep type before comparison.
          */
-        DefaultProcessStep step = unmarshalFile(DefaultProcessStep.class, 
filename);
+        DefaultProcessStep step = unmarshalFile(DefaultProcessStep.class, 
openTestFile(format));
         assertInstanceOf("The unmarshalled object is expected to be in GMI 
namespace.", LE_ProcessStep.class, step);
         step = new DefaultProcessStep(step);
         assertEquals(processStep, step);
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
index 63f496849f..b56af9495f 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
@@ -17,11 +17,11 @@
 package org.apache.sis.metadata.iso.quality;
 
 import java.util.Locale;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.quality.Result;
 import org.opengis.util.InternationalString;
 import org.apache.sis.internal.jaxb.lan.FreeTextMarshallingTest;
-import org.apache.sis.util.Version;
 import org.apache.sis.metadata.xml.TestUsingFile;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
@@ -43,9 +43,14 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
 @DependsOn(FreeTextMarshallingTest.class)
 public final class AbstractPositionalAccuracyTest extends TestUsingFile {
     /**
-     * An XML file containing quality information.
+     * Opens the stream to the XML file containing quality information.
+     *
+     * @param  format  whether to use the 2007 or 2016 version of ISO 19115.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String FILENAME = "PositionalAccuracy.xml";
+    private static InputStream openTestFile(final Format format) {
+        return format.openTestFile("PositionalAccuracy.xml");
+    }
 
     /**
      * Tests the (un)marshalling of a text group with a default {@code 
<gco:CharacterString>} element.
@@ -58,7 +63,7 @@ public final class AbstractPositionalAccuracyTest extends 
TestUsingFile {
      */
     @Test
     public void testXML() throws JAXBException {
-        roundtrip(XML2016+FILENAME, VERSION_2014);
+        roundtrip(Format.XML2016);
     }
 
     /**
@@ -68,7 +73,7 @@ public final class AbstractPositionalAccuracyTest extends 
TestUsingFile {
      */
     @Test
     public void testLegacyXML() throws JAXBException {
-        roundtrip(XML2007+FILENAME, VERSION_2007);
+        roundtrip(Format.XML2007);
     }
 
     /**
@@ -76,8 +81,8 @@ public final class AbstractPositionalAccuracyTest extends 
TestUsingFile {
      * Then marshals the object and verify that we get equivalent XML.
      */
     @SuppressWarnings("deprecation")
-    private void roundtrip(final String filename, final Version version) 
throws JAXBException {
-        final AbstractElement metadata = unmarshalFile(AbstractElement.class, 
filename);
+    private void roundtrip(final Format format) throws JAXBException {
+        final AbstractElement metadata = unmarshalFile(AbstractElement.class, 
openTestFile(format));
         final InternationalString nameOfMeasure = 
getSingleton(metadata.getNamesOfMeasure());
         /*
          * Programmatic verification of the text group.
@@ -95,6 +100,7 @@ public final class AbstractPositionalAccuracyTest extends 
TestUsingFile {
         /*
          * Marshalling: ensure that we didn't lost any information.
          */
-        assertMarshalEqualsFile(filename, metadata, version, "xmlns:*", 
"xsi:schemaLocation", "xsi:type");
+        assertMarshalEqualsFile(openTestFile(format), metadata, 
format.schemaVersion,
+                                "xmlns:*", "xsi:schemaLocation", "xsi:type");
     }
 }
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/xml/TestUsingFile.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/xml/TestUsingFile.java
index da335528fb..6ef8f9cc2b 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/metadata/xml/TestUsingFile.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/metadata/xml/TestUsingFile.java
@@ -16,7 +16,10 @@
  */
 package org.apache.sis.metadata.xml;
 
+import java.net.URL;
+import java.io.InputStream;
 import org.apache.sis.test.xml.TestCase;
+import org.apache.sis.util.Version;
 
 
 /**
@@ -25,19 +28,54 @@ import org.apache.sis.test.xml.TestCase;
  * whether ISO 19139:2007 or ISO 19115-3:2016 schema is used.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   1.0
  */
 public abstract class TestUsingFile extends TestCase {
     /**
-     * The sub-directory of XML files encoded according the ISO 19115-3:2016 
schema.
+     * Identification of the data to use for a test.
      */
-    protected static final String XML2016 = "2016/";
+    protected enum Format {
+        /** A document in the sub-directory of XML files encoded according the 
ISO 19115-3:2016 schema. */
+        XML2016(VERSION_2014, "2016/"),
 
-    /**
-     * The sub-directory of XML files encoded according the ISO 19139:2007 
schema.
-     */
-    protected static final String XML2007 = "2007/";
+        /** A document in the sub-directory of XML files encoded according the 
ISO 19139:2007 schema. */
+        XML2007(VERSION_2007, "2007/");
+
+        /** Version of the XML schema used by this format. */
+        public final Version schemaVersion;
+
+        /** The directory (relative to the {@code TestUsingFile.class} file) 
of the XML document. */
+        private final String directory;
+
+        /** Creates a new enumeration for documents in the specified 
sub-directory. */
+        private Format(final Version schemaVersion, final String directory) {
+            this.schemaVersion = schemaVersion;
+            this.directory = directory;
+        }
+
+        /**
+         * Returns the URL to the specified XML file.
+         *
+         * @param  filename  the XML file in the directory represented by this 
enumeration.
+         * @return URL to the specified file.
+         */
+        public final URL getURL(final String filename) {
+            // Call to `getResource(…)` is caller sensitive: it must be in the 
same module.
+            return TestUsingFile.class.getResource(directory.concat(filename));
+        }
+
+        /**
+         * Opens the stream to the specified XML file.
+         *
+         * @param  filename  the XML file in the directory represented by this 
enumeration.
+         * @return stream opened on the XML document to use for testing 
purpose.
+         */
+        public final InputStream openTestFile(final String filename) {
+            // Call to `getResourceAsStream(…)` is caller sensitive: it must 
be in the same module.
+            return 
TestUsingFile.class.getResourceAsStream(directory.concat(filename));
+        }
+    }
 
     /**
      * For sub-class constructors only.
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
 
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
index af91b44bdb..943b317a18 100644
--- 
a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
+++ 
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/DocumentComparator.java
@@ -73,7 +73,7 @@ import static org.apache.sis.util.Characters.NO_BREAK_SPACE;
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Guilhem Legal (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see TestCase
  * @see org.apache.sis.test.MetadataAssert#assertXmlEquals(Object, Object, 
String[])
@@ -186,8 +186,10 @@ public class DocumentComparator {
      * The inputs can be any of the following types:
      *
      * <ul>
-     *   <li>{@link Node}; used directly without further processing.</li>
-     *   <li>{@link Path}, {@link File}, {@link URL} or {@link URI}: the 
stream is opened and parsed as a XML document.</li>
+     *   <li>{@link Node}: used directly without further processing.</li>
+     *   <li>{@link InputStream}: parsed as an XML document, then closed.</li>
+     *   <li>{@link Path}, {@link File}, {@link URL} or {@link URI}:
+     *       the stream is opened and parsed as an XML document, then 
closed.</li>
      *   <li>{@link String}: The string content is parsed directly as a XML 
document.</li>
      * </ul>
      *
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/TestCase.java 
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/TestCase.java
index 33383b4e70..dfc57faf64 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/TestCase.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/TestCase.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.test.xml;
 
-import java.net.URL;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
@@ -25,11 +24,13 @@ import java.util.Date;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.text.ParseException;
+import java.io.InputStream;
 import java.io.StringReader;
 import java.io.StringWriter;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
 import jakarta.xml.bind.JAXBException;
+import java.io.IOException;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.xml.LegacyNamespaces;
 import org.apache.sis.internal.jaxb.cat.CodeListUID;
@@ -176,29 +177,11 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
     }
 
     /**
-     * Returns the URL to the XML file of the given name.
-     * The file shall be in the same package than a subclass of {@code this}.
-     * This method begins the search in the package of {@link #getClass()}.
-     * If the resource is not found in that package, then this method searches 
in the parent classes.
-     * The intent is to allow some test classes to be overridden in different 
modules.
+     * Marshals the given object and ensures that the result is equal to the 
content of the given stream.
+     * The stream should be opened by a call to {@link 
Class#getResourceAsStream(String)} from the module
+     * that contains the resource, and the stream will be closed by this 
method.
      *
-     * @param  filename  the name of the XML file.
-     * @return the URL to the given XML file.
-     */
-    private URL getResource(final String filename) {
-        Class<?> c = getClass();
-        do {
-            final URL resource = c.getResource(filename);
-            if (resource != null) return resource;
-            c = c.getSuperclass();
-        } while (!c.equals(TestCase.class));
-        throw new AssertionError("Test resource not found: " + filename);
-    }
-
-    /**
-     * Marshals the given object and ensure that the result is equal to the 
content of the given file.
-     *
-     * @param  filename           the name of the XML file in the package of 
the final subclass of {@code this}.
+     * @param  expected           a stream opened on an XML document with the 
expected content.
      * @param  object             the object to marshal.
      * @param  ignoredAttributes  the fully-qualified names of attributes to 
ignore
      *                            (typically {@code "xmlns:*"} and {@code 
"xsi:schemaLocation"}).
@@ -206,35 +189,47 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
      *
      * @see #unmarshalFile(Class, String)
      */
-    protected final void assertMarshalEqualsFile(final String filename, final 
Object object,
+    protected final void assertMarshalEqualsFile(final InputStream expected, 
final Object object,
             final String... ignoredAttributes) throws JAXBException
     {
-        assertXmlEquals(getResource(filename), marshal(object), 
ignoredAttributes);
+        assertNotNull("Test resource is not found or not accessible.", 
expected);
+        try (expected) {
+            assertXmlEquals(expected, marshal(object), ignoredAttributes);
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
     }
 
     /**
-     * Marshals the given object and ensure that the result is equal to the 
content of the given file.
+     * Marshals the given object and ensures that the result is equal to the 
content of the given stream.
+     * The stream should be opened by a call to {@link 
Class#getResourceAsStream(String)} from the module
+     * that contains the resource, and the stream will be closed by this 
method.
      *
-     * @param  filename           the name of the XML file in the package of 
the final subclass of {@code this}.
+     * @param  expected           a stream opened on an XML document with the 
expected content.
      * @param  object             the object to marshal.
      * @param  metadataVersion    whether to marshal legacy 19139:2007 or 
newer ISO 19115-3 document. Can be {@code null}.
      * @param  ignoredAttributes  the fully-qualified names of attributes to 
ignore
      *                            (typically {@code "xmlns:*"} and {@code 
"xsi:schemaLocation"}).
      * @throws JAXBException if an error occurred during marshalling.
-     *
-     * @since 1.0
      */
-    protected final void assertMarshalEqualsFile(final String filename, final 
Object object,
+    protected final void assertMarshalEqualsFile(final InputStream expected, 
final Object object,
             final Version metadataVersion, final String... ignoredAttributes) 
throws JAXBException
     {
-        assertXmlEquals(getResource(filename), marshal(object, 
metadataVersion), ignoredAttributes);
+        assertNotNull("Test resource is not found or not accessible.", 
expected);
+        try (expected) {
+            assertXmlEquals(expected, marshal(object, metadataVersion), 
ignoredAttributes);
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
     }
 
     /**
-     * Marshals the given object and ensure that the result is equal to the 
content of the given file,
+     * Marshals the given object and ensures that the result is equal to the 
content of the given stream,
      * within a tolerance threshold for numerical values.
+     * The stream should be opened by a call to {@link 
Class#getResourceAsStream(String)} from the module
+     * that contains the resource, and the stream will be closed by this 
method.
      *
-     * @param  filename           the name of the XML file in the package of 
the final subclass of {@code this}.
+     * @param  expected           a stream opened on an XML document with the 
expected content.
      * @param  object             the object to marshal.
      * @param  metadataVersion    whether to marshal legacy 19139:2007 or 
newer ISO 19115-3 document. Can be {@code null}.
      * @param  tolerance          the tolerance threshold for comparison of 
numerical values.
@@ -244,13 +239,16 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
      * @throws JAXBException if an error occurred during marshalling.
      *
      * @see #unmarshalFile(Class, String)
-     *
-     * @since 1.0
      */
-    protected final void assertMarshalEqualsFile(final String filename, final 
Object object, final Version metadataVersion,
+    protected final void assertMarshalEqualsFile(final InputStream expected, 
final Object object, final Version metadataVersion,
             final double tolerance, final String[] ignoredNodes, final 
String[] ignoredAttributes) throws JAXBException
     {
-        assertXmlEquals(getResource(filename), marshal(object, 
metadataVersion), tolerance, ignoredNodes, ignoredAttributes);
+        assertNotNull("Test resource is not found or not accessible.", 
expected);
+        try (expected) {
+            assertXmlEquals(expected, marshal(object, metadataVersion), 
tolerance, ignoredNodes, ignoredAttributes);
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
     }
 
     /**
@@ -279,8 +277,6 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
      * @param  metadataVersion  whether to marshal legacy 19139:2007 or newer 
ISO 19115-3 document. Can be {@code null}.
      * @return the marshalled object.
      * @throws JAXBException if an error occurred while marshalling the object.
-     *
-     * @since 1.0
      */
     protected final String marshal(final Object object, final Version 
metadataVersion) throws JAXBException {
         final MarshallerPool pool = getMarshallerPool();
@@ -314,24 +310,28 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
 
     /**
      * Unmarshals the content of the given test file using the {@linkplain 
#getMarshallerPool() test marshaller pool}.
-     * The resource is obtained by a call to {@code 
getClass().getResource(filename)}, which implies that the file
-     * shall be in the same package than the subclass of {@code this}.
+     * The stream should be opened by a call to {@link 
Class#getResourceAsStream(String)} from the module
+     * that contains the resource, and the stream will be closed by this 
method.
      *
-     * @param  <T>       compile-time type of {@code type} argument.
-     * @param  type      the expected type of the unmarshalled object.
-     * @param  filename  the name of the XML file in the package of the final 
subclass of {@code this}.
+     * @param  <T>    compile-time type of {@code type} argument.
+     * @param  type   the expected type of the unmarshalled object.
+     * @param  input  a stream opened on the document to unmarshall.
      * @return the object unmarshalled from the given file.
      * @throws JAXBException if an error occurred during unmarshalling.
      *
      * @see #assertMarshalEqualsFile(String, Object, String...)
      */
-    protected final <T> T unmarshalFile(final Class<T> type, final String 
filename) throws JAXBException {
-        final MarshallerPool pool = getMarshallerPool();
-        final Unmarshaller unmarshaller = pool.acquireUnmarshaller();
-        final Object object = unmarshaller.unmarshal(getResource(filename));
-        pool.recycle(unmarshaller);
-        assertInstanceOf(filename, type, object);
-        return type.cast(object);
+    protected final <T> T unmarshalFile(final Class<T> type, final InputStream 
input) throws JAXBException {
+        assertNotNull("Test resource is not found or not accessible.", input);
+        try (input) {
+            final MarshallerPool pool = getMarshallerPool();
+            final Unmarshaller unmarshaller = pool.acquireUnmarshaller();
+            final Object object = unmarshaller.unmarshal(input);
+            pool.recycle(unmarshaller);
+            return type.cast(object);
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
     }
 
     /**
@@ -412,8 +412,6 @@ public abstract class TestCase extends 
org.apache.sis.test.TestCase {
      *
      * @param  xml  an XML compliant with ISO 19115-3.
      * @return an XML compliant with ISO 19139:2007.
-     *
-     * @since 1.0
      */
     protected static String toLegacyXML(final String xml) {
         final StringBuilder buffer = new StringBuilder(xml);
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/package-info.java 
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/package-info.java
index ce8b8817ab..2f930676fe 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/package-info.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/package-info.java
@@ -25,7 +25,7 @@
  * in any future version without notice.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   1.0
  */
 package org.apache.sis.test.xml;
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
index 62ebf8ba27..f201d86467 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.parameter;
 import java.util.Map;
 import java.util.Iterator;
 import java.util.Objects;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import jakarta.xml.bind.JAXBException;
@@ -58,6 +59,34 @@ import static 
org.apache.sis.referencing.Assertions.assertEpsgNameAndIdentifierE
     DefaultParameterValueGroupTest.class
 })
 public final class ParameterMarshallingTest extends TestCase {
+    /**
+     * Enumeration of test files.
+     */
+    private enum TestFile {
+        /** GML document of a parameter descriptor group. */
+        DESCRIPTOR("ParameterDescriptorGroup.xml"),
+
+        /** GML document of a parameter value group. */
+        VALUE("ParameterValueGroup.xml"),
+
+        /** GML document containing duplicated parameters. */
+        DUPLICATED("DuplicatedParameters.xml");
+
+        /** Relative filename of the GML document. */
+        private final String filename;
+
+        /** Creates an enumeration for a GML document in the specified file. */
+        private TestFile(final String filename) {
+            this.filename = filename;
+        }
+
+        /** Opens the stream to the XML file containing the test document. */
+        final InputStream openTestFile() {
+            // Call to `getResourceAsStream(…)` is caller sensitive: it must 
be in the same module.
+            return 
ParameterMarshallingTest.class.getResourceAsStream(filename);
+        }
+    }
+
     /**
      * Creates a parameter value for marshalling test.
      */
@@ -289,11 +318,11 @@ public final class ParameterMarshallingTest extends 
TestCase {
     @DependsOnMethod("testDoubleValue")
     public void testDescriptorGroup() throws JAXBException {
         // Test marshalling.
-        assertMarshalEqualsFile("ParameterDescriptorGroup.xml",
+        assertMarshalEqualsFile(TestFile.DESCRIPTOR.openTestFile(),
                 ParameterFormatTest.createMercatorParameters(), "xmlns:*", 
"xsi:schemaLocation");
 
         // Test unmarshalling.
-        
verifyDescriptorGroup(unmarshalFile(DefaultParameterDescriptorGroup.class, 
"ParameterDescriptorGroup.xml"));
+        
verifyDescriptorGroup(unmarshalFile(DefaultParameterDescriptorGroup.class, 
TestFile.DESCRIPTOR.openTestFile()));
     }
 
     /**
@@ -367,7 +396,7 @@ public final class ParameterMarshallingTest extends 
TestCase {
     @Test
     @DependsOnMethod("testDescriptorGroup")
     public void testValueGroupMmarshalling() throws JAXBException {
-        assertMarshalEqualsFile("ParameterValueGroup.xml",
+        assertMarshalEqualsFile(TestFile.VALUE.openTestFile(),
                 ParameterFormatTest.createMercatorParameters().createValue(),
                 "xmlns:*", "xsi:schemaLocation");
     }
@@ -381,7 +410,7 @@ public final class ParameterMarshallingTest extends 
TestCase {
     @Test
     @DependsOnMethod("testDescriptorGroup")
     public void testValueGroupUnmarshalling() throws JAXBException {
-        testValueGroupUnmarshalling("ParameterValueGroup.xml");
+        testValueGroupUnmarshalling(TestFile.VALUE);
     }
 
     /**
@@ -394,14 +423,14 @@ public final class ParameterMarshallingTest extends 
TestCase {
     @Test
     @DependsOnMethod("testValueGroupUnmarshalling")
     public void testDuplicatedParametersUnmarshalling() throws JAXBException {
-        testValueGroupUnmarshalling("DuplicatedParameters.xml");
+        testValueGroupUnmarshalling(TestFile.DUPLICATED);
     }
 
     /**
      * Tests unmarshalling of the given file.
      */
-    private void testValueGroupUnmarshalling(final String file) throws 
JAXBException {
-        final DefaultParameterValueGroup group = 
unmarshalFile(DefaultParameterValueGroup.class, file);
+    private void testValueGroupUnmarshalling(final TestFile file) throws 
JAXBException {
+        final DefaultParameterValueGroup group = 
unmarshalFile(DefaultParameterValueGroup.class, file.openTestFile());
         verifyDescriptorGroup(group.getDescriptor());
         final Iterator<GeneralParameterValue> it = group.values().iterator();
         final Iterator<GeneralParameterDescriptor> itd = 
group.getDescriptor().descriptors().iterator();
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
index c42c2aa931..b19549f250 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.test.Validators;
 import org.opengis.referencing.cs.AxisDirection;
@@ -68,9 +69,14 @@ public final class DefaultCompoundCRSTest extends TestCase {
     private static final DefaultTemporalCRS TIME = HardCodedCRS.TIME;
 
     /**
-     * An XML file in this package containing a projected CRS definition.
+     * Opens the stream to the XML file in this package containing a projected 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "CompoundCRS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultCompoundCRSTest.class.getResourceAsStream("CompoundCRS.xml");
+    }
 
     /**
      * Verifies that we do not allow construction with a duplicated horizontal 
or vertical component.
@@ -332,7 +338,7 @@ public final class DefaultCompoundCRSTest extends TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultCompoundCRS crs = unmarshalFile(DefaultCompoundCRS.class, 
XML_FILE);
+        final DefaultCompoundCRS crs = unmarshalFile(DefaultCompoundCRS.class, 
openTestFile());
         Validators.validate(crs);
         assertEpsgNameAndIdentifierEqual("JGD2011 + JGD2011 (vertical) 
height", 6697, crs);
         assertAxisDirectionsEqual("coordinateSystem", 
crs.getCoordinateSystem(), AxisDirection.NORTH, AxisDirection.EAST, 
AxisDirection.UP);
@@ -347,6 +353,6 @@ public final class DefaultCompoundCRSTest extends TestCase {
         /*
          * Test marshalling and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, crs, "xmlns:*", 
"xsi:schemaLocation", "gml:id");
+        assertMarshalEqualsFile(openTestFile(), crs, "xmlns:*", 
"xsi:schemaLocation", "gml:id");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
index 7d300d3cb6..bb6c594b1d 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.crs;
 
 import java.util.Map;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.cs.AxisDirection;
@@ -57,9 +58,14 @@ import static 
org.apache.sis.referencing.Assertions.assertWktEquals;
 })
 public final class DefaultDerivedCRSTest extends TestCase {
     /**
-     * An XML file in this package containing a projected CRS definition.
+     * Opens the stream to the XML file in this package containing a projected 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "DerivedCRS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultDerivedCRSTest.class.getResourceAsStream("DerivedCRS.xml");
+    }
 
     /**
      * Tests {@link DefaultDerivedCRS#getType(SingleCRS, CoordinateSystem)}.
@@ -224,7 +230,7 @@ public final class DefaultDerivedCRSTest extends TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultDerivedCRS crs = unmarshalFile(DefaultDerivedCRS.class, 
XML_FILE);
+        final DefaultDerivedCRS crs = unmarshalFile(DefaultDerivedCRS.class, 
openTestFile());
         Validators.validate(crs);
         assertEpsgNameAndIdentifierEqual("WGS 84", 4979, crs.getBaseCRS());
         assertAxisDirectionsEqual("baseCRS", 
crs.getBaseCRS().getCoordinateSystem(), AxisDirection.NORTH, 
AxisDirection.EAST, AxisDirection.UP);
@@ -239,6 +245,6 @@ public final class DefaultDerivedCRSTest extends TestCase {
         /*
          * Test marshalling and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, crs, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), crs, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeodeticCRSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeodeticCRSTest.java
index 7d26b4dbd9..b45d766345 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeodeticCRSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeodeticCRSTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.crs;
 
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.test.Validators;
 import org.apache.sis.referencing.GeodeticObjectVerifier;
@@ -42,9 +43,14 @@ import static org.junit.Assert.*;
 })
 public final class DefaultGeodeticCRSTest extends TestCase {
     /**
-     * An XML file in this package containing a geodetic CRS definition.
+     * Opens the stream to the XML file in this package containing a geodetic 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "GeographicCRS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultGeodeticCRSTest.class.getResourceAsStream("GeographicCRS.xml");
+    }
 
     /**
      * Tests (un)marshalling of a geodetic coordinate reference system.
@@ -53,7 +59,7 @@ public final class DefaultGeodeticCRSTest extends TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultGeodeticCRS crs = unmarshalFile(DefaultGeodeticCRS.class, 
XML_FILE);
+        final DefaultGeodeticCRS crs = unmarshalFile(DefaultGeodeticCRS.class, 
openTestFile());
         Validators.validate(crs);
         GeodeticObjectVerifier.assertIsWGS84(crs, false, true);
         /*
@@ -64,6 +70,6 @@ public final class DefaultGeodeticCRSTest extends TestCase {
         /*
          * Marshal and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, crs, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), crs, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
index cdd3ad40b7..5b0fb0a4e1 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.crs;
 
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.ProjectedCRS;
@@ -63,6 +64,16 @@ import static 
org.apache.sis.referencing.Assertions.assertWktEquals;
     org.apache.sis.referencing.operation.DefaultConversionTest.class
 })
 public final class DefaultProjectedCRSTest extends TestCase {
+    /**
+     * Opens the stream to the XML file in this package containing a projected 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
+     */
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultProjectedCRSTest.class.getResourceAsStream("ProjectedCRS.xml");
+    }
+
     /**
      * A JUnit rule for listening to log events emitted during execution of 
{@link #testWKT1_WithExplicitAxisLength()}.
      * This rule is used by the test methods for verifying that the logged 
messages contain the expected information.
@@ -83,11 +94,6 @@ public final class DefaultProjectedCRSTest extends TestCase {
         loggings.assertNoUnexpectedLog();
     }
 
-    /**
-     * An XML file in this package containing a projected CRS definition.
-     */
-    private static final String XML_FILE = "ProjectedCRS.xml";
-
     /**
      * Creates a projected CRS and verifies its parameters.
      * Verifies also that the constructor does not accept invalid base CRS.
@@ -471,7 +477,7 @@ public final class DefaultProjectedCRSTest extends TestCase 
{
      */
     @Test
     public void testXML() throws FactoryException, JAXBException {
-        final DefaultProjectedCRS crs = 
unmarshalFile(DefaultProjectedCRS.class, XML_FILE);
+        final DefaultProjectedCRS crs = 
unmarshalFile(DefaultProjectedCRS.class, openTestFile());
         Validators.validate(crs);
         assertEpsgNameAndIdentifierEqual("NTF (Paris) / Lambert zone II", 
27572, crs);
         assertEpsgNameAndIdentifierEqual("NTF (Paris)", 4807, 
crs.getBaseCRS());
@@ -488,7 +494,7 @@ public final class DefaultProjectedCRSTest extends TestCase 
{
          * Test marshalling and compare with the original file. The comparison 
ignores the <gml:name> nodes because the
          * marshalled CRS contains many operation method and parameter aliases 
which were not in the original XML file.
          */
-        assertMarshalEqualsFile(XML_FILE, crs, null, STRICT, new String[] 
{"gml:name"},
+        assertMarshalEqualsFile(openTestFile(), crs, null, STRICT, new 
String[] {"gml:name"},
                 new String[] {"xmlns:*", "xsi:schemaLocation", "gml:id"});
     }
 
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
index 60e2815bc5..7c82ce54de 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.cs;
 
 import java.util.Map;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.test.Validators;
 import org.opengis.referencing.cs.AxisDirection;
@@ -49,9 +50,14 @@ import static 
org.apache.sis.referencing.Assertions.assertEpsgIdentifierEquals;
 })
 public final class DefaultCartesianCSTest extends TestCase {
     /**
-     * An XML file in this package containing a Cartesian coordinate system 
definition.
+     * Opens the stream to the XML file in this package containing a Cartesian 
coordinate system definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "CartesianCS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultCartesianCSTest.class.getResourceAsStream("CartesianCS.xml");
+    }
 
     /**
      * Tests the creation of a Cartesian CS with legal axes.
@@ -205,7 +211,7 @@ public final class DefaultCartesianCSTest extends TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultCartesianCS cs = unmarshalFile(DefaultCartesianCS.class, 
XML_FILE);
+        final DefaultCartesianCS cs = unmarshalFile(DefaultCartesianCS.class, 
openTestFile());
         Validators.validate(cs);
         GeodeticObjectVerifier.assertIsProjected2D(cs);
         /*
@@ -224,6 +230,6 @@ public final class DefaultCartesianCSTest extends TestCase {
         /*
          * Marshal and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, cs, "xmlns:*", "xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), cs, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCSTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCSTest.java
index b0d67d51f4..7d2e1a0045 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCSTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCSTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.cs;
 
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.test.Validators;
 import org.opengis.referencing.cs.AxisDirection;
@@ -44,9 +45,14 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
 @DependsOn(AbstractCSTest.class)
 public final class DefaultEllipsoidalCSTest extends TestCase {
     /**
-     * An XML file in this package containing an ellipsoidal coordinate system 
definition.
+     * Opens the stream to the XML file in this package containing an 
ellipsoidal coordinate system definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "EllipsoidalCS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultEllipsoidalCSTest.class.getResourceAsStream("EllipsoidalCS.xml");
+    }
 
     /**
      * Tests the {@link DefaultEllipsoidalCS#forConvention(AxesConvention)} 
method.
@@ -121,7 +127,7 @@ public final class DefaultEllipsoidalCSTest extends 
TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultEllipsoidalCS cs = 
unmarshalFile(DefaultEllipsoidalCS.class, XML_FILE);
+        final DefaultEllipsoidalCS cs = 
unmarshalFile(DefaultEllipsoidalCS.class, openTestFile());
         Validators.validate(cs);
         GeodeticObjectVerifier.assertIsGeodetic2D(cs, true);
         /*
@@ -140,6 +146,6 @@ public final class DefaultEllipsoidalCSTest extends 
TestCase {
         /*
          * Marshal and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, cs, "xmlns:*", "xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), cs, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
index b6683e64d2..82f8dc614f 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.datum;
 
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.apache.sis.measure.Units;
 import org.apache.sis.test.xml.TestCase;
@@ -40,14 +41,15 @@ import static 
org.apache.sis.referencing.Assertions.assertWktEquals;
 })
 public final class DefaultEllipsoidTest extends TestCase {
     /**
-     * An XML file in this package containing an ellipsoid definition.
-     */
-    private static final String ELLIPSOID_FILE = "Ellipsoid.xml";
-
-    /**
-     * An XML file in this package containing a sphere definition.
+     * Opens the stream to the XML file in this package containing an 
ellipsoid or sphere definition.
+     *
+     * @param  sphere  {@code true} for a sphere or {@code false} for an 
ellipsoid.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String SPHERE_FILE = "Sphere.xml";
+    private static InputStream openTestFile(final boolean sphere) {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return DefaultEllipsoidTest.class.getResourceAsStream(sphere ? 
"Sphere.xml" : "Ellipsoid.xml");
+    }
 
     /**
      * Tests {@link DefaultEllipsoid#getEccentricity()}.
@@ -132,7 +134,7 @@ public final class DefaultEllipsoidTest extends TestCase {
      */
     @Test
     public void testEllipsoidXML() throws JAXBException {
-        final DefaultEllipsoid ellipsoid = 
unmarshalFile(DefaultEllipsoid.class, ELLIPSOID_FILE);
+        final DefaultEllipsoid ellipsoid = 
unmarshalFile(DefaultEllipsoid.class, openTestFile(false));
         assertEquals("name", "Clarke 1880 (international foot)", 
ellipsoid.getName().getCode());
         assertEquals("remarks", "Definition in feet assumed to be 
international foot.", ellipsoid.getRemarks().toString());
         assertFalse ("isSphere",                              
ellipsoid.isSphere());
@@ -144,7 +146,7 @@ public final class DefaultEllipsoidTest extends TestCase {
         /*
          * Marshal and compare to the original file.
          */
-        assertMarshalEqualsFile(ELLIPSOID_FILE, ellipsoid, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(false), ellipsoid, "xmlns:*", 
"xsi:schemaLocation");
     }
 
     /**
@@ -158,7 +160,7 @@ public final class DefaultEllipsoidTest extends TestCase {
      */
     @Test
     public void testSphereXML() throws JAXBException {
-        final DefaultEllipsoid ellipsoid = 
unmarshalFile(DefaultEllipsoid.class, SPHERE_FILE);
+        final DefaultEllipsoid ellipsoid = 
unmarshalFile(DefaultEllipsoid.class, openTestFile(true));
         assertEquals("name", "GRS 1980 Authalic Sphere", 
ellipsoid.getName().getCode());
         assertEquals("remarks", "Authalic sphere derived from GRS 1980 
ellipsoid (code 7019).", ellipsoid.getRemarks().toString());
         assertTrue  ("isSphere",                                    
ellipsoid.isSphere());
@@ -170,6 +172,6 @@ public final class DefaultEllipsoidTest extends TestCase {
         /*
          * Marshal and compare to the original file.
          */
-        assertMarshalEqualsFile(SPHERE_FILE, ellipsoid, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(true), ellipsoid, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
index 73b933a1bf..dac14a0a5d 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.datum;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.referencing.operation.Matrix;
@@ -61,9 +62,14 @@ import static 
org.apache.sis.referencing.GeodeticObjectVerifier.*;
 })
 public final class DefaultGeodeticDatumTest extends TestCase {
     /**
-     * An XML file in this package containing a geodetic datum definition.
+     * Opens the stream to the XML file in this package containing a geodetic 
datum definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "GeodeticDatum.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultGeodeticDatumTest.class.getResourceAsStream("GeodeticDatum.xml");
+    }
 
     /**
      * Tests the creation and serialization of a {@link DefaultGeodeticDatum}.
@@ -289,7 +295,7 @@ public final class DefaultGeodeticDatumTest extends 
TestCase {
      */
     @TestStep
     public DefaultGeodeticDatum testUnmarshalling() throws JAXBException {
-        final DefaultGeodeticDatum datum = 
unmarshalFile(DefaultGeodeticDatum.class, XML_FILE);
+        final DefaultGeodeticDatum datum = 
unmarshalFile(DefaultGeodeticDatum.class, openTestFile());
         assertIsWGS84(datum, true);
         /*
          * Values in the following tests are specific to our XML file.
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
index 6a658dc2ec..e33a45e5db 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.datum;
 
 import java.util.Map;
+import java.io.InputStream;
 import javax.measure.quantity.Angle;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
@@ -49,9 +50,15 @@ import static 
org.apache.sis.referencing.GeodeticObjectVerifier.*;
 @DependsOn(org.apache.sis.referencing.AbstractIdentifiedObjectTest.class)
 public final class DefaultPrimeMeridianTest extends TestCase {
     /**
-     * An XML file in this package containing a prime meridian definition.
+     * Opens the stream to the XML file in this package containing a prime 
meridian definition.
+     *
+     * @param  greenwich  {@code true} for Greenwich meridian or {@code false} 
for an arbitrary one.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "Greenwich.xml";
+    private static InputStream openTestFile(final boolean greenwich) {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return DefaultPrimeMeridianTest.class.getResourceAsStream(greenwich ? 
"Greenwich.xml" : "PrimeMeridian.xml");
+    }
 
     /**
      * Tests {@link DefaultPrimeMeridian#toWKT()}.
@@ -151,7 +158,7 @@ public final class DefaultPrimeMeridianTest extends 
TestCase {
      */
     @Test
     public void testUnmarshall() throws JAXBException {
-        final DefaultPrimeMeridian pm = 
unmarshalFile(DefaultPrimeMeridian.class, XML_FILE);
+        final DefaultPrimeMeridian pm = 
unmarshalFile(DefaultPrimeMeridian.class, openTestFile(true));
         assertIsGreenwich(pm);
     }
 
@@ -180,7 +187,7 @@ public final class DefaultPrimeMeridianTest extends 
TestCase {
     @Test
     @DependsOnMethod({"testUnmarshall", "testMarshall", "testWKT_inGrads"})
     public void testParisMeridian() throws JAXBException {
-        final DefaultPrimeMeridian pm = 
unmarshalFile(DefaultPrimeMeridian.class, "PrimeMeridian.xml");
+        final DefaultPrimeMeridian pm = 
unmarshalFile(DefaultPrimeMeridian.class, openTestFile(false));
         assertIsParis(pm);
         assertEquals("greenwichLongitude", 2.33722917, 
pm.getGreenwichLongitude(Units.DEGREE), 1E-12);
         assertEquals("Equivalent to 2°20′14.025″.", 
pm.getRemarks().toString());
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
index a3bcf85fa8..3eccb35fd5 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.datum;
 import java.util.Date;
 import java.util.Map;
 import java.util.HashMap;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.referencing.ImmutableIdentifier;
@@ -42,9 +43,14 @@ import static 
org.apache.sis.internal.util.StandardDateFormat.MILLISECONDS_PER_D
  */
 public final class DefaultTemporalDatumTest extends TestCase {
     /**
-     * An XML file in this package containing a vertical datum definition.
+     * Opens the stream to the XML file in this package containing a vertical 
datum definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "TemporalDatum.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultTemporalDatumTest.class.getResourceAsStream("TemporalDatum.xml");
+    }
 
     /**
      * November 17, 1858 at 00:00 UTC as a Java timestamp.
@@ -101,7 +107,7 @@ public final class DefaultTemporalDatumTest extends 
TestCase {
     @Test
     public void testMarshalling() throws JAXBException {
         final DefaultTemporalDatum datum = create();
-        assertMarshalEqualsFile(XML_FILE, datum, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), datum, "xmlns:*", 
"xsi:schemaLocation");
     }
 
     /**
@@ -111,7 +117,7 @@ public final class DefaultTemporalDatumTest extends 
TestCase {
      */
     @Test
     public void testUnmarshalling() throws JAXBException {
-        final DefaultTemporalDatum datum = 
unmarshalFile(DefaultTemporalDatum.class, XML_FILE);
+        final DefaultTemporalDatum datum = 
unmarshalFile(DefaultTemporalDatum.class, openTestFile());
         assertIdentifierEquals("identifier", "Apache Spatial Information 
System", "SIS", null, "MJ",
                 getSingleton(datum.getIdentifiers()));
         assertEquals("name", "Modified Julian",
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
index ce33210e16..d4e9103f57 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.datum;
 
 import java.util.Map;
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
@@ -46,14 +47,17 @@ import static 
org.apache.sis.referencing.GeodeticObjectVerifier.*;
  */
 public final class DefaultVerticalDatumTest extends TestCase {
     /**
-     * An XML file in this package containing a vertical datum definition.
-     */
-    private static final String XML_FILE = "VerticalDatum.xml";
-
-    /**
-     * An XML file with the same content than {@link #XML_FILE}, but written 
in an older GML format.
+     * Opens the stream to the XML file in this package containing a vertical 
datum definition.
+     *
+     * @param  legacy  {@code true} for GML 3.1 or {@code false} for GML 3.2.
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String GML31_FILE = "VerticalDatum (GML 3.1).xml";
+    private static InputStream openTestFile(final boolean legacy) {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return DefaultVerticalDatumTest.class.getResourceAsStream(
+                legacy ? "VerticalDatum (GML 3.1).xml"
+                       : "VerticalDatum.xml");
+    }
 
     /**
      * Tests the {@link DefaultVerticalDatum#getVerticalDatumType()} method in 
a state
@@ -107,7 +111,7 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultVerticalDatum datum = 
unmarshalFile(DefaultVerticalDatum.class, XML_FILE);
+        final DefaultVerticalDatum datum = 
unmarshalFile(DefaultVerticalDatum.class, openTestFile(false));
         assertIsMeanSeaLevel(datum, true);
         /*
          * Following attribute does not exist in GML 3.2, so it has been 
inferred.
@@ -124,7 +128,7 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
         /*
          * Test marshalling and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, datum, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(false), datum, "xmlns:*", 
"xsi:schemaLocation");
     }
 
     /**
@@ -140,8 +144,7 @@ public final class DefaultVerticalDatumTest extends 
TestCase {
         final MarshallerPool pool = getMarshallerPool();
         final Unmarshaller unmarshaller = pool.acquireUnmarshaller();
         unmarshaller.setProperty(XML.GML_VERSION, version);
-        final DefaultVerticalDatum datum =
-                (DefaultVerticalDatum) 
unmarshaller.unmarshal(getClass().getResource(GML31_FILE));
+        final var datum = (DefaultVerticalDatum) 
unmarshaller.unmarshal(openTestFile(true));
         pool.recycle(unmarshaller);
         /*
          * Following attribute exists in GML 3.1 only.
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
index 69d36e446f..8123099ba2 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.operation;
 
 import java.util.Map;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.GeodeticCRS;
@@ -55,9 +56,14 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
 })
 public final class DefaultConcatenatedOperationTest extends TestCase {
     /**
-     * An XML file in this package containing a projected CRS definition.
+     * Opens the stream to the XML file in this package containing a projected 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "ConcatenatedOperation.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultConcatenatedOperationTest.class.getResourceAsStream("ConcatenatedOperation.xml");
+    }
 
     /**
      * Creates a “Tokyo to JGD2000” transformation.
@@ -135,7 +141,7 @@ public final class DefaultConcatenatedOperationTest extends 
TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultConcatenatedOperation op = 
unmarshalFile(DefaultConcatenatedOperation.class, XML_FILE);
+        final DefaultConcatenatedOperation op = 
unmarshalFile(DefaultConcatenatedOperation.class, openTestFile());
         Validators.validate(op);
         assertEquals("operations.size()", 2, op.getOperations().size());
         final CoordinateOperation step1 = op.getOperations().get(0);
@@ -156,6 +162,6 @@ public final class DefaultConcatenatedOperationTest extends 
TestCase {
         /*
          * Test marshalling and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, op, "xmlns:*", "xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), op, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
index 3e45eed476..0cc125450a 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.operation;
 
 import java.util.List;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.referencing.crs.CompoundCRS;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -46,9 +47,14 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
 })
 public final class DefaultPassThroughOperationTest extends TestCase {
     /**
-     * An XML file in this package containing a projected CRS definition.
+     * Opens the stream to the XML file in this package containing a projected 
CRS definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "PassThroughOperation.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return 
DefaultPassThroughOperationTest.class.getResourceAsStream("PassThroughOperation.xml");
+    }
 
     /**
      * Tests (un)marshalling of a concatenated operation.
@@ -57,7 +63,7 @@ public final class DefaultPassThroughOperationTest extends 
TestCase {
      */
     @Test
     public void testXML() throws JAXBException {
-        final DefaultPassThroughOperation toTest = 
unmarshalFile(DefaultPassThroughOperation.class, XML_FILE);
+        final DefaultPassThroughOperation toTest = 
unmarshalFile(DefaultPassThroughOperation.class, openTestFile());
         Validators.validate(toTest);
         final CoordinateReferenceSystem sourceCRS = toTest.getSourceCRS();
         final CoordinateReferenceSystem targetCRS = toTest.getTargetCRS();
@@ -79,6 +85,6 @@ public final class DefaultPassThroughOperationTest extends 
TestCase {
         /*
          * Test marshalling and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, toTest, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), toTest, "xmlns:*", 
"xsi:schemaLocation");
     }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/SingleOperationMarshallingTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/SingleOperationMarshallingTest.java
index b0763b61e3..6dfeb39a6c 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/SingleOperationMarshallingTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/SingleOperationMarshallingTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.operation;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.parameter.ParameterDescriptor;
@@ -67,6 +68,18 @@ import static 
org.apache.sis.metadata.Assertions.assertXmlEquals;
     org.apache.sis.parameter.ParameterMarshallingTest.class
 })
 public final class SingleOperationMarshallingTest extends TestCase {
+    /**
+     * Opens the stream to the XML file in this package containing an 
operation definition.
+     *
+     * @param  transformation  {@code true} for a transformation or {@code 
false} for a conversion.
+     * @return stream opened on the XML document to use for testing purpose.
+     */
+    private static InputStream openTestFile(final boolean transformation) {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return SingleOperationMarshallingTest.class.getResourceAsStream(
+                transformation ? "Transformation.xml" : "Conversion.xml");
+    }
+
     /**
      * Creates the test operation method.
      */
@@ -138,7 +151,7 @@ public final class SingleOperationMarshallingTest extends 
TestCase {
     @Test
     @DependsOnMethod("testOperationMethod")
     public void testConversionUnmarshalling() throws JAXBException {
-        final DefaultConversion c = unmarshalFile(DefaultConversion.class, 
"Conversion.xml");
+        final DefaultConversion c = unmarshalFile(DefaultConversion.class, 
openTestFile(false));
         assertEquals("name", "World Mercator", c.getName().getCode());
         assertEquals("identifier", "3395", 
getSingleton(c.getIdentifiers()).getCode());
         assertEquals("scope", "Very small scale mapping.", 
String.valueOf(c.getScope()));
@@ -198,7 +211,7 @@ public final class SingleOperationMarshallingTest extends 
TestCase {
     @Test
     @DependsOnMethod("testConversionUnmarshalling")
     public void testTransformationUnmarshalling() throws JAXBException {
-        final DefaultTransformation c = 
unmarshalFile(DefaultTransformation.class, "Transformation.xml");
+        final DefaultTransformation c = 
unmarshalFile(DefaultTransformation.class, openTestFile(true));
         assertEquals("name",             "NTF (Paris) to NTF (1)",    
c.getName().getCode());
         assertEquals("identifier",       "1763",                      
getSingleton(c.getIdentifiers()).getCode());
         assertEquals("scope",            "Change of prime meridian.", 
String.valueOf(c.getScope()));
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataVerticalTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataVerticalTest.java
index 1ac3c936dd..9da38465c8 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataVerticalTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataVerticalTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.test.integration;
 
 import java.net.URI;
 import java.util.Locale;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import jakarta.xml.bind.JAXBException;
 
@@ -73,10 +74,14 @@ import static 
org.apache.sis.test.TestUtilities.getSingleton;
 })
 public class MetadataVerticalTest extends TestCase {
     /**
-     * The resource file which contains an XML representation
-     * of a {@link Metadata} object with a {@link VerticalCRS}.
+     * Opens the stream to the XML representation of a {@link Metadata} object 
with a {@link VerticalCRS}.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "Metadata with vertical CRS.xml";
+    private static InputStream openTestFile() {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return MetadataVerticalTest.class.getResourceAsStream("Metadata with 
vertical CRS.xml");
+    }
 
     /**
      * A JUnit {@link Rule} for listening to log events. This field is public 
because JUnit requires us to
@@ -100,7 +105,7 @@ public class MetadataVerticalTest extends TestCase {
      */
     @Test
     public void testMetadataWithVerticalCRS() throws JAXBException {
-        final Metadata metadata = unmarshalFile(Metadata.class, XML_FILE);
+        final Metadata metadata = unmarshalFile(Metadata.class, 
openTestFile());
         assertEquals("fileIdentifier", "20090901",                     
metadata.getMetadataIdentifier().getCode());
         assertEquals("language",       Locale.ENGLISH,                 
getSingleton(metadata.getLocalesAndCharsets().keySet()));
         assertEquals("characterSet",   StandardCharsets.UTF_8,         
getSingleton(metadata.getLocalesAndCharsets().values()));
@@ -197,7 +202,7 @@ public class MetadataVerticalTest extends TestCase {
          *
          * Now marshal the object and compare with the original file.
          */
-        assertMarshalEqualsFile(XML_FILE, metadata, VERSION_2007, "xmlns:*", 
"xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), metadata, VERSION_2007, 
"xmlns:*", "xsi:schemaLocation");
     }
 
     /**
diff --git 
a/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java 
b/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
index c9a3c12133..dd3b61b4f9 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
@@ -24,6 +24,7 @@ import java.util.Random;
 import java.util.concurrent.Callable;
 import java.io.PrintWriter;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.file.Path;
 import java.nio.file.Files;
 import java.nio.file.StandardOpenOption;
@@ -53,7 +54,7 @@ import static 
org.apache.sis.internal.util.StandardDateFormat.UTC;
  * Miscellaneous utility methods for test cases.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.3
  */
 public final class TestUtilities extends Static {
@@ -457,21 +458,20 @@ public final class TestUtilities extends Static {
     }
 
     /**
-     * Copies the full content of the given test resource in a temporary file 
and returns the channel for that file.
+     * Copies the full content of the given input stream in a temporary file 
and returns the channel for that file.
      * The file is opened with {@link StandardOpenOption#DELETE_ON_CLOSE}, 
together with read and write options.
      *
-     * @param  caller    defines the root from which to search for the {@code 
resource}.
-     * @param  resource  path (relative to the {@code caller}) of the test 
file to copy.
+     * @param  data    the data to copy in the temporary file.
+     * @param  suffix  suffix (dot included) to append to the temporary file 
name, or {@code null} if none.
      * @return a channel opened on a copy of the content of the given test 
resource.
      * @throws IOException if an error occurred while copying the data.
      *
      * @since 0.8
      */
-    public static SeekableByteChannel createTemporaryFile(final Class<?> 
caller, final String resource) throws IOException {
+    public static SeekableByteChannel createTemporaryFile(final InputStream 
data, final String suffix) throws IOException {
         final SeekableByteChannel channel;
-        try (ReadableByteChannel in = 
Channels.newChannel(caller.getResourceAsStream(resource))) {
-            final int s = resource.lastIndexOf('.');
-            final Path file = Files.createTempFile("SIS", (s >= 0) ? 
resource.substring(s) : null);
+        try (ReadableByteChannel in = Channels.newChannel(data)) {
+            final Path file = Files.createTempFile("SIS", suffix);
             channel = Files.newByteChannel(file, 
StandardOpenOption.DELETE_ON_CLOSE,
                                 StandardOpenOption.READ, 
StandardOpenOption.WRITE);
             final ByteBuffer buffer = ByteBuffer.allocate(4000);
diff --git 
a/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
 
b/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
index 7d16db227c..b78da8cc42 100644
--- 
a/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
+++ 
b/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.profile.fra;
 
 import java.util.Set;
 import java.util.Collection;
+import java.io.InputStream;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.citation.Responsibility;
 import org.apache.sis.metadata.iso.DefaultMetadata;
@@ -43,9 +44,13 @@ import static org.junit.Assert.*;
  */
 public final class DirectReferenceSystemTest extends TestCase {
     /**
-     * An XML file in this package containing a reference system definition.
+     * Opens the stream to the XML file in this package containing a reference 
system definition.
+     *
+     * @return stream opened on the XML document to use for testing purpose.
      */
-    private static final String XML_FILE = "DirectReferenceSystem.xml";
+    private static InputStream openTestFile() {
+        return 
DirectReferenceSystemTest.class.getResourceAsStream("DirectReferenceSystem.xml");
+    }
 
     /**
      * Creates the metadata object to be tested.
@@ -75,7 +80,7 @@ public final class DirectReferenceSystemTest extends TestCase 
{
      */
     @Test
     public void marshallingTest() throws JAXBException {
-        assertMarshalEqualsFile(XML_FILE, createMetadata(false), VERSION_2007, 
"xmlns:*", "xsi:schemaLocation");
+        assertMarshalEqualsFile(openTestFile(), createMetadata(false), 
VERSION_2007, "xmlns:*", "xsi:schemaLocation");
     }
 
     /**
@@ -87,7 +92,7 @@ public final class DirectReferenceSystemTest extends TestCase 
{
     @Test
     public void unmarshallingTest() throws JAXBException {
         final DefaultMetadata expected = createMetadata(true);
-        final DefaultMetadata result = unmarshalFile(DefaultMetadata.class, 
XML_FILE);
+        final DefaultMetadata result = unmarshalFile(DefaultMetadata.class, 
openTestFile());
         assertTrue(expected.equals(result, ComparisonMode.DEBUG));
     }
 }
diff --git 
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
 
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
index b3c7bd127a..1f84e9782e 100644
--- 
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
+++ 
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
@@ -23,18 +23,18 @@ import java.io.StringReader;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.metadata.xml.TestUsingFile;
 import org.apache.sis.internal.xml.LegacyNamespaces;
+import org.apache.sis.metadata.iso.extent.DefaultExtentTest;
 import org.apache.sis.test.DependsOnMethod;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
-import static org.apache.sis.metadata.iso.extent.DefaultExtentTest.FILENAME;
 
 
 /**
  * Tests {@link MimeTypeDetector}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.4
  */
 public final class MimeTypeDetectorTest extends TestUsingFile {
@@ -96,7 +96,7 @@ public final class MimeTypeDetectorTest extends TestUsingFile 
{
     @DependsOnMethod("testGMDFromString")
     public void testGMDFromInputStream() throws IOException {
         final String type;
-        try (InputStream in = 
TestUsingFile.class.getResourceAsStream(XML2007+FILENAME)) {
+        try (InputStream in = DefaultExtentTest.openTestFile(Format.XML2007)) {
             assertEquals('<', in.read());
             assertEquals('?', in.read());
             final MimeTypeDetector detector = new MimeTypeDetector(
diff --git 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
index 98e12d56cf..b5a5663b63 100644
--- 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
+++ 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
@@ -81,10 +81,11 @@ public final class ReaderTest extends TestCase {
     /**
      * Creates a new GPX data store which will read the given test file.
      *
-     * @param  resource  name of the test file in a directory relative to 
{@code "org/apache/sis/internal/gpx"}.
+     * @param  version   identifies the version of the schema to test.
+     * @param  resource  name of the test file.
      */
-    private static Store create(final String resource) throws 
DataStoreException {
-        final StorageConnector connector = new 
StorageConnector(ReaderTest.class.getResourceAsStream(resource));
+    private static Store create(final TestData version, final String resource) 
throws DataStoreException {
+        final var connector = new 
StorageConnector(version.openStream(resource));
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
         return new Store(provider, connector);
     }
@@ -137,7 +138,7 @@ public final class ReaderTest extends TestCase {
      */
     @Test
     public void testMetadata100() throws DataStoreException {
-        try (Store reader = create("1.0/metadata.xml")) {
+        try (Store reader = create(TestData.V1_0, TestData.METADATA)) {
             final Metadata md = (Metadata) reader.getMetadata();
             verifyMetadata(md, 1);
             assertNull(md.author.link);
@@ -153,7 +154,7 @@ public final class ReaderTest extends TestCase {
      */
     @Test
     public void testMetadata110() throws DataStoreException {
-        try (Store reader = create("1.1/metadata.xml")) {
+        try (Store reader = create(TestData.V1_1, TestData.METADATA)) {
             final Metadata md = (Metadata) reader.getMetadata();
             verifyMetadata(md, 3);
             assertStringEquals("http://someone-site.org";, md.author.link);
@@ -223,7 +224,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testMetadata100")
     public void testWayPoint100() throws DataStoreException {
-        try (Store reader = create("1.0/waypoint.xml")) {
+        try (Store reader = create(TestData.V1_0, TestData.WAYPOINT)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_0, reader.getVersion());
             try (Stream<Feature> features = reader.features(false)) {
@@ -244,7 +245,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testMetadata110")
     public void testWayPoint110() throws DataStoreException {
-        try (Store reader = create("1.1/waypoint.xml")) {
+        try (Store reader = create(TestData.V1_1, TestData.WAYPOINT)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_1, reader.getVersion());
             try (Stream<Feature> features = reader.features(false)) {
@@ -265,7 +266,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testWayPoint100")
     public void testRoute100() throws DataStoreException {
-        try (Store reader = create("1.0/route.xml")) {
+        try (Store reader = create(TestData.V1_0, TestData.ROUTE)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_0, reader.getVersion());
             try (Stream<Feature> features = reader.features(false)) {
@@ -285,7 +286,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testWayPoint110")
     public void testRoute110() throws DataStoreException {
-        try (Store reader = create("1.1/route.xml")) {
+        try (Store reader = create(TestData.V1_1, TestData.ROUTE)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_1, reader.getVersion());
             verifyRoute110(reader);
@@ -372,7 +373,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testRoute100")
     public void testTrack100() throws DataStoreException {
-        try (Store reader = create("1.0/track.xml")) {
+        try (Store reader = create(TestData.V1_0, TestData.TRACK)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_0, reader.getVersion());
             try (Stream<Feature> features = reader.features(false)) {
@@ -392,7 +393,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testRoute110")
     public void testTrack110() throws DataStoreException {
-        try (Store reader = create("1.1/track.xml")) {
+        try (Store reader = create(TestData.V1_1, TestData.TRACK)) {
             verifyAlmostEmptyMetadata((Metadata) reader.getMetadata());
             assertEquals("version", StoreProvider.V1_1, reader.getVersion());
             try (Stream<Feature> features = reader.features(false)) {
@@ -558,7 +559,7 @@ public final class ReaderTest extends TestCase {
     @Test
     @DependsOnMethod("testRoute110")
     public void testRouteSkipMetadata() throws DataStoreException {
-        try (Store reader = create("1.1/route.xml")) {
+        try (Store reader = create(TestData.V1_1, TestData.ROUTE)) {
             verifyRoute110(reader);
         }
     }
@@ -568,7 +569,7 @@ public final class ReaderTest extends TestCase {
      * Using the URL makes easier for the data store to read the same data 
more than once.
      */
     private static Store createFromURL() throws DataStoreException {
-        final StorageConnector connector = new 
StorageConnector(ReaderTest.class.getResource("1.1/route.xml"));
+        final StorageConnector connector = new 
StorageConnector(TestData.V1_1.getURL(TestData.ROUTE));
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
         connector.setOption(OptionKey.URL_ENCODING, "UTF-8");
         return new Store(provider, connector);
diff --git 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TestData.java
 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TestData.java
new file mode 100644
index 0000000000..e6e50e1ce1
--- /dev/null
+++ 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/TestData.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.storage.gpx;
+
+import java.net.URL;
+import java.io.InputStream;
+import org.apache.sis.util.Version;
+
+
+/**
+ * Identification of the data to use for testing purpose.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.4
+ * @since   1.4
+ */
+public enum TestData {
+    /**
+     * Test for GPX 1.0.
+     */
+    V1_0(StoreProvider.V1_0, "1.0/"),
+
+    /**
+     * Test for GPX 1.1.
+     */
+    V1_1(StoreProvider.V1_1, "1.1/");
+
+    /**
+     * Version of the XML schema used by this format.
+     */
+    final Version schemaVersion;
+
+    /**
+     * The directory (relative to the {@code TestData.class} file) of the XML 
document.
+     */
+    private final String directory;
+
+    /**
+     * Filename of the metadata test file.
+     */
+    public static final String METADATA = "metadata.xml";
+
+    /**
+     * Filename of a test data file.
+     */
+    static final String WAYPOINT = "waypoint.xml", ROUTE = "route.xml", TRACK 
= "track.xml";
+
+    /**
+     * Creates a new enumeration for documents in the specified sub-directory.
+     */
+    private TestData(final Version schemaVersion, final String directory) {
+        this.schemaVersion = schemaVersion;
+        this.directory = directory;
+    }
+
+    /**
+     * Returns the URL to the specified XML file.
+     *
+     * @param  filename  name of the file to open.
+     * @return URL to the XML document to use for testing purpose.
+     */
+    public final URL getURL(final String filename) {
+        // Call to `getResource(…)` is caller sensitive: it must be in the 
same module.
+        return TestData.class.getResource(directory.concat(filename));
+    }
+
+    /**
+     * Opens the stream to the specified XML file.
+     *
+     * @param  filename  name of the file to open.
+     * @return stream opened on the XML document to use for testing purpose.
+     */
+    public final InputStream openStream(final String filename) {
+        // Call to `getResourceAsStream(…)` is caller sensitive: it must be in 
the same module.
+        return TestData.class.getResourceAsStream(directory.concat(filename));
+    }
+}
diff --git 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
index 454dfc236d..f906676612 100644
--- 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
+++ 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
@@ -28,7 +28,6 @@ import org.apache.sis.setup.OptionKey;
 import org.apache.sis.storage.gps.Fix;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
-import org.apache.sis.util.Version;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestUtilities;
@@ -51,7 +50,7 @@ import org.opengis.feature.Feature;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.8
  */
 @DependsOn({MetadataTest.class, ReaderTest.class})
@@ -114,7 +113,7 @@ public final class WriterTest extends TestCase {
      */
     @Test
     public void testMetadata100() throws Exception {
-        testMetadata(StoreProvider.V1_0, "1.0/metadata.xml");
+        testMetadata(TestData.V1_0);
     }
 
     /**
@@ -125,7 +124,7 @@ public final class WriterTest extends TestCase {
      */
     @Test
     public void testMetadata110() throws Exception {
-        testMetadata(StoreProvider.V1_1, "1.1/metadata.xml");
+        testMetadata(TestData.V1_1);
     }
 
     /**
@@ -134,13 +133,13 @@ public final class WriterTest extends TestCase {
      * @param version   either {@link StoreProvider#V1_0} or {@link 
StoreProvider#V1_1}.
      * @param expected  name of a test file containing the expected XML result.
      */
-    private void testMetadata(final Version version, final String expected) 
throws Exception {
+    private void testMetadata(final TestData data) throws Exception {
         final Metadata metadata = MetadataTest.create();
         try (WritableStore store = create()) {
-            store.setVersion(version);
+            store.setVersion(data.schemaVersion);
             store.write(metadata, null);
         }
-        assertXmlEquals(WriterTest.class.getResourceAsStream(expected), 
toString(), STRICT,
+        assertXmlEquals(data.openStream(TestData.METADATA), toString(), STRICT,
                         new String[] {Tags.NAMESPACE_V11 + ":extensions"},
                         new String[] {"xmlns:xsi", "xsi:schemaLocation", 
"xsi:type"});
     }
@@ -154,7 +153,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testMetadata100")
     public void testWayPoints100() throws Exception {
-        testFeatures(StoreProvider.V1_0, Type.WAY_POINT, "1.0/waypoint.xml");
+        testFeatures(TestData.V1_0, Type.WAY_POINT, TestData.WAYPOINT);
     }
 
     /**
@@ -166,7 +165,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testMetadata110")
     public void testWayPoints110() throws Exception {
-        testFeatures(StoreProvider.V1_1, Type.WAY_POINT, "1.1/waypoint.xml");
+        testFeatures(TestData.V1_1, Type.WAY_POINT, TestData.WAYPOINT);
     }
 
     /**
@@ -178,7 +177,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testWayPoints100")
     public void testRoutes100() throws Exception {
-        testFeatures(StoreProvider.V1_0, Type.ROUTE, "1.0/route.xml");
+        testFeatures(TestData.V1_0, Type.ROUTE, TestData.ROUTE);
     }
 
     /**
@@ -190,7 +189,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testWayPoints110")
     public void testRoutes110() throws Exception {
-        testFeatures(StoreProvider.V1_1, Type.ROUTE, "1.1/route.xml");
+        testFeatures(TestData.V1_1, Type.ROUTE, TestData.ROUTE);
     }
 
     /**
@@ -202,7 +201,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testRoutes100")
     public void testTracks100() throws Exception {
-        testFeatures(StoreProvider.V1_0, Type.TRACK, "1.0/track.xml");
+        testFeatures(TestData.V1_0, Type.TRACK, TestData.TRACK);
     }
 
     /**
@@ -214,7 +213,7 @@ public final class WriterTest extends TestCase {
     @Test
     @DependsOnMethod("testRoutes110")
     public void testTracks110() throws Exception {
-        testFeatures(StoreProvider.V1_1, Type.TRACK, "1.1/track.xml");
+        testFeatures(TestData.V1_1, Type.TRACK, TestData.TRACK);
     }
 
     /**
@@ -227,16 +226,16 @@ public final class WriterTest extends TestCase {
     /**
      * Implementation of way points, routes and tracks test methods.
      *
-     * @param version   either {@link StoreProvider#V1_0} or {@link 
StoreProvider#V1_1}.
+     * @param version   either {@link TestData#V1_0} or {@link TestData#V1_1}.
      * @param type      the kind of feature to test: way point, route or track.
      * @param expected  name of a test file containing the expected XML result.
      */
-    private void testFeatures(final Version version, final Type type, final 
String expected) throws Exception {
+    private void testFeatures(final TestData version, final Type type, final 
String expected) throws Exception {
         try (WritableStore store = create()) {
-            store.version = version;
+            store.version = version.schemaVersion;
             testFeatures(store, type);
         }
-        assertXmlEquals(WriterTest.class.getResourceAsStream(expected), 
toString(),
+        assertXmlEquals(version.openStream(expected), toString(),
                         "xmlns:xsi", "xsi:schemaLocation", "xsi:type");
     }
 
@@ -367,7 +366,7 @@ public final class WriterTest extends TestCase {
     @DependsOnMethod("testRoutes110")
     public void testInputReplacement() throws Exception {
         final StorageConnector connector = new StorageConnector(
-                TestUtilities.createTemporaryFile(ReaderTest.class, 
"1.1/metadata.xml"));
+                
TestUtilities.createTemporaryFile(TestData.V1_1.openStream(TestData.METADATA), 
".xml"));
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
         try (WritableStore store = new WritableStore(provider, connector)) {
             /*

Reply via email to