diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 73962f4baec4374f2e9cf3278f8068b621879463..89455251463e2204b1824cb7162d2799643480ef 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,7 +4,8 @@ stages:
   - package
 
 variables:
-  CONTAINER_GCC_IMAGE: $CI_REGISTRY_IMAGE:gcc-$CI_COMMIT_REF_SLUG
+  CONTAINER_GCC_IMAGE: $CI_REGISTRY_IMAGE/gcc:$CI_COMMIT_REF_SLUG
+  XUNIT_TO_JUNIT_IMAGE: $CI_REGISTRY_IMAGE/xunit-to-junit
 
 include:
   - local: '/scripts/ci/extends/container-maker-setup.yml'
diff --git a/scripts/ci/jobs/build.yml b/scripts/ci/jobs/build.yml
index 4a39289e101eeb3c084af0a355ef311ed3f77c12..6d925198b108207e67bd4616ed56d7ba4bfe89db 100644
--- a/scripts/ci/jobs/build.yml
+++ b/scripts/ci/jobs/build.yml
@@ -19,15 +19,15 @@ build:
     - cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DOGS_USE_CONAN=OFF -DOGS_BUILD_PROCESSES=GroundwaterFlow
     - cmake --build . > >(tee make.output)
     - cmake --build . --target tests
-    - cmake --build . --target ctest -j 8
+    - cmake --build . --target ctest
+    - cp Testing/**/Test.xml Tests/ctest.xml
 
   artifacts:
     paths:
-      - build/Testing/**/*.xml
+      - build/Tests/ctest.xml
       - build/Tests/testrunner.xml
       - build/make.output
     expire_in: 1 week
     reports:
       junit:
         - build/Tests/testrunner.xml
-        - build/Testing/**/*.xml
diff --git a/scripts/ci/jobs/build_image.yml b/scripts/ci/jobs/build_image.yml
index 3f63ea0212a76bc1b75591209bdba4d34d56f128..faa39250c5a0f6be34d15b5b7db39b7109510cfa 100644
--- a/scripts/ci/jobs/build_image.yml
+++ b/scripts/ci/jobs/build_image.yml
@@ -1,8 +1,8 @@
-build_image:
+build gcc image:
   stage: .pre
-  # only:
-    # changes:
-      # - ThirdParty/container-maker
+  only:
+    changes:
+      - ThirdParty/container-maker
   tags:
     - docker-shell
   extends: .container-maker-setup
@@ -12,3 +12,16 @@ build_image:
     - python ThirdParty/container-maker/ogscm/cli.py --build --gitlab
       --ogs off --pm system --cvode --cppcheck --docs --gcovr
       --tag $CONTAINER_GCC_IMAGE --upload
+
+build xunit-to-junit image:
+  stage: .pre
+  only:
+    changes:
+      - scripts/docker/saxon/**/*
+  tags:
+    - docker-shell
+  script:
+    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+    - docker pull $XUNIT_TO_JUNIT_IMAGE:latest || true
+    - docker build --cache-from $XUNIT_TO_JUNIT_IMAGE:latest -t $XUNIT_TO_JUNIT_IMAGE:latest -f scripts/docker/saxon/Dockerfile scripts/docker/saxon
+    - docker push $XUNIT_TO_JUNIT_IMAGE:latest
diff --git a/scripts/ci/jobs/checks.yml b/scripts/ci/jobs/checks.yml
index a33771b344cc5725887d397165a72701c2673b6a..85fe1c517da6cf22e7dbf1dc852f510075965b21 100644
--- a/scripts/ci/jobs/checks.yml
+++ b/scripts/ci/jobs/checks.yml
@@ -2,9 +2,28 @@ compiler warnings:
   stage: checks
   variables:
     GIT_STRATEGY: none
-  script:
-    - cd build
-    - "if [[ $(cat make.output | grep warning -i) ]]; then echo 'There were compiler warnings:'; cat make.output | grep warning -i; exit 1; fi"
   allow_failure: true
   dependencies:
     - build
+  script:
+  - cd build
+  - "if [[ $(cat make.output | grep warning -i) ]]; then echo 'There were compiler warnings:'; cat make.output | grep warning -i; exit 1; fi"
+
+
+ctest results:
+  stage: checks
+  variables:
+    GIT_STRATEGY: none
+  tags:
+    - singularity
+  dependencies:
+    - build
+  script:
+    - singularity run docker://$XUNIT_TO_JUNIT_IMAGE -s:./build/Tests/ctest.xml > build/ctest-junit.xml
+  artifacts:
+    paths:
+      - build/ctest-junit.xml
+    expire_in: 1 week
+    reports:
+      junit:
+        - build/ctest-junit.xml
diff --git a/scripts/docker/saxon/Dockerfile b/scripts/docker/saxon/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..b2604370a1511ff146dda05f518d8d7bcdaafa9a
--- /dev/null
+++ b/scripts/docker/saxon/Dockerfile
@@ -0,0 +1,8 @@
+FROM openjdk:8-jre
+
+WORKDIR /usr/src/saxon
+RUN curl -L -O https://repo1.maven.org/maven2/net/sf/saxon/Saxon-HE/9.9.1-5/Saxon-HE-9.9.1-5.jar
+COPY entrypoint.sh entrypoint.sh
+ENTRYPOINT ["/bin/sh", "/usr/src/saxon/entrypoint.sh"]
+
+RUN curl -L -O https://raw.githubusercontent.com/rpavlik/jenkins-ctest-plugin/master/ctest-to-junit.xsl
diff --git a/scripts/docker/saxon/README.md b/scripts/docker/saxon/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..09d61126efaaf3db77c5a2956499096953d31fa8
--- /dev/null
+++ b/scripts/docker/saxon/README.md
@@ -0,0 +1 @@
+Modified from https://github.com/AtomGraph/saxon-docker
diff --git a/scripts/docker/saxon/entrypoint.sh b/scripts/docker/saxon/entrypoint.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5a9c239720a278f49b2ca2c1686ce6c42d354418
--- /dev/null
+++ b/scripts/docker/saxon/entrypoint.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+java $JAVA_OPTS -jar /usr/src/saxon/Saxon-HE-9.9.1-5.jar -xsl:/usr/src/saxon/ctest-to-junit.xsl "$@"