diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9c0d3d355f6f3bae905f76b11fcc3ca5d7a95f7..51d119c59c218c9ccbcf03f663e1dfa1bd31c0cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,65 +10,58 @@ if (HAVE_LIB_M)
     set(EXTRA_LIBS ${EXTRA_LIBS} m)
 endif (HAVE_LIB_M)
 
-# Fetch Catch2
+add_executable(Uebung4
+        src/main.cpp
+        src/fillnans.cpp
+        src/fillnans.hpp
+        src/integrate.cpp
+        src/integrate.hpp
+        src/string_tools.cpp
+        src/string_tools.hpp
+)
+
+target_link_libraries(Uebung4 PUBLIC ${EXTRA_LIBS})
+
+# Fetch GoogleTest
 Include(FetchContent)
 FetchContent_Declare(
-        Catch2
-        GIT_REPOSITORY https://github.com/catchorg/Catch2.git
-        GIT_TAG        v3.3.2
+        googletest
+        GIT_REPOSITORY https://github.com/google/googletest.git
+        GIT_TAG        v1.15.2
 )
-FetchContent_MakeAvailable(Catch2)
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+FetchContent_MakeAvailable(googletest)
 
 # Build Tests
 enable_testing()
 
-
-add_executable(main src/main.cpp
-        src/string_tools.cpp
-        src/string_tools.h
-        src/integrate.cpp
-        src/integrate.h
-        src/fillnans.cpp
-        src/fillnans.h)
-
-add_library(common OBJECT
-        src/string_tools.cpp
-        src/string_tools.h
-        src/integrate.cpp
-        src/integrate.h
-        src/fillnans.cpp
-        src/fillnans.h)
-
-
-target_link_libraries(main PUBLIC ${EXTRA_LIBS})
-target_link_libraries(common PUBLIC ${EXTRA_LIBS})
-
 add_executable(test_string
-        $<TARGET_OBJECTS:common>
+        src/string_tools.cpp
+        src/string_tools.hpp
         src/string_tools.test.cpp
 )
 
 add_executable(test_integrate
-        $<TARGET_OBJECTS:common>
+        src/integrate.cpp
+        src/integrate.hpp
         src/integrate.test.cpp
 )
 
 add_executable(test_fillnans
-        $<TARGET_OBJECTS:common>
+        src/fillnans.cpp
+        src/fillnans.hpp
         src/fillnans.test.cpp
 )
 
-target_link_libraries(test_string PRIVATE Catch2::Catch2WithMain)
-target_link_libraries(test_integrate PRIVATE Catch2::Catch2WithMain)
-target_link_libraries(test_fillnans PRIVATE Catch2::Catch2WithMain)
+target_link_libraries(test_string PRIVATE GTest::gtest_main ${EXTRA_LIBS})
+target_link_libraries(test_integrate PRIVATE GTest::gtest_main ${EXTRA_LIBS})
+target_link_libraries(test_fillnans PRIVATE GTest::gtest_main ${EXTRA_LIBS})
 
 target_include_directories(test_string PRIVATE src/)
 target_include_directories(test_integrate PRIVATE src/)
 target_include_directories(test_fillnans PRIVATE src/)
 
-add_test(test_string ./test_string)
-add_test(test_integrate ./test_integrate)
-add_test(test_fillnans ./test_fillnans)
-set_property(TEST test_string PROPERTY ENVIRONMENT "CTEST_OUTPUT_ON_FAILURE=1")
-set_property(TEST test_integrate PROPERTY ENVIRONMENT "CTEST_OUTPUT_ON_FAILURE=1")
-set_property(TEST test_fillnans PROPERTY ENVIRONMENT "CTEST_OUTPUT_ON_FAILURE=1")
\ No newline at end of file
+include(GoogleTest)
+gtest_discover_tests(test_string)
+gtest_discover_tests(test_integrate)
+gtest_discover_tests(test_fillnans)
\ No newline at end of file
diff --git a/src/fillnans.cpp b/src/fillnans.cpp
index b4320c2d1b24036adc8b9dfe3e1ab703ef826bac..c1b62a533d4deefe68cd3fbbee10b9198c77db65 100644
--- a/src/fillnans.cpp
+++ b/src/fillnans.cpp
@@ -1,4 +1,4 @@
-#include "fillnans.h"
+#include "fillnans.hpp"
 
 #include <cmath>
 #include <iostream>
diff --git a/src/fillnans.h b/src/fillnans.hpp
similarity index 100%
rename from src/fillnans.h
rename to src/fillnans.hpp
diff --git a/src/fillnans.test.cpp b/src/fillnans.test.cpp
index a9d6dae3b370c9fcb2b84c61a0aa505aff454011..f6ff5a174a593fe861e0f64dbbc61704270d20f7 100644
--- a/src/fillnans.test.cpp
+++ b/src/fillnans.test.cpp
@@ -1,66 +1,77 @@
-#include <cmath>
+#include "fillnans.hpp"
 
-#include "fillnans.h"
+#include <gtest/gtest.h>
 
-#include <catch2/catch_test_macros.hpp>
-#include <catch2/matchers/catch_matchers_floating_point.hpp>
+#include <cmath>
+#include <vector>
 
-static void check_array(double* data, std::vector<double> ref, double tol = 1e-12) {
+static void check_array(double* data, std::vector<double> ref,
+                        double tol = 1e-12) {
     for (size_t i = 0; i < ref.size(); ++i) {
-        CHECK_THAT(data[i], Catch::Matchers::WithinRel(ref[i], tol));
+        EXPECT_NEAR(data[i], ref[i], tol);
     }
 }
 
-TEST_CASE("fillnans_left") {
+TEST(fillnans, left) {
     double data1[]{1, 2, 3, 4};
-    const size_t count1 = fill_nans(data1, sizeof(data1) / sizeof(double), InterpMethod::Left);
-    REQUIRE(count1 == 0);
+    const size_t count1 =
+        fill_nans(data1, sizeof(data1) / sizeof(double), InterpMethod::Left);
+    EXPECT_EQ(count1, 0);
     check_array(data1, {1.0, 2.0, 3.0, 4.0});
 
     double data2[]{1, NAN, 3, 4, 5};
-    const size_t count2 = fill_nans(data2, sizeof(data2) / sizeof(double), InterpMethod::Left);
-    REQUIRE(count2 == 1);
+    const size_t count2 =
+        fill_nans(data2, sizeof(data2) / sizeof(double), InterpMethod::Left);
+    EXPECT_EQ(count2, 1);
     check_array(data2, {1.0, 1.0, 3.0, 4.0, 5.0});
 
     double data3[]{1, NAN, 3, NAN, 5};
-    const size_t count3 = fill_nans(data3, sizeof(data3) / sizeof(double), InterpMethod::Left);
-    REQUIRE(count3 == 2);
+    const size_t count3 =
+        fill_nans(data3, sizeof(data3) / sizeof(double), InterpMethod::Left);
+    EXPECT_EQ(count3, 2);
     check_array(data3, {1.0, 1.0, 3.0, 3.0, 5.0});
 
     double data4[]{1, NAN, NAN, 4, 5};
-    const size_t count4 = fill_nans(data4, sizeof(data4) / sizeof(double), InterpMethod::Left);
-    REQUIRE(count4 == 2);
+    const size_t count4 =
+        fill_nans(data4, sizeof(data4) / sizeof(double), InterpMethod::Left);
+    EXPECT_EQ(count4, 2);
     check_array(data4, {1.0, 1.0, 1.0, 4.0, 5.0});
 
     double data5[]{1, NAN, NAN, NAN, 5};
-    const size_t count5 = fill_nans(data5, sizeof(data5) / sizeof(double), InterpMethod::Left);
-    REQUIRE(count5 == 3);
+    const size_t count5 =
+        fill_nans(data5, sizeof(data5) / sizeof(double), InterpMethod::Left);
+    EXPECT_EQ(count5, 3);
     check_array(data5, {1.0, 1.0, 1.0, 1.0, 5.0});
 }
 
-TEST_CASE("fillnans_linear") {
+TEST(fillnans, linear) {
     double data1[]{1, 2, 4, 6, 10};
-    const size_t count1 = fill_nans(data1, sizeof(data1) / sizeof(double), InterpMethod::Linear);
-    REQUIRE(count1 == 0);
+    const size_t count1 =
+        fill_nans(data1, sizeof(data1) / sizeof(double), InterpMethod::Linear);
+    EXPECT_EQ(count1, 0);
     check_array(data1, {1.0, 2.0, 4.0, 6.0});
 
     double data2[]{1, NAN, 4, 6, 10};
-    const size_t count2 = fill_nans(data2, sizeof(data2) / sizeof(double), InterpMethod::Linear);
-    REQUIRE(count2 == 1);
+    const size_t count2 =
+        fill_nans(data2, sizeof(data2) / sizeof(double), InterpMethod::Linear);
+    EXPECT_EQ(count2, 1);
     check_array(data2, {1.0, 2.5, 4.0, 6.0, 10.0});
 
     double data3[]{1, NAN, 4, NAN, 10};
-    const size_t count3 = fill_nans(data3, sizeof(data3) / sizeof(double), InterpMethod::Linear);
-    REQUIRE(count3 == 2);
+    const size_t count3 =
+        fill_nans(data3, sizeof(data3) / sizeof(double), InterpMethod::Linear);
+    EXPECT_EQ(count3, 2);
     check_array(data3, {1.0, 2.5, 4.0, 7.0, 10.0});
 
     double data4[]{1, NAN, NAN, 6, 10};
-    const size_t count4 = fill_nans(data4, sizeof(data4) / sizeof(double), InterpMethod::Linear);
-    REQUIRE(count4 == 2);
+    const size_t count4 =
+        fill_nans(data4, sizeof(data4) / sizeof(double), InterpMethod::Linear);
+    EXPECT_EQ(count4, 2);
     check_array(data4, {1.0, 8.0 / 3.0, 13.0 / 3.0, 6.0, 10.0});
 
     double data5[]{1, NAN, NAN, NAN, 11};
-    const size_t count5 = fill_nans(data5, sizeof(data5) / sizeof(double), InterpMethod::Linear);
-    REQUIRE(count5 == 3);
+    const size_t count5 =
+        fill_nans(data5, sizeof(data5) / sizeof(double), InterpMethod::Linear);
+    EXPECT_EQ(count5, 3);
     check_array(data5, {1.0, 3.5, 6.0, 8.5, 11.0});
 }
diff --git a/src/integrate.cpp b/src/integrate.cpp
index 5b68b4996c71e688cdd1c40e2a53c50d4ca0013c..5df1d22deb29ee1e37909a6975d4303547a58476 100644
--- a/src/integrate.cpp
+++ b/src/integrate.cpp
@@ -1,4 +1,4 @@
-#include "integrate.h"
+#include "integrate.hpp"
 
 #include <cmath>
 
diff --git a/src/integrate.h b/src/integrate.hpp
similarity index 100%
rename from src/integrate.h
rename to src/integrate.hpp
diff --git a/src/integrate.test.cpp b/src/integrate.test.cpp
index 238ba8395d01e0fb1489386102ed4fac1c9fa4cb..ddecbd7a6fca23dc5647c5223ebc64853fd7f214 100644
--- a/src/integrate.test.cpp
+++ b/src/integrate.test.cpp
@@ -1,21 +1,20 @@
-#include "integrate.h"
+#include "integrate.hpp"
 
-#include <catch2/catch_test_macros.hpp>
-#include <catch2/matchers/catch_matchers_floating_point.hpp>
+#include <gtest/gtest.h>
 
-TEST_CASE("f1") { CHECK_THAT(f1(0.4), Catch::Matchers::WithinRel(0.56, 0.01)); }
+TEST(function, one) { EXPECT_NEAR(f1(0.4), 0.56, 0.01); }
 
-TEST_CASE("f2") { CHECK_THAT(f2(2), Catch::Matchers::WithinRel(0.693, 0.01)); }
+TEST(function, two) { EXPECT_NEAR(f2(2), 0.693, 0.01); }
 
 static double one(double) { return 1.0; }
 
-TEST_CASE("integrate_constant") {
-    CHECK_THAT(integrate(one, 0, 10, 1), Catch::Matchers::WithinRel(10.0, 1e-12));
-    CHECK_THAT(integrate(one, 1, 10, 2), Catch::Matchers::WithinRel(9.0, 1e-12));
-    CHECK_THAT(integrate(one, 2, 10, 10000), Catch::Matchers::WithinRel(8.0, 1e-12));
+TEST(integrate, constant) {
+    EXPECT_NEAR(integrate(one, 0, 10, 1), 10.0, 1e-12);
+    EXPECT_NEAR(integrate(one, 1, 10, 2), 9.0, 1e-12);
+    EXPECT_NEAR(integrate(one, 2, 10, 10000), 8.0, 1e-12);
 }
 
-TEST_CASE("integrate") {
-    CHECK_THAT(integrate(f1, 0, 10, 10000), Catch::Matchers::WithinRel(383.33, 0.01));
-    CHECK_THAT(integrate(f2, 1, 10, 10000), Catch::Matchers::WithinRel(14.0373, 0.01));
+TEST(integrate, functions) {
+    EXPECT_NEAR(integrate(f1, 0, 10, 100000), 383.33, 0.02);
+    EXPECT_NEAR(integrate(f2, 1, 10, 100000), 14.0373, 0.02);
 }
diff --git a/src/main.cpp b/src/main.cpp
index cc108d7c3374a450b6ced8aedeb53eceaf5493bd..128943bb039757eee35238f8da074c3e13b2c3c6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,6 @@
 #include <iostream>
 
-#include "integrate.h"
+#include "integrate.hpp"
 
 int main() {
     std::cout << integrate(f2, 1, 10, 100000);
diff --git a/src/string_tools.cpp b/src/string_tools.cpp
index 1d1dd72c414173e674064d927c81c90d1eeb7639..6fe1a0b0d2a237c4f0e6fe55d055b5e8fbcd3e07 100644
--- a/src/string_tools.cpp
+++ b/src/string_tools.cpp
@@ -1,4 +1,4 @@
-#include "string_tools.h"
+#include "string_tools.hpp"
 
 #include <cctype>
 
diff --git a/src/string_tools.h b/src/string_tools.hpp
similarity index 100%
rename from src/string_tools.h
rename to src/string_tools.hpp
diff --git a/src/string_tools.test.cpp b/src/string_tools.test.cpp
index 0555284e6b0bac67a5ecbd11f6e2e286fbc36c17..7005aaa1dbf60048f306afb3ab6af2db077a380f 100644
--- a/src/string_tools.test.cpp
+++ b/src/string_tools.test.cpp
@@ -1,14 +1,15 @@
-#include "string_tools.h"
+#include "string_tools.hpp"
+
+#include <gtest/gtest.h>
 
-#include <catch2/catch_test_macros.hpp>
 #include <cstdio>
 
-TEST_CASE("palindrome") {
-    REQUIRE(isWordPalindrom(""));
-    REQUIRE(isWordPalindrom("a"));
-    REQUIRE(isWordPalindrom("anna"));
-    REQUIRE(isWordPalindrom("Anna"));
-    REQUIRE_FALSE(isWordPalindrom("Tomate"));
+TEST(isWordPalindrom, test) {
+    EXPECT_TRUE(isWordPalindrom(""));
+    EXPECT_TRUE(isWordPalindrom("a"));
+    EXPECT_TRUE(isWordPalindrom("anna"));
+    EXPECT_TRUE(isWordPalindrom("Anna"));
+    EXPECT_FALSE(isWordPalindrom("Tomate"));
 }
 
 constexpr char UNWRITTEN = (char)0xFF;
@@ -19,9 +20,9 @@ static void init_buffer(char* buf, size_t bufsize) {
     }
 }
 
-TEST_CASE("concat") {
-    // use one byte before and two bytes after buffer that is given to the function to assert that
-    // the function doesn't touch the surounding bytes.
+TEST(concat_s, test) {
+    // use one byte before and two bytes after buffer that is given to the
+    // function to assert that the function doesn't touch the surounding bytes.
     constexpr size_t TRUEBUFLEN = 13;
     char true_buf[TRUEBUFLEN];
 
@@ -30,64 +31,64 @@ TEST_CASE("concat") {
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "Test", "that");
-    REQUIRE(strcmp(buf, "Testthat") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "Testthat"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, " 0Test", " 2 ");
-    REQUIRE(strcmp(buf, " 0Test 2 ") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, " 0Test 2 "), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "1234567890123", "ABC");
-    REQUIRE(strcmp(buf, "123456789") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "123456789"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "ABC", "1234567890123");
-    REQUIRE(strcmp(buf, "ABC123456") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "ABC123456"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "123456789", "ABC");
-    REQUIRE(strcmp(buf, "123456789") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "123456789"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "xy", "");
-    REQUIRE(strcmp(buf, "xy") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "xy"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "", "ab");
-    REQUIRE(strcmp(buf, "ab") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, "ab"), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, BUFLEN, "", "");
-    REQUIRE(strcmp(buf, "") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN] == UNWRITTEN);
-    REQUIRE(buf[BUFLEN + 1] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, ""), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN], UNWRITTEN);
+    EXPECT_EQ(buf[BUFLEN + 1], UNWRITTEN);
 
     init_buffer(true_buf, TRUEBUFLEN);
     concat_s(buf, 1, "a", "b");
-    REQUIRE(strcmp(buf, "") == 0);
-    REQUIRE(buf[-1] == UNWRITTEN);
-    REQUIRE(buf[1] == UNWRITTEN);
-    REQUIRE(buf[2] == UNWRITTEN);
+    EXPECT_EQ(strcmp(buf, ""), 0);
+    EXPECT_EQ(buf[-1], UNWRITTEN);
+    EXPECT_EQ(buf[1], UNWRITTEN);
+    EXPECT_EQ(buf[2], UNWRITTEN);
 }