diff --git a/tests/test_SymbolTable.cpp b/tests/test_SymbolTable.cpp
index 1bf8a63b8456c3be0c4ee90d616fe88e0ec2e15e..33645f9ef70771ffb9d9b7f942b3ab7c259ee493 100644
--- a/tests/test_SymbolTable.cpp
+++ b/tests/test_SymbolTable.cpp
@@ -3,6 +3,8 @@
 #include <SymbolTable.hpp>
 #include <sstream>
 
+#include <CFunctionEmbedder.hpp>
+
 #include <pegtl/internal/iterator.hpp>
 
 TEST_CASE("SymbolTable", "[language]")
@@ -127,4 +129,92 @@ TEST_CASE("SymbolTable", "[language]")
     auto [i_search_b, found_b] = nested_st->find("b", use_position);
     REQUIRE(not found_b);   // "b" is not defined in any symbol table
   }
+
+  SECTION("Output of function_id")
+  {
+    std::shared_ptr root_st = std::make_shared<SymbolTable>();
+
+    using namespace TAO_PEGTL_NAMESPACE;
+    position begin_position{internal::iterator{"fixture"}, "fixture"};
+    begin_position.byte = 2;
+
+    auto [i_symbol_a, created_a] = root_st->add("a", begin_position);
+    REQUIRE(i_symbol_a->attributes().position().byte == 2);
+
+    position use_position{internal::iterator{"fixture"}, "fixture"};
+    use_position.byte = 3;   // after declarative position
+
+    auto [i_search_a, found_a] = root_st->find("a", use_position);
+    REQUIRE(found_a);
+    REQUIRE(i_search_a == i_symbol_a);
+
+    auto& attributes_a = i_search_a->attributes();
+    REQUIRE(attributes_a.dataType() == ASTNodeDataType::undefined_t);
+    REQUIRE(not attributes_a.isInitialized());
+
+    REQUIRE(std::holds_alternative<std::monostate>(attributes_a.value()));
+
+    {
+      std::stringstream value_output;
+      value_output << attributes_a;
+      REQUIRE(value_output.str() == "--");
+    }
+
+    // defining function data
+    attributes_a.setIsInitialized();
+    REQUIRE(attributes_a.isInitialized());
+
+    attributes_a.setDataType(ASTNodeDataType::function_t);
+    REQUIRE(attributes_a.dataType() == ASTNodeDataType::function_t);
+
+    attributes_a.value() = static_cast<uint64_t>(2);
+
+    REQUIRE(std::holds_alternative<uint64_t>(attributes_a.value()));
+
+    {
+      std::stringstream value_output;
+      value_output << attributes_a;
+      REQUIRE(value_output.str() == "function_id:2");
+    }
+
+    {
+      const SymbolTable::Symbol symbol{i_symbol_a->name(), i_symbol_a->attributes()};
+      std::stringstream value_output;
+      value_output << symbol.attributes();
+      REQUIRE(value_output.str() == "function_id:2");
+    }
+  }
+
+  SECTION("FunctionTable")
+  {
+    std::shared_ptr root_st = std::make_shared<SymbolTable>();
+
+    auto& function_table = root_st->functionTable();
+    REQUIRE(function_table.size() == 0);
+
+    const auto& const_function_table = static_cast<const SymbolTable&>(*root_st).functionTable();
+    REQUIRE(const_function_table.size() == 0);
+
+    function_table.add(FunctionDescriptor{});
+
+    REQUIRE(function_table.size() == 1);
+    REQUIRE(const_function_table.size() == 1);
+  }
+
+  SECTION("CFunctionEmbedderTable")
+  {
+    std::shared_ptr root_st = std::make_shared<SymbolTable>();
+
+    auto& c_function_table = root_st->cFunctionEbedderTable();
+    REQUIRE(c_function_table.size() == 0);
+
+    const auto& const_c_function_table = static_cast<const SymbolTable&>(*root_st).cFunctionEbedderTable();
+    REQUIRE(const_c_function_table.size() == 0);
+
+    c_function_table.add(std::make_shared<CFunctionEmbedder<double, double>>(
+      std::function<double(double)>{[](double) -> double { return 0; }}));
+
+    REQUIRE(c_function_table.size() == 1);
+    REQUIRE(const_c_function_table.size() == 1);
+  }
 }