diff --git a/corsika/modules/writers/TrackWriterParquet.hpp b/corsika/modules/writers/TrackWriterParquet.hpp
index dad76c074a6c7dc171b59cf4bb285e906fb7a9b4..7caf90558b2ae0fc5c1cc13ca38b7d009e70b335 100644
--- a/corsika/modules/writers/TrackWriterParquet.hpp
+++ b/corsika/modules/writers/TrackWriterParquet.hpp
@@ -12,13 +12,12 @@
 #include <corsika/output/ParquetStreamer.hpp>
 #include <corsika/framework/core/ParticleProperties.hpp>
 #include <corsika/framework/core/PhysicalUnits.hpp>
+#include <corsika/framework/geometry/QuantityVector.hpp>
 
 namespace corsika {
 
   class TrackWriterParquet : public BaseOutput {
 
-    ParquetStreamer output_; ///< The primary output file.
-
   public:
     /**
      * Construct a new writer.
@@ -53,6 +52,9 @@ namespace corsika {
                QuantityVector<length_d> const& start,
                QuantityVector<length_d> const& end);
 
+  private:
+    ParquetStreamer output_; ///< The primary output file.
+
   }; // class TrackWriterParquet
 
 } // namespace corsika
diff --git a/corsika/output/NoOutput.hpp b/corsika/output/NoOutput.hpp
index 67710e2d09e25040c25ec7b7a4a89ea26726a8b9..289c19ad720f9f03d621d3b50ac031c40cc794cf 100644
--- a/corsika/output/NoOutput.hpp
+++ b/corsika/output/NoOutput.hpp
@@ -7,6 +7,9 @@
  */
 #pragma once
 
+#include <corsika/framework/core/ParticleProperties.hpp>
+#include <corsika/framework/core/PhysicalUnits.hpp>
+
 namespace corsika {
 
   /**
diff --git a/tests/output/CMakeLists.txt b/tests/output/CMakeLists.txt
index 98ca8008ed84200c25458402dfd724aa8cf54a3a..98a43b4c218bf8d9e21bb7b9e56ac1275cbc9b0e 100644
--- a/tests/output/CMakeLists.txt
+++ b/tests/output/CMakeLists.txt
@@ -3,8 +3,8 @@ set (test_output_sources
   testOutputManager.cpp
   testDummyOutputManager.cpp
   testParquetStreamer.cpp
-  #testWriterObservationPlane.cpp
-  #testWriterTrack.cpp
+  testWriterObservationPlane.cpp
+  testWriterTracks.cpp
   )
 
 CORSIKA_ADD_TEST (testOutput SOURCES ${test_output_sources})
diff --git a/tests/output/testOutputManager.cpp b/tests/output/testOutputManager.cpp
index 84fdcdc41f0b92d92285121c02cc79231468294f..58f90589c2206ed1e01607cd216a6b76c53a20c9 100644
--- a/tests/output/testOutputManager.cpp
+++ b/tests/output/testOutputManager.cpp
@@ -10,11 +10,25 @@
 
 #include <boost/filesystem.hpp>
 
-#include <corsika/output/OutputManager.hpp>
 #include <corsika/framework/core/Logging.hpp>
 
+#include <corsika/output/OutputManager.hpp>
+#include <corsika/output/NoOutput.hpp>
+
 using namespace corsika;
 
+struct DummyNoOutput : public NoOutput {
+  void check() {
+    NoOutput::startOfLibrary("./");
+    NoOutput::startOfShower();
+    NoOutput::endOfShower();
+    NoOutput::endOfLibrary();
+    NoOutput::getConfig();
+    NoOutput::getSummary();
+  }
+  void checkWrite() { NoOutput::write(Code::Unknown, 1_eV, 1_m, 1_m); }
+};
+
 struct DummyOutput : public BaseOutput {
 
   mutable bool isConfig_ = false;
@@ -26,7 +40,10 @@ struct DummyOutput : public BaseOutput {
 
   void startOfLibrary(boost::filesystem::path const&) { startLibrary_ = true; }
 
-  void startOfShower() { startShower_ = true; }
+  void startOfShower() {
+    BaseOutput::startOfShower();
+    startShower_ = true;
+  }
 
   void endOfShower() { endShower_ = true; }
 
@@ -39,7 +56,7 @@ struct DummyOutput : public BaseOutput {
 
   YAML::Node getSummary() {
     isSummary_ = true;
-    return YAML::Node();
+    return BaseOutput::getSummary();
   }
 };
 
@@ -86,6 +103,32 @@ TEST_CASE("OutputManager") {
     CHECK(test.isSummary_);
     test.isSummary_ = false;
     test.endLibrary_ = false;
+
+    CHECK(boost::filesystem::exists("./out_test/check/test/summary.yaml"));
+  }
+
+  SECTION("auto-write") {
+
+    // preparation
+    if (boost::filesystem::exists("./out_test")) {
+      boost::filesystem::remove_all("./out_test");
+    }
+
+    // output manager performs nothing, no action, just interface
+    OutputManager* output = new OutputManager("check", "./out_test");
+
+    CHECK(boost::filesystem::is_directory("./out_test/check"));
+
+    DummyOutput test;
+    output->add("test", test);
+    output->startOfLibrary();
+    output->startOfShower();
+
+    // check support for closing automatically
+    delete output;
+    output = 0;
+
+    CHECK(boost::filesystem::exists("./out_test/check/test/summary.yaml"));
   }
 
   SECTION("failures") {
@@ -129,4 +172,13 @@ TEST_CASE("OutputManager") {
     // CHECK_THROWS(output.startOfShower());
     // CHECK_THROWS(output.endOfLibrary());
   }
+
+  SECTION("NoOutput") {
+    // this is one of the classes where testing is a bit useless, but we can at least make
+    // sure the interface exists.
+    DummyNoOutput nothing;
+
+    nothing.check();
+    nothing.checkWrite();
+  }
 }
\ No newline at end of file
diff --git a/tests/output/testParquetStreamercpp b/tests/output/testParquetStreamercpp
deleted file mode 100644
index fd141051ef7845e1309af0c841218bf2f2b02caf..0000000000000000000000000000000000000000
--- a/tests/output/testParquetStreamercpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#include <catch2/catch.hpp>
-
-#include <boost/filesystem.hpp>
-
-#include <corsika/output/ParquetStreamer.hpp>
-#include <corsika/framework/core/Logging.hpp>
-
-using namespace corsika;
-
-TEST_CASE("ParquetStreamer") {
-
-  logging::set_level(logging::level::info);
-
-  SECTION("standard") {
-
-    // preparation
-    if (boost::filesystem::exists("./parquet_test.parquet")) {
-      boost::filesystem::remove_all("./parquet_test.parquet");
-    }
-
-    ParquetStreamer test;
-    test.initStreamer("./parquet_test.parquet");
-
-    test.addField();
-
-    test.enableCompression(5);
-
-    test.buildStreamer();
-    test.closeStreamer();
-
-    std::shared_ptr<parquet::StreamWriter> writer = test.getWriter();
-  }
-}
\ No newline at end of file
diff --git a/tests/output/testWriterObservationPlane.cpp b/tests/output/testWriterObservationPlane.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b780a2b4bbcde53d531f4a6a113d4b2a7087f3a
--- /dev/null
+++ b/tests/output/testWriterObservationPlane.cpp
@@ -0,0 +1,50 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#include <catch2/catch.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include <corsika/modules/writers/ObservationPlaneWriterParquet.hpp>
+
+#include <corsika/framework/core/Logging.hpp>
+#include <corsika/framework/geometry/QuantityVector.hpp>
+
+using namespace corsika;
+
+struct TestWriterPlane : public ObservationPlaneWriterParquet {
+
+  YAML::Node getConfig() const { return YAML::Node(); }
+
+  void checkWrite() {
+    ObservationPlaneWriterParquet::write(Code::Unknown, 1_eV, 2_m, 3_m);
+  }
+};
+
+TEST_CASE("ObservationPlaneWriterParquet") {
+
+  logging::set_level(logging::level::info);
+
+  SECTION("standard") {
+
+    // preparation
+    if (boost::filesystem::exists("./output_dir")) {
+      boost::filesystem::remove_all("./output_dir");
+    }
+    boost::filesystem::create_directory("./output_dir");
+
+    TestWriterPlane test;
+    test.startOfLibrary("./output_dir");
+    test.startOfShower();
+    test.checkWrite();
+    test.endOfShower();
+    test.endOfLibrary();
+
+    CHECK(boost::filesystem::exists("./output_dir/particles.parquet"));
+  }
+}
diff --git a/tests/output/testWriterTracks.cpp b/tests/output/testWriterTracks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38cf0cf5985a956aaef03b589b93a1b6b9f9b260
--- /dev/null
+++ b/tests/output/testWriterTracks.cpp
@@ -0,0 +1,49 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#include <catch2/catch.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include <corsika/modules/writers/TrackWriterParquet.hpp>
+
+#include <corsika/framework/core/Logging.hpp>
+
+using namespace corsika;
+
+struct TestWriterTrack : public TrackWriterParquet {
+
+  YAML::Node getConfig() const { return YAML::Node(); }
+
+  void checkWrite() {
+    TrackWriterParquet::write(Code::Unknown, 1_eV, {2_m, 3_m, 4_m}, {5_m, 6_m, 7_m});
+  }
+};
+
+TEST_CASE("TrackWriterParquet") {
+
+  logging::set_level(logging::level::info);
+
+  SECTION("standard") {
+
+    // preparation
+    if (boost::filesystem::exists("./output_dir_tracks")) {
+      boost::filesystem::remove_all("./output_dir_tracks");
+    }
+    boost::filesystem::create_directory("./output_dir_tracks");
+
+    TestWriterTrack test;
+    test.startOfLibrary("./output_dir_tracks");
+    test.startOfShower();
+    test.checkWrite();
+    test.endOfShower();
+    test.endOfLibrary();
+
+    CHECK(boost::filesystem::exists("./output_dir_tracks/tracks.parquet"));
+  }
+}