diff --git a/CMakeLists.txt b/CMakeLists.txt
index cee720940c..f91ba950aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,12 +3,14 @@
 
 cmake_minimum_required(VERSION 3.22)
 
+project(yuzu)
+
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
+
 include(DownloadExternals)
 include(CMakeDependentOption)
-
-project(yuzu)
+include(CTest)
 
 # Set bundled sdl2/qt as dependent options.
 # OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
@@ -42,7 +44,7 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
 
 option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
 
-option(YUZU_TESTS "Compile tests" ON)
+option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
 
 option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
 
@@ -242,7 +244,7 @@ if (ENABLE_WEB_SERVICE)
 endif()
 
 if (YUZU_TESTS)
-    find_package(Catch2 2.13.7 REQUIRED)
+    find_package(Catch2 3.0.1 REQUIRED)
 endif()
 
 find_package(Boost 1.73.0 COMPONENTS context)
@@ -606,7 +608,6 @@ if (YUZU_USE_FASTER_LD AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     endif()
 endif()
 
-enable_testing()
 add_subdirectory(externals)
 add_subdirectory(src)
 
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 89a3815875..94dd8bb622 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -5,6 +5,9 @@
 # some of its variables, which is only possible in 3.13+
 set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
 
+# Disable tests in all externals supporting the standard option name
+set(BUILD_TESTING OFF)
+
 # xbyak
 if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
     add_subdirectory(xbyak EXCLUDE_FROM_ALL)
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 9b65e79cbf..ae84408bcf 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -14,7 +14,6 @@ add_executable(tests
     core/core_timing.cpp
     core/internal_network/network.cpp
     precompiled_headers.h
-    tests.cpp
     video_core/buffer_base.cpp
     input_common/calibration_configuration_job.cpp
 )
@@ -22,7 +21,7 @@ add_executable(tests
 create_target_directory_groups(tests)
 
 target_link_libraries(tests PRIVATE common core input_common)
-target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Catch2::Catch2 Threads::Threads)
+target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Catch2::Catch2WithMain Threads::Threads)
 
 add_test(NAME tests COMMAND tests)
 
diff --git a/src/tests/common/bit_field.cpp b/src/tests/common/bit_field.cpp
index 0071ae52e8..75e990ecd9 100644
--- a/src/tests/common/bit_field.cpp
+++ b/src/tests/common/bit_field.cpp
@@ -4,7 +4,7 @@
 #include <array>
 #include <cstring>
 #include <type_traits>
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 #include "common/bit_field.h"
 
 TEST_CASE("BitField", "[common]") {
diff --git a/src/tests/common/cityhash.cpp b/src/tests/common/cityhash.cpp
index 05942eadb4..2a391dff16 100644
--- a/src/tests/common/cityhash.cpp
+++ b/src/tests/common/cityhash.cpp
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/cityhash.h"
 
diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp
index 4e29f91996..ecad7583ff 100644
--- a/src/tests/common/fibers.cpp
+++ b/src/tests/common/fibers.cpp
@@ -11,7 +11,7 @@
 #include <unordered_map>
 #include <vector>
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/common_types.h"
 #include "common/fiber.h"
diff --git a/src/tests/common/host_memory.cpp b/src/tests/common/host_memory.cpp
index e49d0a09fb..1b014b6326 100644
--- a/src/tests/common/host_memory.cpp
+++ b/src/tests/common/host_memory.cpp
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/host_memory.h"
 #include "common/literals.h"
diff --git a/src/tests/common/param_package.cpp b/src/tests/common/param_package.cpp
index d036cc83a1..41575def44 100644
--- a/src/tests/common/param_package.cpp
+++ b/src/tests/common/param_package.cpp
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: 2017 Citra Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 #include <math.h>
 #include "common/logging/backend.h"
 #include "common/param_package.h"
diff --git a/src/tests/common/range_map.cpp b/src/tests/common/range_map.cpp
index 5a4630a381..d301ac5f63 100644
--- a/src/tests/common/range_map.cpp
+++ b/src/tests/common/range_map.cpp
@@ -3,7 +3,7 @@
 
 #include <stdexcept>
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/range_map.h"
 
diff --git a/src/tests/common/ring_buffer.cpp b/src/tests/common/ring_buffer.cpp
index 4f81b6e5e6..7dee988c8d 100644
--- a/src/tests/common/ring_buffer.cpp
+++ b/src/tests/common/ring_buffer.cpp
@@ -7,7 +7,7 @@
 #include <numeric>
 #include <thread>
 #include <vector>
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 #include "common/ring_buffer.h"
 
 namespace Common {
diff --git a/src/tests/common/scratch_buffer.cpp b/src/tests/common/scratch_buffer.cpp
index f6e50da4a4..132f139fa8 100644
--- a/src/tests/common/scratch_buffer.cpp
+++ b/src/tests/common/scratch_buffer.cpp
@@ -5,7 +5,7 @@
 #include <array>
 #include <cstring>
 #include <span>
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 #include "common/common_types.h"
 #include "common/scratch_buffer.h"
 
diff --git a/src/tests/common/unique_function.cpp b/src/tests/common/unique_function.cpp
index 3112725068..f7a23e876d 100644
--- a/src/tests/common/unique_function.cpp
+++ b/src/tests/common/unique_function.cpp
@@ -3,7 +3,7 @@
 
 #include <string>
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/unique_function.h"
 
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index 284b2ae66f..f08afbf9ab 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: 2016 Dolphin Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include <array>
 #include <bitset>
diff --git a/src/tests/core/internal_network/network.cpp b/src/tests/core/internal_network/network.cpp
index 164b0ff245..10ddd8b426 100644
--- a/src/tests/core/internal_network/network.cpp
+++ b/src/tests/core/internal_network/network.cpp
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "core/internal_network/network.h"
 #include "core/internal_network/sockets.h"
diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp
index e5f6988867..516ff1b302 100644
--- a/src/tests/input_common/calibration_configuration_job.cpp
+++ b/src/tests/input_common/calibration_configuration_job.cpp
@@ -6,7 +6,7 @@
 #include <thread>
 #include <boost/asio.hpp>
 #include <boost/crc.hpp>
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "input_common/drivers/udp_client.h"
 #include "input_common/helpers/udp_protocol.h"
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
deleted file mode 100644
index 3f905c05ca..0000000000
--- a/src/tests/tests.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#define CATCH_CONFIG_MAIN
-#include <catch2/catch.hpp>
-
-// Catch provides the main function since we've given it the
-// CATCH_CONFIG_MAIN preprocessor directive.
diff --git a/src/tests/video_core/buffer_base.cpp b/src/tests/video_core/buffer_base.cpp
index 5cd0628f22..1275cca242 100644
--- a/src/tests/video_core/buffer_base.cpp
+++ b/src/tests/video_core/buffer_base.cpp
@@ -4,7 +4,7 @@
 #include <stdexcept>
 #include <unordered_map>
 
-#include <catch2/catch.hpp>
+#include <catch2/catch_test_macros.hpp>
 
 #include "common/alignment.h"
 #include "common/common_types.h"
diff --git a/vcpkg.json b/vcpkg.json
index 3c92510d60..ef271f778a 100644
--- a/vcpkg.json
+++ b/vcpkg.json
@@ -40,7 +40,7 @@
     "overrides": [
         {
             "name": "catch2",
-            "version": "2.13.9"
+            "version": "3.0.1"
         },
         {
             "name": "fmt",