Index: code/branches/testing/src/libraries/util/output/OutputManager.cc
===================================================================
--- code/branches/testing/src/libraries/util/output/OutputManager.cc	(revision 9538)
+++ code/branches/testing/src/libraries/util/output/OutputManager.cc	(revision 9539)
@@ -307,5 +307,5 @@
     {
         // "undefined" context is ignored because it's used implicitly if no explicit context is defined
-        static OutputContextMask undefined_mask = context::undefined().mask;
+        OutputContextMask undefined_mask = context::undefined().mask;
 
         std::string prefix = this->getLevelName(level) + ": ";
Index: code/branches/testing/src/libraries/util/output/SubcontextOutputListener.h
===================================================================
--- code/branches/testing/src/libraries/util/output/SubcontextOutputListener.h	(revision 9538)
+++ code/branches/testing/src/libraries/util/output/SubcontextOutputListener.h	(revision 9539)
@@ -78,4 +78,7 @@
             virtual bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const;
 
+            inline const std::set<OutputContextSubID>& getSubcontexts() const
+                { return this->subcontexts_; }
+
         private:
             OutputContextMask subcontextsCheckMask_;    ///< All contexts defined by this mask need to be checked whether they are accepted by the set of sub-contexts
Index: code/branches/testing/test/util/output/BaseWriterTest.cc
===================================================================
--- code/branches/testing/test/util/output/BaseWriterTest.cc	(revision 9538)
+++ code/branches/testing/test/util/output/BaseWriterTest.cc	(revision 9539)
@@ -1,6 +1,176 @@
 #include <gtest/gtest.h>
+#include <gmock/gmock.h>
 #include "util/Output.h"
+#include "util/output/BaseWriter.h"
+#include "util/output/OutputManager.h"
 
 namespace orxonox
 {
+    namespace context
+    {
+        namespace
+        {
+            REGISTER_OUTPUT_CONTEXT(unittest1);
+            REGISTER_OUTPUT_CONTEXT(unittest2);
+            REGISTER_OUTPUT_CONTEXT(unittest3);
+
+            REGISTER_OUTPUT_SUBCONTEXT(unittest3, sub1);
+            REGISTER_OUTPUT_SUBCONTEXT(unittest3, sub2);
+            REGISTER_OUTPUT_SUBCONTEXT(unittest3, sub3);
+        }
+    }
+
+    namespace
+    {
+        class MockBaseWriter : public BaseWriter
+        {
+            public:
+                MockBaseWriter(const std::string& name, bool bRegister = true) : BaseWriter(name, bRegister) {}
+
+                MOCK_METHOD2(printLine, void(const std::string&, OutputLevel));
+
+                virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+                    { this->BaseWriter::output(level, context, lines); }
+        };
+    }
+
+    // test getName
+    TEST(BaseWriterTest, GetName)
+    {
+        MockBaseWriter writer("mytestname");
+        EXPECT_EQ("mytestname", writer.getName());
+    }
+
+    // test configurable names contain name
+    TEST(BaseWriterTest, ConfigurableNamesContainName)
+    {
+        MockBaseWriter writer("mytestname");
+        EXPECT_NE(writer.getConfigurableMaxLevelName().find(writer.getName()), std::string::npos);
+        EXPECT_NE(writer.getConfigurableAdditionalContextsMaxLevelName().find(writer.getName()), std::string::npos);
+        EXPECT_NE(writer.getConfigurableAdditionalContextsName().find(writer.getName()), std::string::npos);
+
+        // but the section name is 'static' (does not contain the name)
+        EXPECT_EQ(writer.getConfigurableSectionName().find(writer.getName()), std::string::npos);
+    }
+
+    // output calls printLine for each line
+    TEST(BaseWriterTest, OutputCallsPrintLine)
+    {
+        MockBaseWriter writer("mytestname");
+
+        std::vector<std::string> lines;
+        lines.push_back("line1");
+        lines.push_back("line2");
+
+        EXPECT_CALL(writer, printLine(::testing::_, level::debug_output)).Times(2);
+
+        writer.output(level::debug_output, context::undefined(), lines);
+    }
+
+    // output adds prefix to first line
+    TEST(BaseWriterTest, OutputAddsPrefixToFirstLine)
+    {
+        MockBaseWriter writer("mytestname");
+
+        std::vector<std::string> lines;
+        lines.push_back("line1");
+
+        std::string prefix = OutputManager::getInstance().getDefaultPrefix(level::debug_output, context::undefined());
+        EXPECT_CALL(writer, printLine(prefix + "line1", level::debug_output));
+
+        writer.output(level::debug_output, context::undefined(), lines);
+    }
+
+    // setLevelMax sets level max
+    void testLevelMaxUserWarning(OutputLevel mask)
+    {
+        EXPECT_FALSE(mask & level::none);
+        EXPECT_TRUE(mask & level::message);
+        EXPECT_TRUE(mask & level::debug_output);
+        EXPECT_TRUE(mask & level::user_error);
+        EXPECT_TRUE(mask & level::user_warning);
+        EXPECT_FALSE(mask & level::user_status);
+        EXPECT_FALSE(mask & level::verbose);
+    }
+
+    TEST(BaseWriterTest, SetLevelMax)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.setLevelMax(level::user_warning);
+        testLevelMaxUserWarning(writer.getLevelMask());
+    }
+
+    // setAdditionalContextsLevelMax sets additional contexts level max
+    TEST(BaseWriterTest, SetAdditionalContextsLevelMax)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.setAdditionalContextsLevelMax(level::user_warning);
+        testLevelMaxUserWarning(writer.getAdditionalContextsLevelMask());
+    }
+
+    // changedConfigurableLevel sets max level to configurableMaxLevel_
+    TEST(BaseWriterTest, ChangedConfigurableLevel)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.configurableMaxLevel_ = level::user_warning;
+        writer.changedConfigurableLevel();
+
+        testLevelMaxUserWarning(writer.getLevelMask());
+    }
+
+    // changedConfigurableAdditionalContextsLevel sets additional contexts level max to configurableAdditionalContextsMaxLevel_
+    TEST(BaseWriterTest, ChangedConfigurableAdditionalContextsLevel)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.configurableAdditionalContextsMaxLevel_ = level::user_warning;
+        writer.changedConfigurableAdditionalContextsLevel();
+
+        testLevelMaxUserWarning(writer.getAdditionalContextsLevelMask());
+    }
+
+    // changedConfigurableAdditionalContexts sets additional contexts to configurableAdditionalContexts_
+    TEST(BaseWriterTest, ChangedConfigurableAdditionalContexts)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.configurableAdditionalContexts_.push_back("unittest1");
+        writer.changedConfigurableAdditionalContexts();
+
+        EXPECT_TRUE(writer.getAdditionalContextsMask() & context::unittest1().mask);
+    }
+
+    // contexts added by name
+    TEST(BaseWriterTest, DefineContextsByName)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.configurableAdditionalContexts_.push_back("unittest1");
+        writer.configurableAdditionalContexts_.push_back("unittest2");
+        writer.changedConfigurableAdditionalContexts();
+
+        EXPECT_TRUE(writer.acceptsOutput(level::message, context::unittest1()));
+        EXPECT_TRUE(writer.acceptsOutput(level::message, context::unittest2()));
+        EXPECT_FALSE(writer.acceptsOutput(level::message, context::unittest3()));
+    }
+
+    // subcontexts added by name, separated from base context with "::"
+    TEST(BaseWriterTest, DefineSubcontextsByName)
+    {
+        MockBaseWriter writer("mytestname");
+
+        writer.configurableAdditionalContexts_.push_back("unittest3::sub1");
+        writer.configurableAdditionalContexts_.push_back("unittest3::sub3");
+        writer.changedConfigurableAdditionalContexts();
+
+        EXPECT_FALSE(writer.acceptsOutput(level::message, context::unittest3()));
+        EXPECT_FALSE(writer.acceptsOutput(level::message, context::unittest3()));
+        EXPECT_FALSE(writer.acceptsOutput(level::message, context::unittest3()));
+        EXPECT_TRUE(writer.acceptsOutput(level::message, context::sub1()));
+        EXPECT_FALSE(writer.acceptsOutput(level::message, context::sub2()));
+        EXPECT_TRUE(writer.acceptsOutput(level::message, context::sub3()));
+    }
 }
