diff --git a/src/common/scratch_buffer.h b/src/common/scratch_buffer.h
index afbe2eee13..59bb8a9ea9 100644
--- a/src/common/scratch_buffer.h
+++ b/src/common/scratch_buffer.h
@@ -19,16 +19,16 @@ public:
     ScratchBuffer() = default;
 
     explicit ScratchBuffer(size_t initial_capacity)
-        : last_requested_size{initial_capacity}, capacity{initial_capacity},
+        : last_requested_size{initial_capacity}, buffer_capacity{initial_capacity},
           buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
 
     ~ScratchBuffer() = default;
 
     /// This will only grow the buffer's capacity if size is greater than the current capacity.
     void resize(size_t size) {
-        if (size > capacity) {
-            capacity = size;
-            buffer = Common::make_unique_for_overwrite<T[]>(capacity);
+        if (size > buffer_capacity) {
+            buffer_capacity = size;
+            buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity);
         }
         last_requested_size = size;
     }
@@ -65,9 +65,13 @@ public:
         return last_requested_size;
     }
 
+    [[nodiscard]] size_t capacity() const noexcept {
+        return buffer_capacity;
+    }
+
 private:
     size_t last_requested_size{};
-    size_t capacity{};
+    size_t buffer_capacity{};
     std::unique_ptr<T[]> buffer{};
 };
 
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 348d1edf40..6a4022e456 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -8,6 +8,7 @@ add_executable(tests
     common/host_memory.cpp
     common/param_package.cpp
     common/ring_buffer.cpp
+    common/scratch_buffer.cpp
     common/unique_function.cpp
     core/core_timing.cpp
     core/internal_network/network.cpp
diff --git a/src/tests/common/scratch_buffer.cpp b/src/tests/common/scratch_buffer.cpp
new file mode 100644
index 0000000000..a59490f559
--- /dev/null
+++ b/src/tests/common/scratch_buffer.cpp
@@ -0,0 +1,127 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <algorithm>
+#include <array>
+#include <span>
+#include <catch2/catch.hpp>
+#include "common/common_types.h"
+#include "common/scratch_buffer.h"
+
+namespace Common {
+
+TEST_CASE("ScratchBuffer: Basic Test", "[common]") {
+    ScratchBuffer<u8> buf;
+
+    REQUIRE(buf.size() == 0U);
+    REQUIRE(buf.capacity() == 0U);
+
+    std::array<u8, 10> payload;
+    payload.fill(66);
+
+    buf.resize(payload.size());
+    REQUIRE(buf.size() == payload.size());
+    REQUIRE(buf.capacity() == payload.size());
+
+    std::memcpy(buf.data(), payload.data(), payload.size());
+    for (size_t i = 0; i < payload.size(); ++i) {
+        REQUIRE(buf[i] == payload[i]);
+    }
+}
+
+TEST_CASE("ScratchBuffer: Resize Grow", "[common]") {
+    std::array<u8, 10> payload;
+    payload.fill(66);
+
+    ScratchBuffer<u8> buf(payload.size());
+    REQUIRE(buf.size() == payload.size());
+    REQUIRE(buf.capacity() == payload.size());
+
+    // Increasing the size should reallocate the buffer
+    buf.resize(payload.size() * 2);
+    REQUIRE(buf.size() == payload.size() * 2);
+    REQUIRE(buf.capacity() == payload.size() * 2);
+
+    // Since the buffer is not value initialized, reading its data will be garbage
+}
+
+TEST_CASE("ScratchBuffer: Resize Shrink", "[common]") {
+    std::array<u8, 10> payload;
+    payload.fill(66);
+
+    ScratchBuffer<u8> buf(payload.size());
+    REQUIRE(buf.size() == payload.size());
+    REQUIRE(buf.capacity() == payload.size());
+
+    std::memcpy(buf.data(), payload.data(), payload.size());
+    for (size_t i = 0; i < payload.size(); ++i) {
+        REQUIRE(buf[i] == payload[i]);
+    }
+
+    // Decreasing the size should not cause a buffer reallocation
+    // This can be tested by ensuring the buffer capacity and data has not changed,
+    buf.resize(1U);
+    REQUIRE(buf.size() == 1U);
+    REQUIRE(buf.capacity() == payload.size());
+
+    for (size_t i = 0; i < payload.size(); ++i) {
+        REQUIRE(buf[i] == payload[i]);
+    }
+}
+
+TEST_CASE("ScratchBuffer: Span Size", "[common]") {
+    std::array<u8, 10> payload;
+    payload.fill(66);
+
+    ScratchBuffer<u8> buf(payload.size());
+    REQUIRE(buf.size() == payload.size());
+    REQUIRE(buf.capacity() == payload.size());
+
+    std::memcpy(buf.data(), payload.data(), payload.size());
+    for (size_t i = 0; i < payload.size(); ++i) {
+        REQUIRE(buf[i] == payload[i]);
+    }
+
+    buf.resize(3U);
+    REQUIRE(buf.size() == 3U);
+    REQUIRE(buf.capacity() == payload.size());
+
+    const auto buf_span = std::span<u8>(buf);
+    // The span size is the last requested size of the buffer, not its capacity
+    REQUIRE(buf_span.size() == buf.size());
+
+    for (size_t i = 0; i < buf_span.size(); ++i) {
+        REQUIRE(buf_span[i] == buf[i]);
+        REQUIRE(buf_span[i] == payload[i]);
+    }
+}
+
+TEST_CASE("ScratchBuffer: Span Writes", "[common]") {
+    std::array<u8, 10> payload;
+    payload.fill(66);
+
+    ScratchBuffer<u8> buf(payload.size());
+    REQUIRE(buf.size() == payload.size());
+    REQUIRE(buf.capacity() == payload.size());
+
+    std::memcpy(buf.data(), payload.data(), payload.size());
+    for (size_t i = 0; i < payload.size(); ++i) {
+        REQUIRE(buf[i] == payload[i]);
+    }
+
+    buf.resize(3U);
+    REQUIRE(buf.size() == 3U);
+    REQUIRE(buf.capacity() == payload.size());
+
+    const auto buf_span = std::span<u8>(buf);
+    REQUIRE(buf_span.size() == buf.size());
+
+    for (size_t i = 0; i < buf_span.size(); ++i) {
+        const auto new_value = static_cast<u8>(i + 1U);
+        // Writes to a span of the scratch buffer will propogate to the buffer itself
+        buf_span[i] = new_value;
+        REQUIRE(buf[i] == new_value);
+    }
+}
+
+} // namespace Common