diff --git a/.travis.yml b/.travis.yml
index 7ab09832..a0b2ebdb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,6 +24,9 @@ install: true
 script:
   - mvn install -B
   - cd compat-tests && ./hamcrest-test.sh 2.6.5-SNAPSHOT 2.2
+  - cd compat-tests && ./assertj-test.sh 2.6.5-SNAPSHOT 3.9.1
+#  - cd compat-tests && ./assertj-test.sh 2.6.5-SNAPSHOT 3.13.0
+#  - cd compat-tests && ./assertj-test.sh 2.6.5-SNAPSHOT 3.15.0
 notifications:
   email:
     - xmlunit-commits@lists.sourceforge.net
diff --git a/compat-tests/TestResources.java b/compat-tests/TestResources.java
new file mode 100644
index 00000000..8ccdcb6b
--- /dev/null
+++ b/compat-tests/TestResources.java
@@ -0,0 +1,28 @@
+/*
+  This file is licensed 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.xmlunit;
+
+public final class TestResources {
+    public static final String TEST_RESOURCE_DIR = "../../../test-resources/";
+
+    public static final String ANIMAL_FILE = TEST_RESOURCE_DIR + "test1.xml";
+    public static final String BLAME_FILE = TEST_RESOURCE_DIR + "test.blame.html";
+    public static final String ANIMAL_XSL = TEST_RESOURCE_DIR + "animal.xsl";
+    public static final String DOG_FILE = TEST_RESOURCE_DIR + "testAnimal.xml";
+
+    public static final String BOOK_DTD = TEST_RESOURCE_DIR + "Book.dtd";
+    public static final String BOOK_XSD = TEST_RESOURCE_DIR + "Book.xsd";
+
+    private TestResources() { }
+}
diff --git a/compat-tests/assertj-test.sh b/compat-tests/assertj-test.sh
new file mode 100755
index 00000000..58be09a9
--- /dev/null
+++ b/compat-tests/assertj-test.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+set -e
+
+if [ "$#" -ne 2 ]; then
+    echo "Usage: assertj-test.sh XMLUNIT_VERSION ASSERTJ_VERSION"
+    exit 1
+fi
+
+XMLUNIT_VERSION=$1
+ASSERTJ_VERSION=$2
+
+SCRATCH_DIR=scratch/assertj-${ASSERTJ_VERSION}
+
+rm -rf scratch && mkdir -p ${SCRATCH_DIR}/src/test/java/org/xmlunit/
+
+cat > ${SCRATCH_DIR}/pom.xml <<EOF
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.xmlunit</groupId>
+    <artifactId>xmlunit-parent</artifactId>
+    <version>${XMLUNIT_VERSION}</version>
+    <relativePath>../../..</relativePath>
+  </parent>
+
+  <groupId>org.xmlunit</groupId>
+  <artifactId>xmlunit-compat-tests-assertj-${ASSERTJ_VERSION}</artifactId>
+  <packaging>jar</packaging>
+  <name>org.xmlunit:xmlunit-compat-tests-assertj-${ASSERTJ_VERSION}</name>
+  <description>Verifies the AssertJ assertions are compatible with AssertJ ${ASSERTJ_VERSION}</description>
+  <url>https://www.xmlunit.org/</url>
+
+  <properties>
+    <automatic.module.name>\${project.groupId}.compat-tests-assertj-${ASSERTJ_VERSION}</automatic.module.name>
+    <assertj.version>${ASSERTJ_VERSION}</assertj.version>
+    <maven.compile.source>1.7</maven.compile.source>
+    <maven.compile.target>1.7</maven.compile.target>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.xmlunit</groupId>
+      <artifactId>xmlunit-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.xmlunit</groupId>
+      <artifactId>xmlunit-assertj</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>\${assertj.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.bytebuddy</groupId>
+      <artifactId>byte-buddy</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
+EOF
+
+cp TestResources.java ${SCRATCH_DIR}/src/test/java/org/xmlunit/
+
+cp -r ../xmlunit-assertj/src/test/java/org/xmlunit/assertj ${SCRATCH_DIR}/src/test/java/org/xmlunit
+
+mvn -f ${SCRATCH_DIR}/pom.xml test
diff --git a/compat-tests/hamcrest-test.sh b/compat-tests/hamcrest-test.sh
index ce707f19..4e00feea 100755
--- a/compat-tests/hamcrest-test.sh
+++ b/compat-tests/hamcrest-test.sh
@@ -74,36 +74,7 @@ cat > ${SCRATCH_DIR}/pom.xml <<EOF
 </project>
 EOF
 
-cat > ${SCRATCH_DIR}/src/test/java/org/xmlunit/TestResources.java <<'EOF'
-/*
-  This file is licensed 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.xmlunit;
-
-public final class TestResources {
-    public static final String TEST_RESOURCE_DIR = "../../../test-resources/";
-
-    public static final String ANIMAL_FILE = TEST_RESOURCE_DIR + "test1.xml";
-    public static final String BLAME_FILE = TEST_RESOURCE_DIR + "test.blame.html";
-    public static final String ANIMAL_XSL = TEST_RESOURCE_DIR + "animal.xsl";
-    public static final String DOG_FILE = TEST_RESOURCE_DIR + "testAnimal.xml";
-
-    public static final String BOOK_DTD = TEST_RESOURCE_DIR + "Book.dtd";
-    public static final String BOOK_XSD = TEST_RESOURCE_DIR + "Book.xsd";
-
-    private TestResources() { }
-}
-EOF
+cp TestResources.java ${SCRATCH_DIR}/src/test/java/org/xmlunit/
 
 cp -r ../xmlunit-matchers/src/test/java/org/xmlunit/bugreports ${SCRATCH_DIR}/src/test/java/org/xmlunit
 cp -r ../xmlunit-matchers/src/test/java/org/xmlunit/matchers ${SCRATCH_DIR}/src/test/java/org/xmlunit
diff --git a/pom.xml b/pom.xml
index 86c2ea25..a06cb7be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -135,6 +135,11 @@
         <artifactId>xmlunit-matchers</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-assertj</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-core</artifactId>
diff --git a/xmlunit-assertj/pom.xml b/xmlunit-assertj/pom.xml
index 20df78f6..f61f1879 100644
--- a/xmlunit-assertj/pom.xml
+++ b/xmlunit-assertj/pom.xml
@@ -38,6 +38,12 @@
       <groupId>org.xmlunit</groupId>
       <artifactId>xmlunit-core</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.xmlunit</groupId>
+      <artifactId>xmlunit-core</artifactId>
+      <classifier>tests</classifier>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
diff --git a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreNotSimilarTest.java b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreNotSimilarTest.java
index 1aae529c..0ca25f3e 100644
--- a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreNotSimilarTest.java
+++ b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreNotSimilarTest.java
@@ -15,6 +15,7 @@
 
 import org.junit.Rule;
 import org.junit.Test;
+import org.xmlunit.TestResources;
 
 import java.io.File;
 
@@ -38,8 +39,8 @@ public void testAreNotSimilar_shouldPass() {
     @Test
     public void testAreNotSimilar_fromFiles_shouldPass() {
 
-        File testXml = new File("../test-resources/test1.xml");
-        File controlXml = new File("../test-resources/test2.xml");
+        File testXml = new File(TestResources.ANIMAL_FILE);
+        File controlXml = new File(TestResources.TEST_RESOURCE_DIR + "test2.xml");
 
         assertThat(testXml).and(controlXml).areNotSimilar();
     }
diff --git a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreSimilarTest.java b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreSimilarTest.java
index 55960f86..e424ca64 100644
--- a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreSimilarTest.java
+++ b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/CompareAssertAreSimilarTest.java
@@ -18,6 +18,7 @@
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
+import org.xmlunit.TestResources;
 import org.xmlunit.diff.Comparison;
 import org.xmlunit.diff.ComparisonController;
 import org.xmlunit.diff.ComparisonListener;
@@ -90,8 +91,8 @@ public void testAreSimilar_fromFiles_shouldFailed() {
         thrown.expectAssertionErrorPattern(".*Expecting:.*<(?:.*test2\\.xml)> and <(?:.*test1\\.xml)> to be similar.*");
         thrown.expectAssertionError("Expected processing instruction data 'href=\"animal.xsl\" type=\"text/xsl\"' but was 'type=\"text/xsl\" href=\"animal.xsl\"");
 
-        File testXml = new File("../test-resources/test1.xml");
-        File controlXml = new File("../test-resources/test2.xml");
+        File testXml = new File(TestResources.ANIMAL_FILE);
+        File controlXml = new File(TestResources.TEST_RESOURCE_DIR + "test2.xml");
 
         assertThat(testXml).and(controlXml).areSimilar();
     }
diff --git a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/XmlAssertValidationTest.java b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/XmlAssertValidationTest.java
index 8518b6fd..7e2dc0eb 100644
--- a/xmlunit-assertj/src/test/java/org/xmlunit/assertj/XmlAssertValidationTest.java
+++ b/xmlunit-assertj/src/test/java/org/xmlunit/assertj/XmlAssertValidationTest.java
@@ -16,10 +16,12 @@
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.xmlunit.TestResources;
 import org.xmlunit.validation.Languages;
 import org.xmlunit.assertj.util.SetEnglishLocaleRule;
 
 import java.io.File;
+import java.util.regex.Pattern;
 
 import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
@@ -38,16 +40,16 @@ public class XmlAssertValidationTest {
 
     @Test
     public void testIsValidAgainst_shouldPass() {
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
-        StreamSource xsd = new StreamSource(new File("../test-resources/Book.xsd"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
+        StreamSource xsd = new StreamSource(new File(TestResources.BOOK_XSD));
 
         assertThat(xml).isValidAgainst(xsd);
     }
 
     @Test
     public void testIsValidAgainst_withExternallyCreatedSchemaInstance_shouldPass() throws Exception {
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
-        StreamSource xsd = new StreamSource(new File("../test-resources/Book.xsd"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
+        StreamSource xsd = new StreamSource(new File(TestResources.BOOK_XSD));
 
         SchemaFactory factory = SchemaFactory.newInstance(Languages.W3C_XML_SCHEMA_NS_URI);
         Schema schema = factory.newSchema(xsd);
@@ -57,16 +59,16 @@ public void testIsValidAgainst_withExternallyCreatedSchemaInstance_shouldPass()
 
     @Test
     public void testIsNotValidAgainst_withBrokenXml_shouldPass() {
-        final StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
-        final StreamSource xsd = new StreamSource(new File("../test-resources/Book.xsd"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
+        StreamSource xsd = new StreamSource(new File(TestResources.BOOK_XSD));
 
         assertThat(xml).isNotValidAgainst(xsd);
     }
 
     @Test
     public void testIsNotValidAgainst_withBrokenXml_andExternallyCreatedSchemaInstance_shouldPass() throws Exception {
-        StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
-        StreamSource xsd = new StreamSource(new File("../test-resources/Book.xsd"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
+        StreamSource xsd = new StreamSource(new File(TestResources.BOOK_XSD));
 
         SchemaFactory factory = SchemaFactory.newInstance(Languages.W3C_XML_SCHEMA_NS_URI);
         Schema schema = factory.newSchema(xsd);
@@ -77,13 +79,13 @@ public void testIsNotValidAgainst_withBrokenXml_andExternallyCreatedSchemaInstan
     @Test
     public void testIsValidAgainst_withBrokenXml_shouldFailed() {
 
-        thrown.expectAssertionErrorPattern("^\\nExpecting:\\n <.*\\.\\.\\/test-resources\\/invalidBook.xml>\\nto be valid but found following problems:\\n.*");
+        thrown.expectAssertionErrorPattern("^\\nExpecting:\\n <.*" + Pattern.quote(TestResources.TEST_RESOURCE_DIR) + "invalidBook.xml>\\nto be valid but found following problems:\\n.*");
         thrown.expectAssertionError("1. line=9; column=8; type=ERROR;" +
                 " message=cvc-complex-type.2.4.b: The content of element 'Book' is not complete." +
                 " One of '{\"https://www.xmlunit.org/publishing\":Publisher}' is expected.");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
-        StreamSource xsd = new StreamSource(new File("../test-resources/Book.xsd"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
+        StreamSource xsd = new StreamSource(new File(TestResources.BOOK_XSD));
 
         assertThat(xml).isValidAgainst(xsd);
     }
@@ -91,7 +93,7 @@ public void testIsValidAgainst_withBrokenXml_shouldFailed() {
     @Test
     public void testIsValidAgainst_withEmptySourcesArray_shouldPass() {
 
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
 
         assertThat(xml).isValidAgainst();
         assertThat(xml).isValidAgainst(new Object[0]);
@@ -104,7 +106,7 @@ public void testIsValidAgainst_withBrokenXmlAndEmptySourcesArray_shouldFailed()
                 " message=cvc-complex-type.2.4.b: The content of element 'Book' is not complete." +
                 " One of '{\"https://www.xmlunit.org/publishing\":Publisher}' is expected.");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
 
         assertThat(xml).isValidAgainst();
     }
@@ -112,7 +114,7 @@ public void testIsValidAgainst_withBrokenXmlAndEmptySourcesArray_shouldFailed()
     @Test
     public void testIsValid_shouldPass() {
 
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
 
         assertThat(xml).isValid();
     }
@@ -124,7 +126,7 @@ public void testIsValid_withBrokenXml_shouldPass() {
                 " message=cvc-complex-type.2.4.b: The content of element 'Book' is not complete." +
                 " One of '{\"https://www.xmlunit.org/publishing\":Publisher}' is expected.");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
 
         assertThat(xml).isValid();
     }
@@ -132,7 +134,7 @@ public void testIsValid_withBrokenXml_shouldPass() {
     @Test
     public void testIsInvalid_withBrokenXml_shouldPass() {
 
-        StreamSource xml = new StreamSource(new File("../test-resources/invalidBook.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "invalidBook.xml"));
 
         assertThat(xml).isInvalid();
     }
@@ -140,9 +142,10 @@ public void testIsInvalid_withBrokenXml_shouldPass() {
     @Test
     public void testIsInvalid_shouldField() {
 
-        thrown.expectAssertionErrorPattern("^\\nExpecting:\\n <.*\\.\\.\\/test-resources\\/BookXsdGenerated.xml>\\nto be invalid");
+        thrown.expectAssertionErrorPattern("^\\nExpecting:\\n <.*"
+            + Pattern.quote(TestResources.TEST_RESOURCE_DIR) + "BookXsdGenerated.xml>\\nto be invalid");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
 
         assertThat(xml).isInvalid();
     }
@@ -152,7 +155,7 @@ public void testIsValidAgainst_withNullSchemaSources_shouldFailed() {
 
         thrown.expectAssertionError("actual not to be null");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
 
         assertThat(xml).isValidAgainst((Object[]) null);
     }
@@ -162,7 +165,7 @@ public void testIsValidAgainst_withNullSchema_shouldFailed() {
 
         thrown.expectAssertionError("actual not to be null");
 
-        StreamSource xml = new StreamSource(new File("../test-resources/BookXsdGenerated.xml"));
+        StreamSource xml = new StreamSource(new File(TestResources.TEST_RESOURCE_DIR + "BookXsdGenerated.xml"));
 
         assertThat(xml).isValidAgainst((Schema) null);
     }