diff --git a/BUILD.bazel b/BUILD.bazel
index 1241afd48a2b8ca915d26657c4eacf2b20c3dded..d26e88c2fef44b3cf0d6899b8f14a7405c6dceb3 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -18,7 +18,7 @@ cc_library(
 
 cc_library(
     name = "test_utils",
-    hdrs = ["test/MantleAPI/Test/test_utils.h"],
+    hdrs = glob(["test/**/*.h"]),
     includes = ["test"],
     visibility = ["//visibility:public"],
     deps = [
@@ -30,6 +30,6 @@ cc_library(
 cc_test(
     name = "interface_test",
     timeout = "short",
-    srcs = ["test/interface_test.cpp"],
+    srcs = ["test/interface_test.cpp"] + glob(["test/**/*.cc"]),
     deps = [":test_utils"],
 )
diff --git a/include/MantleAPI/Common/clothoid_spline.h b/include/MantleAPI/Common/clothoid_spline.h
new file mode 100644
index 0000000000000000000000000000000000000000..48a922799deec1b93582e8cbe11e1cc10ce83597
--- /dev/null
+++ b/include/MantleAPI/Common/clothoid_spline.h
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2025, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+//-----------------------------------------------------------------------------
+/// @file clothoid_spline.h
+//-----------------------------------------------------------------------------
+
+#ifndef MANTLEAPI_COMMON_CLOTHOID_SPLINE_H
+#define MANTLEAPI_COMMON_CLOTHOID_SPLINE_H
+
+#include <MantleAPI/Common/pose.h>
+#include <MantleAPI/Common/unit_definitions.h>
+#include <units.h>
+
+#include <optional>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+namespace mantle_api
+{
+
+/// This struct represents one segment of a clothoid spline
+struct ClothoidSplineSegment
+{
+  units::curve::curvature_t curvature_end;    ///< End curvature of the clothoid segment. Unit: [1/m]. Range: ]-inf..inf[.
+  units::curve::curvature_t curvature_start;  ///< Start curvature of the clothoid segment. Unit: [1/m]. Range: ]-inf..inf[.
+  units::angle::radian_t h_offset;            ///< Heading offset relative to end of the previous segment or to position_start if present. Unit: [rad]. Range: ]-pi..pi[.
+  units::length::meter_t length;              ///< Length of the clothoid segment. Unit: [m]. Range: ]0..inf[.
+  std::optional<Pose> position_start;         ///< Optional start position of the clothoid segment.
+};
+
+/// Compare two objects of ClothoidSplineSegment.
+///
+/// @param[in]  lhs left-hand side value for the comparison
+/// @param[in]  rhs right-hand side value for the comparison
+/// @returns  true if the values of lhs exactly equals to rhs values
+constexpr bool operator==(const ClothoidSplineSegment& lhs, const ClothoidSplineSegment& rhs) noexcept
+{
+  return std::tie(lhs.curvature_end, lhs.curvature_start, lhs.h_offset, lhs.length, lhs.position_start) ==
+         std::tie(rhs.curvature_end, rhs.curvature_start, rhs.h_offset, rhs.length, rhs.position_start);
+};
+
+/// Print a human-readable representation of 'ClothoidSplineSegment' to 'os'.
+///
+/// @param os             The output stream
+/// @param clothoid_spline_segment  ClothoidSplineSegment to be printed
+/// @returns 'clothoid_spline_segment' in a human-readable format
+inline std::ostream& operator<<(std::ostream& os, const ClothoidSplineSegment& clothoid_spline_segment)
+{
+  os << "ClothoidSplineSegment("
+     << ".curvatureEnd=" << clothoid_spline_segment.curvature_end
+     << ", .curvatureStart=" << clothoid_spline_segment.curvature_start
+     << ", .hOffset=" << clothoid_spline_segment.h_offset
+     << ", .length=" << clothoid_spline_segment.length;
+
+  if (clothoid_spline_segment.position_start.has_value())
+  {
+    os << ", .position_start=" << clothoid_spline_segment.position_start.value();
+  }
+  os << ")";
+  return os;
+};
+
+/// Representation of a single clothoid or a sequence of concatenated clothoids forming a spline
+struct ClothoidSpline
+{
+  using segments_type = std::vector<ClothoidSplineSegment>;  ///< Clothoid spline segments type
+  using iterator = segments_type::iterator;                  ///< Clothoid spline segments iterator
+  using const_iterator = segments_type::const_iterator;      ///< Clothoid spline segments const iterator
+
+  segments_type segments;  ///< Clothoid spline segments
+
+  /// Return an iterator to the beginning.
+  ///
+  /// @returns Return an iterator to the first element of the segments
+  iterator begin() { return segments.begin(); };
+
+  /// Return an iterator to the end.
+  ///
+  /// @returns Return an iterator to the element next after the last element of the segments
+  iterator end() { return segments.end(); };
+
+  /// Return the const iterator to the beginning.
+  ///
+  /// @returns Return the const iterator to the first element of the segments
+  [[nodiscard]] const_iterator cbegin() const { return segments.cbegin(); };
+
+  /// Return the const iterator to the end.
+  ///
+  /// @returns Return the const iterator to the element next after the last element of the segments
+  [[nodiscard]] const_iterator cend() const { return segments.cend(); };
+};
+
+/// Compare two objects of ClothoidSpline.
+///
+/// @param[in]  lhs left-hand side value for the comparison
+/// @param[in]  rhs right-hand side value for the comparison
+/// @returns  true if the segments values of lhs exactly equals to rhs segments values
+inline bool operator==(const ClothoidSpline& lhs, const ClothoidSpline& rhs) noexcept
+{
+  return lhs.segments == rhs.segments;
+};
+
+/// Print a human-readable representation of 'ClothoidSpline' to 'os'.
+///
+/// @param os             The output stream
+/// @param clothoid_spline  ClothoidSpline to be printed
+/// @returns 'clothoid_spline' in a human-readable format
+inline std::ostream& operator<<(std::ostream& os, const ClothoidSpline& clothoid_spline)
+{
+  os << "ClothoidSpline(";
+  for (std::size_t i = 0; i < clothoid_spline.segments.size(); i++)
+  {
+    os << (i == 0 ? "[" : ", [") << std::to_string(i) << "]=" << clothoid_spline.segments[i];
+  }
+  os << ")";
+  return os;
+};
+
+}  // namespace mantle_api
+
+#endif  // MANTLEAPI_COMMON_CLOTHOID_SPLINE_H
diff --git a/include/MantleAPI/Common/poly_line.h b/include/MantleAPI/Common/poly_line.h
index c28c40a1c432d14820f372704490ed60773f9cb1..ab3292e0e9b7a3dc7639369a137b515fa9a092bd 100644
--- a/include/MantleAPI/Common/poly_line.h
+++ b/include/MantleAPI/Common/poly_line.h
@@ -1,5 +1,6 @@
 /*******************************************************************************
  * Copyright (c) 2021-2023, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ * Copyright (c) 2024, Mercedes-Benz Tech Innovation GmbH
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -18,53 +19,74 @@
 #include <MantleAPI/Common/pose.h>
 #include <MantleAPI/Common/time_utils.h>
 
+#include <iosfwd>
 #include <optional>
+#include <string>
+#include <tuple>
 #include <vector>
 
 namespace mantle_api
 {
 
-/// This struct represents the point of a polygonal chain (polyline) trajectory specification
+/// One point of a polygonal chain (polyline) trajectory specification.
 struct PolyLinePoint
 {
-  Pose pose{};                 ///< Pose of the PolyLinePoint
-  std::optional<Time> time{};  ///< Time specification of the PolyLinePoint
+  Pose pose;                 ///< Pose of the PolyLinePoint
+  std::optional<Time> time;  ///< Time specification of the PolyLinePoint
+};
 
-  /// @brief Equality comparison for PolyLinePoint.
-  ///
-  /// @param[in]  other The left-hand side value for the comparison
-  /// @returns  true if the values of `this` exactly equal to the values of other.
-  bool operator==(const PolyLinePoint& other) const
-  {
-    return other.time == time && other.pose == pose;
-  }
+/// Compare the values of two PolyLinePoints.
+///
+/// @param[in] lhs left-hand side value for the comparison
+/// @param[in] rhs right-hand side value for the comparison
+/// @returns true, if the values of the two PolyLinePoints are equal, false otherwise
+constexpr bool operator==(const PolyLinePoint& lhs, const PolyLinePoint& rhs) noexcept
+{
+  return std::tie(lhs.pose, lhs.time) == std::tie(rhs.pose, rhs.time);
+}
 
-  /// @brief Prints a human-readable representation of 'polyLinePoint' to 'os'.
-  /// @param os             The output stream
-  /// @param polyLinePoint  The point of a polygonal chain (polyline) trajectory specification
-  /// @returns 'polyLinePoint' in a human-readable format
-  friend std::ostream& operator<<(std::ostream& os, const PolyLinePoint& polyLinePoint);
-};
+/// Compare the values of two PolyLinePoints.
+///
+/// @param[in] lhs left-hand side value for the comparison
+/// @param[in] rhs right-hand side value for the comparison
+/// @returns true, if the values of the two PolyLinePoints are not equal, false otherwise
+constexpr bool operator!=(const PolyLinePoint& lhs, const PolyLinePoint& rhs) noexcept
+{
+  return !(lhs == rhs);
+}
 
-/// @brief Prints a human-readable representation of 'polyLinePoint' to 'os'.
-/// @param os             The output stream
-/// @param polyLinePoint  The point of a polygonal chain (polyline) trajectory specification
-/// @returns 'polyLinePoint' in a human-readable format
-inline std::ostream& operator<<(std::ostream& os, const PolyLinePoint& polyLinePoint)
+/// The list of polyline points.
+using PolyLine = std::vector<PolyLinePoint>;
+
+/// Output stream operator for PolyLinePoint.
+///
+/// @param[in] os output stream
+/// @param[in] point PolyLinePoint to be printed
+/// @returns output stream with printed PolyLinePoint
+///
+inline std::ostream& operator<<(std::ostream& os, const PolyLinePoint& point)
 {
-  os << polyLinePoint.pose;
+  os << "PolyLinePoint(.pose=" << point.pose << ", .time=" << point.time.value_or(Time{}) << ')';
+  return os;
+}
 
-  if (polyLinePoint.time.has_value())
+/// Output stream operator for PolyLine.
+///
+/// @param[in] os output stream
+/// @param[in] poly_line PolyLine to be printed
+/// @returns output stream with printed PolyLine
+///
+inline std::ostream& operator<<(std::ostream& os, const PolyLine& poly_line)
+{
+  os << "PolyLine(";
+  for (auto idx = 0U; idx < poly_line.size(); ++idx)
   {
-    os << ", time in ms " << polyLinePoint.time.value();
+    os << (idx == 0U ? "[" : ", [") << std::to_string(idx) << "]=" << poly_line.at(idx);
   }
-
+  os << ')';
   return os;
 }
 
-/// The list of polyline points
-using PolyLine = std::vector<PolyLinePoint>;
-
 }  // namespace mantle_api
 
 #endif  // MANTLEAPI_COMMON_POLY_LINE_H
diff --git a/include/MantleAPI/Common/trajectory.h b/include/MantleAPI/Common/trajectory.h
index 0dbb0c880e7815cbf0fb27d6eda10fb13e657401..e4598bef778f4cc4c07466a5f9e10bf18b2cada3 100644
--- a/include/MantleAPI/Common/trajectory.h
+++ b/include/MantleAPI/Common/trajectory.h
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2021-2023, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ * Copyright (c) 2021-2025, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -15,45 +15,65 @@
 #ifndef MANTLEAPI_COMMON_TRAJECTORY_H
 #define MANTLEAPI_COMMON_TRAJECTORY_H
 
+#include <MantleAPI/Common/clothoid_spline.h>
 #include <MantleAPI/Common/poly_line.h>
 
+#include <cstdint>
+#include <optional>
 #include <string>
+#include <tuple>
 #include <variant>
 
 namespace mantle_api
 {
 
+/// Defines which reference point of the object is used for the trajectory.
+enum class TrajectoryReferencePoint : std::uint8_t
+{
+  kUndefined = 0,     ///< Type of trajectory reference point is underfined
+  kRearAxle,          ///< Reference point is the rear axle of the object
+  kFrontAxle,         ///< Reference point is the front axle of the object
+  kCenterOfMass,      ///< Reference point is the center of mass of the object
+  kBoundingBoxCenter  ///< Reference point is the center of the bounding box of the object
+};
+
 /// Definition of a trajectory type in terms of shape
 struct Trajectory
 {
-  std::string name;             ///< Name of the trajectory type
-  std::variant<PolyLine> type;  ///< Trajectory type in terms of shape
-
-  /// @brief Prints a human-readable representation of 'trajectory' to 'os'.
-  /// @param os         The output stream
-  /// @param trajectory Open scenario trajectory
-  /// @returns 'trajectory' in a human-readable format
-  friend std::ostream& operator<<(std::ostream& os, const Trajectory& trajectory);
+  std::string name;                             ///< Name of the trajectory type
+  std::variant<PolyLine, ClothoidSpline> type;  ///< Trajectory type in terms of shape
+  TrajectoryReferencePoint reference;           ///< Reference point of object, which is used in trajectory
 };
 
-/// @brief Prints a human-readable representation of 'trajectory' to 'os'.
+/// Compare two objects of Trajectory.
+///
+/// @param[in]  lhs left-hand side value for the comparison
+/// @param[in]  rhs right-hand side value for the comparison
+/// @returns  true if the values of lhs exactly equals to rhs values
+constexpr bool operator==(const Trajectory& lhs, const Trajectory& rhs) noexcept
+{
+  return std::tie(lhs.name, lhs.type, lhs.reference) == std::tie(rhs.name, rhs.type, rhs.reference);
+}
+
+/// Print a human-readable representation of 'trajectory' to 'os'.
+///
 /// @param os         The output stream
 /// @param trajectory Open scenario trajectory
 /// @returns 'trajectory' in a human-readable format
 inline std::ostream& operator<<(std::ostream& os, const Trajectory& trajectory)
 {
-  os << "Trajectory \"" << trajectory.name;
+  os << "Trajectory(.name=" << trajectory.name << ", .type=";
 
   if (std::holds_alternative<PolyLine>(trajectory.type))
   {
-    const auto& polyLine = std::get<PolyLine>(trajectory.type);
-    for (const auto& polyLinePoint : polyLine)
-    {
-      os << polyLinePoint;
-    }
+    os << std::get<PolyLine>(trajectory.type);
+  }
+  else if (std::holds_alternative<ClothoidSpline>(trajectory.type))
+  {
+    os << std::get<ClothoidSpline>(trajectory.type);
   }
 
-  os << "\"\n";
+  os << ", reference=" << static_cast<int>(trajectory.reference) << ")";
 
   return os;
 }
diff --git a/include/MantleAPI/Common/unit_definitions.h b/include/MantleAPI/Common/unit_definitions.h
index c3b6693197b7f01e7b88d635e0ccad31bf1f4668..f4cb0f7d6d8b97632400bb6333d2d11a9b06b0ae 100644
--- a/include/MantleAPI/Common/unit_definitions.h
+++ b/include/MantleAPI/Common/unit_definitions.h
@@ -84,6 +84,23 @@ using jerk_acceleration_unit = base_unit<detail::meter_ratio<1>, std::ratio<0>,
 
 UNIT_ADD_CATEGORY_TRAIT(jerk_acceleration)
 
+/// Definition of inverse meter [1/m]
+UNIT_ADD(
+    curve,
+    curvature,
+    curvatures,
+    curv,
+    unit<std::ratio<1>, inverse<length::meter>>)
+
+namespace category
+{
+
+using curve_unit = base_unit<std::ratio<1>, inverse<length::meter>>;
+
+}  // namespace category
+
+UNIT_ADD_CATEGORY_TRAIT(curve)
+
 }  // namespace units
 
 #endif  // MANTLEAPI_COMMON_UNIT_DEFINITIONS_H
diff --git a/test/MantleAPI/Common/CMakeLists.txt b/test/MantleAPI/Common/CMakeLists.txt
index 0bf4b4e39e65886709a435f23eb03bb1ec2bd469..9920800bd3dbf30b6b20f750bede30a74655355f 100644
--- a/test/MantleAPI/Common/CMakeLists.txt
+++ b/test/MantleAPI/Common/CMakeLists.txt
@@ -9,7 +9,7 @@
 ################################################################################
 
 add_executable(CommonTest)
-target_sources(CommonTest PUBLIC floating_point_helper_test.cc logger_test.cc log_utils_test.cc)
+target_sources(CommonTest PUBLIC floating_point_helper_test.cc logger_test.cc log_utils_test.cc clothoid_spline_test.cc trajectory_test.cc)
 target_include_directories(CommonTest PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/test>)
 target_link_libraries(CommonTest PUBLIC MantleAPI::MantleAPI GTest::gmock_main)
 
diff --git a/test/MantleAPI/Common/clothoid_spline_test.cc b/test/MantleAPI/Common/clothoid_spline_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dfc637d128f7d1cfcafcd3609be1188d7b337c86
--- /dev/null
+++ b/test/MantleAPI/Common/clothoid_spline_test.cc
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2025, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+#include <MantleAPI/Common/clothoid_spline.h>
+#include <MantleAPI/Common/pose.h>
+#include <gtest/gtest.h>
+
+#include <functional>
+#include <iostream>
+#include <optional>
+#include <sstream>
+
+using units::literals::operator""_m;
+using units::literals::operator""_rad;
+using units::literals::operator""_curv;
+
+using mantle_api::ClothoidSpline;
+using mantle_api::ClothoidSplineSegment;
+
+namespace
+{
+class ClothoidSplineTest : public ::testing::Test
+{
+public:
+  ClothoidSplineTest()
+  {
+    clothoid_spline_left_.segments.push_back({0.0_curv,
+                                              6.6_curv,
+                                              0.4_rad,
+                                              1.0_m,
+                                              std::nullopt});
+
+    clothoid_spline_left_.segments.push_back(
+        {
+            7.0_curv,
+            -7.6_curv,
+            0.5_rad,
+            0.2_m,
+            mantle_api::Pose{{96.8_m, -4.9_m, 1.6_m}, {-0.3_rad, 2.8_rad, -2.0_rad}},
+        });
+    clothoid_spline_right_ = clothoid_spline_left_;
+  }
+
+protected:
+  ClothoidSpline clothoid_spline_left_;
+  ClothoidSpline clothoid_spline_right_;
+};
+
+TEST_F(ClothoidSplineTest, GivenClothoidSplineSegments_WhenSegmentsHaveEqualParameters_ThenClothoidSplineSegmentEqualOperatorReturnsTrue)
+{
+  ClothoidSplineSegment segment_left = clothoid_spline_left_.segments.back();
+  ClothoidSplineSegment segment_rigt = clothoid_spline_left_.segments.back();
+
+  EXPECT_TRUE(segment_left == segment_rigt);
+}
+
+using ChangeParam = std::function<void(ClothoidSplineSegment&)>;
+
+void ChangeCurvatureEnd(ClothoidSplineSegment& segment)
+{
+  segment.curvature_end = 6.7_curv;
+}
+
+void ChangeCurvatureStart(ClothoidSplineSegment& segment)
+{
+  segment.curvature_start = 5.7_curv;
+}
+
+void ChangeHOffset(ClothoidSplineSegment& segment)
+{
+  segment.h_offset = 188.0_rad;
+}
+
+void ChangeLength(ClothoidSplineSegment& segment)
+{
+  segment.length = 256.0_m;
+}
+
+void ChangePositionStart(ClothoidSplineSegment& segment)
+{
+  if (segment.position_start.has_value())
+  {
+    segment.position_start.value().position.x = 6.8_m;
+  }
+}
+
+class ClothoidSplineTestParam : public ::testing::WithParamInterface<ChangeParam>, public ClothoidSplineTest
+{
+};
+
+INSTANTIATE_TEST_SUITE_P(ClothoidSplineTestInstParam,
+                         ClothoidSplineTestParam,
+                         ::testing::Values(
+                             ChangeCurvatureEnd,
+                             ChangeCurvatureStart,
+                             ChangeHOffset,
+                             ChangeLength,
+                             ChangePositionStart));
+
+TEST_P(ClothoidSplineTestParam, GivenClothoidSplineSegments_WhenSegmentsHaveDifferentParameters_ThenClothoidSplineSegmentEqualOperatorReturnsFalse)
+{
+  ClothoidSplineSegment segment_left = clothoid_spline_left_.segments.back();
+  ClothoidSplineSegment segment_right = clothoid_spline_left_.segments.back();
+
+  GetParam()(segment_right);
+
+  EXPECT_FALSE(segment_left == segment_right);
+}
+
+TEST_F(ClothoidSplineTest, GivenClothoidSplines_WhenSegmentsHaveEqualParameters_ThenClothoidSplineEqualOperatorReturnsTrue)
+{
+  EXPECT_TRUE(clothoid_spline_left_ == clothoid_spline_right_);
+}
+
+TEST_F(ClothoidSplineTest, GivenClothoidSplines_WhenSegmentsHaveDifferentParameters_ThenClothoidSplineEqualOperatorReturnsFalse)
+{
+  clothoid_spline_right_.segments.back().curvature_end = 6.7_curv;
+  EXPECT_FALSE(clothoid_spline_left_ == clothoid_spline_right_);
+}
+
+TEST_F(ClothoidSplineTest, GivenClothoidSplines_WhenSegmentsHaveDifferentSize_ThenClothoidSplineEqualOperatorReturnsFalse)
+{
+  clothoid_spline_left_.segments.push_back(ClothoidSplineSegment());
+  EXPECT_FALSE(clothoid_spline_left_ == clothoid_spline_right_);
+}
+
+TEST_F(ClothoidSplineTest, GivenClothoidSpline_WhenOutputToStream_ThenNoExceptionAndOutputNotEmpty)
+{
+  auto output_to_stream = [](std::ostream& os, ClothoidSpline& clothoid_spline)
+  {
+    os << clothoid_spline;
+  };
+  std::ostringstream actual_os;
+  ASSERT_NO_THROW(output_to_stream(actual_os, clothoid_spline_left_));
+  EXPECT_GT(actual_os.str().size(), 0);
+}
+
+TEST_F(ClothoidSplineTest, GivenClothoidSpline_WhenIterate_ThenIterationIsCorrect)
+{
+  auto actual_it{clothoid_spline_left_.begin()};
+  auto expected_it{clothoid_spline_left_.segments.begin()};
+
+  EXPECT_EQ(clothoid_spline_left_.begin(), clothoid_spline_left_.segments.begin());
+  EXPECT_EQ(clothoid_spline_left_.end(), clothoid_spline_left_.segments.end());
+
+  while (actual_it != clothoid_spline_left_.end())
+  {
+    // Test if increment is correct
+    EXPECT_EQ(actual_it, expected_it);
+
+    // Test if dereferencing is correct
+    EXPECT_EQ(*actual_it, *expected_it);
+
+    ++actual_it;
+    ++expected_it;
+  }
+
+  EXPECT_EQ(actual_it, clothoid_spline_left_.segments.end());
+}
+
+TEST_F(ClothoidSplineTest, GivenConstClothoidSpline_WhenIterate_ThenIterationIsCorrect)
+{
+  const ClothoidSpline clothoid_spline{clothoid_spline_left_};
+  auto actual_it{clothoid_spline.cbegin()};
+  auto expected_it{clothoid_spline.segments.cbegin()};
+
+  EXPECT_EQ(clothoid_spline.cbegin(), clothoid_spline.segments.cbegin());
+  EXPECT_EQ(clothoid_spline.cend(), clothoid_spline.segments.cend());
+
+  while (actual_it != clothoid_spline.cend())
+  {
+    // Test if increment is correct
+    EXPECT_EQ(actual_it, expected_it);
+
+    // Test if dereferencing is correct
+    EXPECT_EQ(*actual_it, *expected_it);
+
+    ++actual_it;
+    ++expected_it;
+  }
+
+  EXPECT_EQ(actual_it, clothoid_spline.segments.cend());
+}
+}  // namespace
diff --git a/test/MantleAPI/Common/trajectory_test.cc b/test/MantleAPI/Common/trajectory_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..684315815fc8b59d863971d4f151587a5c77e115
--- /dev/null
+++ b/test/MantleAPI/Common/trajectory_test.cc
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2025, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+#include <MantleAPI/Common/trajectory.h>
+#include <gtest/gtest.h>
+
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <variant>
+
+using units::literals::operator""_m;
+using units::literals::operator""_rad;
+using units::literals::operator""_curv;
+using units::literals::operator""_s;
+
+using mantle_api::ClothoidSpline;
+using mantle_api::PolyLine;
+using mantle_api::Trajectory;
+
+namespace
+{
+class TrajectoryTest : public ::testing::Test
+{
+public:
+  TrajectoryTest()
+  {
+    clothoid_spline_.segments.push_back({0.0_curv,
+                                         6.6_curv,
+                                         0.4_rad,
+                                         1.0_m,
+                                         std::nullopt});
+
+    clothoid_spline_.segments.push_back({
+        7.0_curv,
+        -7.6_curv,
+        0.5_rad,
+        0.2_m,
+        mantle_api::Pose{{96.8_m, -4.9_m, 1.6_m}, {-0.3_rad, 2.8_rad, -2.0_rad}},
+    });
+
+    polyline_.push_back({{{1.0_m, 51.0_m, 8.3_m}, {0.8_rad, 0.5_rad, 0.4_rad}}, 0.5_s});
+    polyline_.push_back({{{1.0_m, 51.0_m, 8.3_m}, {-0.8_rad, 0.5_rad, 0.4_rad}}, 0.6_s});
+
+    trajectory_left_.name = "Trajectory";
+    trajectory_left_.reference = mantle_api::TrajectoryReferencePoint::kCenterOfMass;
+  }
+
+protected:
+  ClothoidSpline clothoid_spline_;
+  PolyLine polyline_;
+  Trajectory trajectory_left_;
+  Trajectory trajectory_right_;
+};
+
+TEST_F(TrajectoryTest, GivenTrajectories_WhenTrajectoriesHaveEqualParameters_ThenTrajectoryEqualOperatorReturnsTrue)
+{
+  trajectory_left_.type = clothoid_spline_;
+  trajectory_right_ = trajectory_left_;
+  EXPECT_TRUE(trajectory_left_ == trajectory_right_);
+
+  trajectory_left_.type = polyline_;
+  trajectory_right_ = trajectory_left_;
+  EXPECT_TRUE(trajectory_left_ == trajectory_right_);
+}
+
+using ChangeParam = std::function<void(Trajectory&)>;
+
+void ChangeName(Trajectory& trajectory)
+{
+  trajectory.name = "New name";
+}
+
+void ChangeType(Trajectory& trajectory)
+{
+  if (std::holds_alternative<PolyLine>(trajectory.type))
+  {
+    auto& polyline = std::get<PolyLine>(trajectory.type);
+    polyline.front().pose.position.x = 100_m;
+  }
+  else if (std::holds_alternative<ClothoidSpline>(trajectory.type))
+  {
+    auto& clothoid = std::get<ClothoidSpline>(trajectory.type);
+    clothoid.segments.front().curvature_end = 100.0_curv;
+  }
+}
+
+void ChangeReference(Trajectory& trajectory)
+{
+  trajectory.reference = mantle_api::TrajectoryReferencePoint::kRearAxle;
+}
+
+class TrajectoryTestParam : public ::testing::WithParamInterface<ChangeParam>, public TrajectoryTest
+{
+};
+
+INSTANTIATE_TEST_SUITE_P(TrajectoryTestInstParam,
+                         TrajectoryTestParam,
+                         ::testing::Values(
+                             ChangeName,
+                             ChangeType,
+                             ChangeReference));
+
+TEST_P(TrajectoryTestParam, GivenTrajectories_WhenTrajectoriesHaveDifferentParameters_ThenTrajectoryEqualOperatorReturnsFalse)
+{
+  trajectory_left_.type = polyline_;
+  trajectory_right_ = trajectory_left_;
+  GetParam()(trajectory_right_);
+  EXPECT_FALSE(trajectory_left_ == trajectory_right_);
+
+  trajectory_left_.type = clothoid_spline_;
+  trajectory_right_ = trajectory_left_;
+  GetParam()(trajectory_right_);
+  EXPECT_FALSE(trajectory_left_ == trajectory_right_);
+}
+
+TEST_F(TrajectoryTest, GivenTrajectoryWithNoType_WhenOutputToStream_ThenNoExceptionAndOutputNotEmpty)
+{
+  std::stringstream actual_os;
+  auto output_to_stream = [](std::ostream& os, Trajectory& trajectory)
+  {
+    os << trajectory;
+  };
+  ASSERT_NO_THROW(output_to_stream(actual_os, trajectory_left_));
+  EXPECT_GT(actual_os.str().size(), 0);
+}
+
+TEST_F(TrajectoryTest, GivenTrajectoryWithPolylineType_WhenOutputToStream_ThenNoExceptionAndOutputNotEmpty)
+{
+  std::stringstream actual_os;
+  trajectory_left_.type = polyline_;
+  auto output_to_stream = [](std::ostream& os, Trajectory& trajectory)
+  {
+    os << trajectory;
+  };
+  ASSERT_NO_THROW(output_to_stream(actual_os, trajectory_left_));
+  EXPECT_GT(actual_os.str().size(), 0);
+}
+
+TEST_F(TrajectoryTest, GivenTrajectoryWithClothoidSplineType_WhenOutputToStream_ThenNoExceptionAndOutputNotEmpty)
+{
+  std::stringstream actual_os;
+  trajectory_left_.type = clothoid_spline_;
+  auto output_to_stream = [](std::ostream& os, Trajectory& trajectory)
+  {
+    os << trajectory;
+  };
+  ASSERT_NO_THROW(output_to_stream(actual_os, trajectory_left_));
+  EXPECT_GT(actual_os.str().size(), 0);
+}
+}  // namespace