diff --git a/.gn b/.gn
index b9586c7fce69ea..f844fd20e9b87d 100644
--- a/.gn
+++ b/.gn
@@ -25,6 +25,7 @@ script_executable = "python3"
 
 default_args = {
   pw_unit_test_AUTOMATIC_RUNNER = "$dir_pigweed/targets/host/run_test"
+  pw_unit_test_CONFIG = "//config/pw_unit_test:define_overrides"
 
   pw_build_PIP_CONSTRAINTS = [ "//scripts/setup/constraints.txt" ]
   pw_build_PIP_REQUIREMENTS = [ "//scripts/setup/requirements.build.txt" ]
diff --git a/config/pw_unit_test/BUILD.gn b/config/pw_unit_test/BUILD.gn
new file mode 100644
index 00000000000000..20889115f74538
--- /dev/null
+++ b/config/pw_unit_test/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/chip.gni")
+import("//build_overrides/pigweed.gni")
+
+import("${chip_root}/build/chip/tests.gni")
+
+import("$dir_pw_build/target_types.gni")
+pw_source_set("define_overrides") {
+  public_configs = [ ":define_options" ]
+}
+
+config("define_options") {
+  if (chip_fake_platform && chip_link_tests) {
+    defines = [ "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE=65536" ]
+  } else {
+    defines = [ "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE=16384" ]
+  }
+}
diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn
index 89f0934486b9c1..3232796aabe7e1 100644
--- a/src/messaging/tests/BUILD.gn
+++ b/src/messaging/tests/BUILD.gn
@@ -14,7 +14,6 @@
 
 import("//build_overrides/build.gni")
 import("//build_overrides/chip.gni")
-import("//build_overrides/nlunit_test.gni")
 
 import("${chip_root}/build/chip/chip_test_suite.gni")
 import("${chip_root}/src/app/icd/icd.gni")
@@ -38,15 +37,9 @@ static_library("helpers") {
     "${chip_root}/src/transport",
     "${chip_root}/src/transport/tests:helpers",
   ]
-
-  # MessagingContext exposes nl-test compatible setup/teardown functions, specifically
-  # they return nltest specific SUCCESS/FAILURE constants hence this dependency.
-  #
-  # Once all tests are moved to pw_unittest/gtest, this dependency should be removed
-  public_deps = [ "${nlunit_test_root}:nlunit-test" ]
 }
 
-chip_test_suite_using_nltest("tests") {
+chip_test_suite("tests") {
   output_name = "libMessagingLayerTests"
 
   test_sources = [
@@ -73,12 +66,10 @@ chip_test_suite_using_nltest("tests") {
     "${chip_root}/src/lib/core",
     "${chip_root}/src/lib/support",
     "${chip_root}/src/lib/support:test_utils",
-    "${chip_root}/src/lib/support:testing_nlunit",
     "${chip_root}/src/messaging",
     "${chip_root}/src/protocols",
     "${chip_root}/src/transport",
     "${chip_root}/src/transport/raw/tests:helpers",
-    "${nlunit_test_root}:nlunit-test",
   ]
 
   if (chip_enable_icd_server) {
diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h
index ab9912924e713c..bd9b0b981926e6 100644
--- a/src/messaging/tests/MessagingContext.h
+++ b/src/messaging/tests/MessagingContext.h
@@ -32,8 +32,6 @@
 #include <transport/tests/LoopbackTransportManager.h>
 #include <transport/tests/UDPTransportManager.h>
 
-#include <nlunit-test.h>
-
 #include <vector>
 
 namespace chip {
@@ -98,6 +96,8 @@ class MessagingContext : public PlatformMemoryUser
         mInitialized(false), mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)),
         mBobAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT))
     {}
+    // TODO Replace VerifyOrDie with Pigweed assert after transition app/tests to Pigweed.
+    // TODO Currently src/app/icd/server/tests is using MessagingConetext as dependency.
     ~MessagingContext() { VerifyOrDie(mInitialized == false); }
 
     // Whether Alice and Bob are initialized, must be called before Init
diff --git a/src/messaging/tests/TestAbortExchangesForFabric.cpp b/src/messaging/tests/TestAbortExchangesForFabric.cpp
index d5c945c848a9aa..8f8eb825553bf5 100644
--- a/src/messaging/tests/TestAbortExchangesForFabric.cpp
+++ b/src/messaging/tests/TestAbortExchangesForFabric.cpp
@@ -21,10 +21,9 @@
  *      one) for a fabric.
  */
 
+#include <gtest/gtest.h>
+
 #include <app/icd/server/ICDServerConfig.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <lib/support/UnitTestUtils.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeMgr.h>
 #include <messaging/ReliableMessageProtocolConfig.h>
@@ -49,16 +48,23 @@ using namespace chip::System;
 using namespace chip::System::Clock::Literals;
 using namespace chip::Protocols;
 
-struct TestContext : Test::LoopbackMessagingContext
+struct TestAbortExchangesForFabric : public chip::Test::LoopbackMessagingContext, public ::testing::Test
 {
+    static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); }
+
+    static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); }
+
     void SetUp() override
     {
 #if CHIP_CRYPTO_PSA
-        // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete
-        VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
+        ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS);
 #endif
         chip::Test::LoopbackMessagingContext::SetUp();
     }
+
+    void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); }
+
+    void CommonCheckAbortAllButOneExchange(bool dropResponseMessages);
 };
 
 class MockAppDelegate : public ExchangeDelegate
@@ -76,57 +82,57 @@ class MockAppDelegate : public ExchangeDelegate
     bool mOnMessageReceivedCalled = false;
 };
 
-void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx, bool dropResponseMessages)
+void TestAbortExchangesForFabric::CommonCheckAbortAllButOneExchange(bool dropResponseMessages)
 {
     // We want to have two sessions using the same fabric id that we use for
     // creating our exchange contexts.  That lets us test exchanges on the same
     // session as the "special exchange" as well as on other sessions.
-    auto & sessionManager = ctx.GetSecureSessionManager();
+    auto & sessionManager = GetSecureSessionManager();
 
     // Use key ids that are not going to collide with anything else that ctx is
     // doing.
     // TODO: These should really be CASE sessions...
     SessionHolder session1;
-    CHIP_ERROR err = sessionManager.InjectCaseSessionWithTestKey(session1, 100, 101, ctx.GetAliceFabric()->GetNodeId(),
-                                                                 ctx.GetBobFabric()->GetNodeId(), ctx.GetAliceFabricIndex(),
-                                                                 ctx.GetBobAddress(), CryptoContext::SessionRole::kInitiator, {});
+    CHIP_ERROR err = sessionManager.InjectCaseSessionWithTestKey(session1, 100, 101, GetAliceFabric()->GetNodeId(),
+                                                                 GetBobFabric()->GetNodeId(), GetAliceFabricIndex(),
+                                                                 GetBobAddress(), CryptoContext::SessionRole::kInitiator, {});
 
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     SessionHolder session1Reply;
-    err = sessionManager.InjectCaseSessionWithTestKey(session1Reply, 101, 100, ctx.GetBobFabric()->GetNodeId(),
-                                                      ctx.GetAliceFabric()->GetNodeId(), ctx.GetBobFabricIndex(),
-                                                      ctx.GetAliceAddress(), CryptoContext::SessionRole::kResponder, {});
+    err = sessionManager.InjectCaseSessionWithTestKey(session1Reply, 101, 100, GetBobFabric()->GetNodeId(),
+                                                      GetAliceFabric()->GetNodeId(), GetBobFabricIndex(), GetAliceAddress(),
+                                                      CryptoContext::SessionRole::kResponder, {});
 
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // TODO: Ideally this would go to a different peer, but we don't have that
     // set up right now: only Alice and Bob have useful node ids and whatnot.
     SessionHolder session2;
-    err = sessionManager.InjectCaseSessionWithTestKey(session2, 200, 201, ctx.GetAliceFabric()->GetNodeId(),
-                                                      ctx.GetBobFabric()->GetNodeId(), ctx.GetAliceFabricIndex(),
-                                                      ctx.GetBobAddress(), CryptoContext::SessionRole::kInitiator, {});
+    err = sessionManager.InjectCaseSessionWithTestKey(session2, 200, 201, GetAliceFabric()->GetNodeId(),
+                                                      GetBobFabric()->GetNodeId(), GetAliceFabricIndex(), GetBobAddress(),
+                                                      CryptoContext::SessionRole::kInitiator, {});
 
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     SessionHolder session2Reply;
-    err = sessionManager.InjectCaseSessionWithTestKey(session2Reply, 101, 100, ctx.GetBobFabric()->GetNodeId(),
-                                                      ctx.GetAliceFabric()->GetNodeId(), ctx.GetBobFabricIndex(),
-                                                      ctx.GetAliceAddress(), CryptoContext::SessionRole::kResponder, {});
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = sessionManager.InjectCaseSessionWithTestKey(session2Reply, 101, 100, GetBobFabric()->GetNodeId(),
+                                                      GetAliceFabric()->GetNodeId(), GetBobFabricIndex(), GetAliceAddress(),
+                                                      CryptoContext::SessionRole::kResponder, {});
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    auto & exchangeMgr = ctx.GetExchangeManager();
+    auto & exchangeMgr = GetExchangeManager();
 
     MockAppDelegate delegate;
     Echo::EchoServer server;
     err = server.Init(&exchangeMgr);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    auto & loopback = ctx.GetLoopback();
+    auto & loopback = GetLoopback();
 
     auto trySendMessage = [&](ExchangeContext * exchange, SendMessageFlags flags) {
         PacketBufferHandle buffer = MessagePacketBuffer::New(0);
-        NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+        EXPECT_FALSE(buffer.IsNull());
         return exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), flags);
     };
 
@@ -137,79 +143,81 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx,
         loopback.mDroppedMessageCount = 0;
 
         err = trySendMessage(exchange, flags);
-        NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled);
-        NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
+        DrainAndServiceIO();
+        EXPECT_FALSE(delegate.mOnMessageReceivedCalled);
+        EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
     };
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
 
     // We want to test three possible exchange states:
     // 1) Closed but waiting for ack.
     // 2) Waiting for a response.
     // 3) Waiting for a send.
     auto * waitingForAck1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForAck1 != nullptr);
+    ASSERT_NE(waitingForAck1, nullptr);
     sendAndDropMessage(waitingForAck1, SendMessageFlags::kNone);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     auto * waitingForAck2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForAck2 != nullptr);
+    ASSERT_NE(waitingForAck2, nullptr);
     sendAndDropMessage(waitingForAck2, SendMessageFlags::kNone);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 2);
 
     auto * waitingForIncomingMessage1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForIncomingMessage1 != nullptr);
+    ASSERT_NE(waitingForIncomingMessage1, nullptr);
     sendAndDropMessage(waitingForIncomingMessage1, SendMessageFlags::kExpectResponse);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 3);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 3);
 
     auto * waitingForIncomingMessage2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForIncomingMessage2 != nullptr);
+    ASSERT_NE(waitingForIncomingMessage2, nullptr);
     sendAndDropMessage(waitingForIncomingMessage2, SendMessageFlags::kExpectResponse);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 4);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 4);
 
     auto * waitingForSend1 = exchangeMgr.NewContext(session1.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForSend1 != nullptr);
+    ASSERT_NE(waitingForSend1, nullptr);
     waitingForSend1->WillSendMessage();
 
     auto * waitingForSend2 = exchangeMgr.NewContext(session2.Get().Value(), &delegate);
-    NL_TEST_ASSERT(inSuite, waitingForSend2 != nullptr);
+    ASSERT_NE(waitingForSend2, nullptr);
     waitingForSend2->WillSendMessage();
 
     // Grab handles to our sessions now, before we evict things.
     const auto & sessionHandle1 = session1.Get();
     const auto & sessionHandle2 = session2.Get();
 
-    session1->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
-        Test::MessagingContext::kResponsiveIdleRetransTimeout, Test::MessagingContext::kResponsiveActiveRetransTimeout));
+    session1->AsSecureSession()->SetRemoteSessionParameters(
+        ReliableMessageProtocolConfig(chip::Test::MessagingContext::kResponsiveIdleRetransTimeout,
+                                      chip::Test::MessagingContext::kResponsiveActiveRetransTimeout));
 
-    session1Reply->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig(
-        Test::MessagingContext::kResponsiveIdleRetransTimeout, Test::MessagingContext::kResponsiveActiveRetransTimeout));
+    session1Reply->AsSecureSession()->SetRemoteSessionParameters(
+        ReliableMessageProtocolConfig(chip::Test::MessagingContext::kResponsiveIdleRetransTimeout,
+                                      chip::Test::MessagingContext::kResponsiveActiveRetransTimeout));
 
-    NL_TEST_ASSERT(inSuite, session1);
-    NL_TEST_ASSERT(inSuite, session2);
+    EXPECT_TRUE(session1);
+    EXPECT_TRUE(session2);
     auto * specialExhange = exchangeMgr.NewContext(session1.Get().Value(), &delegate);
     specialExhange->AbortAllOtherCommunicationOnFabric();
 
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
-    NL_TEST_ASSERT(inSuite, !session1);
-    NL_TEST_ASSERT(inSuite, !session2);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
+    EXPECT_FALSE(session1);
+    EXPECT_FALSE(session2);
 
-    NL_TEST_ASSERT(inSuite, exchangeMgr.NewContext(sessionHandle1.Value(), &delegate) == nullptr);
-    NL_TEST_ASSERT(inSuite, exchangeMgr.NewContext(sessionHandle2.Value(), &delegate) == nullptr);
+    EXPECT_EQ(exchangeMgr.NewContext(sessionHandle1.Value(), &delegate), nullptr);
+    EXPECT_EQ(exchangeMgr.NewContext(sessionHandle2.Value(), &delegate), nullptr);
 
     // Make sure we can't send messages on any of the other exchanges.
-    NL_TEST_ASSERT(inSuite, trySendMessage(waitingForSend1, SendMessageFlags::kExpectResponse) != CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, trySendMessage(waitingForSend2, SendMessageFlags::kExpectResponse) != CHIP_NO_ERROR);
+    EXPECT_NE(trySendMessage(waitingForSend1, SendMessageFlags::kExpectResponse), CHIP_NO_ERROR);
+    EXPECT_NE(trySendMessage(waitingForSend2, SendMessageFlags::kExpectResponse), CHIP_NO_ERROR);
 
     // Make sure we can send a message on the special exchange.
-    NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled);
+    EXPECT_FALSE(delegate.mOnMessageReceivedCalled);
     err = trySendMessage(specialExhange, SendMessageFlags::kNone);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     // Should be waiting for an ack now.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     if (dropResponseMessages)
     {
@@ -217,7 +225,7 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx,
         // This version of the test allows us to validate logic that marks expired sessions as defunct
         // on encountering an MRP failure.
         //
-        loopback.mNumMessagesToDrop   = Test::LoopbackTransport::kUnlimitedMessageCount;
+        loopback.mNumMessagesToDrop   = chip::Test::LoopbackTransport::kUnlimitedMessageCount;
         loopback.mDroppedMessageCount = 0;
 
         //
@@ -231,18 +239,18 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx,
         waitTimeout += ICDConfigurationData::GetInstance().GetFastPollingInterval();
 #endif
 
-        ctx.GetIOContext().DriveIOUntil(waitTimeout, [&]() { return false; });
+        GetIOContext().DriveIOUntil(waitTimeout, [&]() { return false; });
     }
     else
     {
-        ctx.DrainAndServiceIO();
+        DrainAndServiceIO();
     }
 
     // Should not get an app-level response, since we are not expecting one.
-    NL_TEST_ASSERT(inSuite, !delegate.mOnMessageReceivedCalled);
+    EXPECT_FALSE(delegate.mOnMessageReceivedCalled);
 
     // We should have gotten our ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     waitingForSend1->Close();
     waitingForSend2->Close();
@@ -251,43 +259,14 @@ void CommonCheckAbortAllButOneExchange(nlTestSuite * inSuite, TestContext & ctx,
     loopback.mDroppedMessageCount = 0;
 }
 
-void CheckAbortAllButOneExchange(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAbortExchangesForFabric, CheckAbortAllButOneExchange)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-    CommonCheckAbortAllButOneExchange(inSuite, ctx, false);
+    CommonCheckAbortAllButOneExchange(false);
 }
 
-void CheckAbortAllButOneExchangeResponseTimeout(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAbortExchangesForFabric, CheckAbortAllButOneExchangeResponseTimeout)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-    CommonCheckAbortAllButOneExchange(inSuite, ctx, true);
+    CommonCheckAbortAllButOneExchange(true);
 }
 
-const nlTest sTests[] = {
-    NL_TEST_DEF("Test aborting all but one exchange", CheckAbortAllButOneExchange),
-    NL_TEST_DEF("Test aborting all but one exchange + response timeout", CheckAbortAllButOneExchangeResponseTimeout),
-    NL_TEST_SENTINEL(),
-};
-
-// clang-format off
-nlTestSuite sSuite = {
-    "Test-AbortExchangesForFabric",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
 } // namespace
-
-/**
- *  Main
- */
-int TestAbortExchangesForFabric()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAbortExchangesForFabric);
diff --git a/src/messaging/tests/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp
index fbc1c9e505204d..7c0257d3093d3f 100644
--- a/src/messaging/tests/TestExchange.cpp
+++ b/src/messaging/tests/TestExchange.cpp
@@ -14,12 +14,14 @@
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+#include <errno.h>
+#include <utility>
+
+#include <gtest/gtest.h>
 
 #include <lib/core/CHIPCore.h>
 #include <lib/support/CHIPMem.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeMgr.h>
 #include <messaging/Flags.h>
@@ -28,12 +30,6 @@
 #include <transport/SessionManager.h>
 #include <transport/TransportMgr.h>
 
-#include <nlbyteorder.h>
-#include <nlunit-test.h>
-
-#include <errno.h>
-#include <utility>
-
 #if CHIP_CRYPTO_PSA
 #include "psa/crypto.h"
 #endif
@@ -45,18 +41,30 @@ using namespace chip::Inet;
 using namespace chip::Transport;
 using namespace chip::Messaging;
 
-struct TestContext : Test::LoopbackMessagingContext
+class MockExchangeDelegate;
+
+struct TestExchange : public Test::LoopbackMessagingContext, public ::testing::Test
 {
     // TODO Add TearDown function when changing test framework to Pigweed to make it more clear how it works.
     // Currently, the TearDown function is from LoopbackMessagingContext
     void SetUp() override
     {
 #if CHIP_CRYPTO_PSA
-        // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete
-        VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
+        ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS);
 #endif
         chip::Test::LoopbackMessagingContext::SetUp();
     }
+
+    void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); }
+
+    static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); }
+
+    static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); }
+
+    template <typename AfterRequestChecker, typename AfterResponseChecker>
+    void DoRoundTripTest(MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, uint8_t requestMessageType,
+                         uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker,
+                         AfterResponseChecker && afterResponseChecker);
 };
 
 enum : uint8_t
@@ -113,18 +121,16 @@ class MockExchangeDelegate : public UnsolicitedMessageHandler, public ExchangeDe
 // handler, sends a message of type requestMessageType via an exchange that has
 // delegate1 as delegate, responds with responseMessageType.
 template <typename AfterRequestChecker, typename AfterResponseChecker>
-void DoRoundTripTest(nlTestSuite * inSuite, void * inContext, MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2,
-                     uint8_t requestMessageType, uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker,
-                     AfterResponseChecker && afterResponseChecker)
+void TestExchange::DoRoundTripTest(MockExchangeDelegate & delegate1, MockExchangeDelegate & delegate2, uint8_t requestMessageType,
+                                   uint8_t responseMessageType, AfterRequestChecker && afterRequestChecker,
+                                   AfterResponseChecker && afterResponseChecker)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
-    ExchangeContext * ec1 = ctx.NewExchangeToBob(&delegate1);
-    NL_TEST_ASSERT(inSuite, ec1 != nullptr);
+    ExchangeContext * ec1 = NewExchangeToBob(&delegate1);
+    ASSERT_NE(ec1, nullptr);
 
-    CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id,
-                                                                                       requestMessageType, &delegate2);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    CHIP_ERROR err =
+        GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, requestMessageType, &delegate2);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // To simplify things, skip MRP for all our messages, and make sure we are
     // always expecting responses.
@@ -133,45 +139,45 @@ void DoRoundTripTest(nlTestSuite * inSuite, void * inContext, MockExchangeDelega
 
     err = ec1->SendMessage(Protocols::SecureChannel::Id, requestMessageType,
                            System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), sendFlags);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     afterRequestChecker();
 
     ExchangeContext * ec2 = delegate2.mExchange;
     err                   = ec2->SendMessage(Protocols::SecureChannel::Id, responseMessageType,
                                              System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize), sendFlags);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     afterResponseChecker();
 
     ec1->Close();
     ec2->Close();
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, kMsgType_TEST1);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::SecureChannel::Id, kMsgType_TEST1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 }
 
-void CheckBasicMessageRoundTrip(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchange, CheckBasicMessageRoundTrip)
 {
     MockExchangeDelegate delegate1;
     MockExchangeDelegate delegate2;
     DoRoundTripTest(
-        inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2,
+        delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2,
         [&] {
-            NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0);
-            NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+            EXPECT_EQ(delegate1.mReceivedMessageCount, 0u);
+            EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
         },
         [&] {
-            NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 1);
-            NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+            EXPECT_EQ(delegate1.mReceivedMessageCount, 1u);
+            EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
         });
 }
 
-void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchange, CheckBasicExchangeMessageDispatch)
 {
     class MockMessageDispatch : public ExchangeMessageDispatch
     {
@@ -191,14 +197,14 @@ void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext)
         MockExchangeDelegate delegate2;
 
         DoRoundTripTest(
-            inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST1,
+            delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST1,
             [&] {
-                NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0);
-                NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+                EXPECT_EQ(delegate1.mReceivedMessageCount, 0u);
+                EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
             },
             [&] {
-                NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 1);
-                NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+                EXPECT_EQ(delegate1.mReceivedMessageCount, 1u);
+                EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
             });
     }
 
@@ -209,53 +215,15 @@ void CheckBasicExchangeMessageDispatch(nlTestSuite * inSuite, void * inContext)
         MockExchangeDelegate delegate2;
 
         DoRoundTripTest(
-            inSuite, inContext, delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2,
+            delegate1, delegate2, kMsgType_TEST1, kMsgType_TEST2,
             [&] {
-                NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0);
-                NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+                EXPECT_EQ(delegate1.mReceivedMessageCount, 0u);
+                EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
             },
             [&] {
-                NL_TEST_ASSERT(inSuite, delegate1.mReceivedMessageCount == 0);
-                NL_TEST_ASSERT(inSuite, delegate2.mReceivedMessageCount == 1);
+                EXPECT_EQ(delegate1.mReceivedMessageCount, 0u);
+                EXPECT_EQ(delegate2.mReceivedMessageCount, 1u);
             });
     }
 }
-
-// Test Suite
-
-/**
- *  Test Suite that lists all the test functions.
- */
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("Test ExchangeContext::SendMessage", CheckBasicMessageRoundTrip),
-    NL_TEST_DEF("Test ExchangeMessageDispatch", CheckBasicExchangeMessageDispatch),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "Test-Exchange",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
 } // namespace
-
-/**
- *  Main
- */
-int TestExchange()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestExchange);
diff --git a/src/messaging/tests/TestExchangeHolder.cpp b/src/messaging/tests/TestExchangeHolder.cpp
index 849c1856d9b013..35f0856cfede24 100644
--- a/src/messaging/tests/TestExchangeHolder.cpp
+++ b/src/messaging/tests/TestExchangeHolder.cpp
@@ -21,11 +21,10 @@
  *      one) for a fabric.
  */
 
+#include <gtest/gtest.h>
+
 #include "messaging/ExchangeDelegate.h"
 #include "system/SystemClock.h"
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <lib/support/UnitTestUtils.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeHolder.h>
 #include <messaging/ExchangeMgr.h>
@@ -69,9 +68,16 @@ using namespace chip::Messaging;
 using namespace chip::System;
 using namespace chip::Protocols;
 
-using TestContext = Test::LoopbackMessagingContext;
+struct TestExchangeHolder : public chip::Test::LoopbackMessagingContext, public ::testing::Test
+{
+    static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); }
+
+    static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); }
 
-TestContext * gCtx = nullptr;
+    void SetUp() override { chip::Test::LoopbackMessagingContext::SetUp(); }
+
+    void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); }
+};
 
 class MockProtocolResponder : public ExchangeDelegate, public Messaging::UnsolicitedMessageHandler
 {
@@ -87,26 +93,27 @@ class MockProtocolResponder : public ExchangeDelegate, public Messaging::Unsolic
     };
 
     template <typename... Args>
-    MockProtocolResponder(BehaviorModifier modifier1, Args &&... args) :
-        mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward<Args>(args)...)
+    MockProtocolResponder(TestExchangeHolder & ctx, BehaviorModifier modifier1, Args &&... args) :
+        mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward<Args>(args)...), testExchangeHolder(ctx)
     {
-        VerifyOrDie(gCtx != nullptr);
-        gCtx->GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, this);
+        testExchangeHolder.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id,
+                                                                                             this);
         ChipLogDetail(ExchangeManager, "[%p] MockProtocolResponder: %p", this, &mExchangeCtx);
     }
 
-    MockProtocolResponder(BehaviorModifier modifier = BehaviorModifier::kNone) : mExchangeCtx(*this)
+    MockProtocolResponder(TestExchangeHolder & ctx, BehaviorModifier modifier = BehaviorModifier::kNone) :
+        mExchangeCtx(*this), testExchangeHolder(ctx)
     {
-        VerifyOrDie(gCtx != nullptr);
         mBehaviorModifier.Set(modifier);
-        gCtx->GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id, this);
+        testExchangeHolder.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id,
+                                                                                             this);
         ChipLogDetail(ExchangeManager, "[%p] MockProtocolResponder: %p", this, &mExchangeCtx);
     }
 
     ~MockProtocolResponder()
     {
         ChipLogDetail(ExchangeManager, "[%p] ~MockProtocolResponder", this);
-        gCtx->GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id);
+        testExchangeHolder.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(chip::Protocols::MockProtocol::Id);
     }
 
     bool DidInteractionSucceed() { return mInteractionSucceeded; }
@@ -126,6 +133,7 @@ class MockProtocolResponder : public ExchangeDelegate, public Messaging::Unsolic
     ExchangeHolder mExchangeCtx;
     BitFlags<BehaviorModifier> mBehaviorModifier = BehaviorModifier::kNone;
     bool mInteractionSucceeded                   = false;
+    TestExchangeHolder & testExchangeHolder;
 };
 
 class MockProtocolInitiator : public ExchangeDelegate
@@ -144,15 +152,16 @@ class MockProtocolInitiator : public ExchangeDelegate
         kExpireSessionAfterMsg3Send  = 0x18,
     };
 
-    MockProtocolInitiator(BehaviorModifier modifier = BehaviorModifier::kNone) : mExchangeCtx(*this)
+    MockProtocolInitiator(TestExchangeHolder & ctx, BehaviorModifier modifier = BehaviorModifier::kNone) :
+        mExchangeCtx(*this), testExchangeHolder(ctx)
     {
         mBehaviorModifier.Set(modifier);
         ChipLogDetail(ExchangeManager, "[%p] MockProtocolInitiator: %p", this, &mExchangeCtx);
     }
 
     template <typename... Args>
-    MockProtocolInitiator(BehaviorModifier modifier1, Args &&... args) :
-        mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward<Args>(args)...)
+    MockProtocolInitiator(TestExchangeHolder & ctx, BehaviorModifier modifier1, Args &&... args) :
+        mExchangeCtx(*this), mBehaviorModifier(modifier1, std::forward<Args>(args)...), testExchangeHolder(ctx)
     {
         ChipLogDetail(ExchangeManager, "[%p] MockProtocolInitiator: %p", this, &mExchangeCtx);
     }
@@ -172,6 +181,7 @@ class MockProtocolInitiator : public ExchangeDelegate
     ExchangeHolder mExchangeCtx;
     BitFlags<BehaviorModifier> mBehaviorModifier = BehaviorModifier::kNone;
     bool mInteractionSucceeded                   = false;
+    TestExchangeHolder & testExchangeHolder;
 };
 
 CHIP_ERROR MockProtocolResponder::OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader,
@@ -248,7 +258,7 @@ CHIP_ERROR MockProtocolInitiator::StartInteraction(SessionHandle & sessionHandle
     PacketBufferHandle buffer = MessagePacketBuffer::New(0);
     VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY);
 
-    auto exchange = gCtx->GetExchangeManager().NewContext(sessionHandle, this);
+    auto exchange = testExchangeHolder.GetExchangeManager().NewContext(sessionHandle, this);
     VerifyOrReturnError(exchange != nullptr, CHIP_ERROR_NO_MEMORY);
 
     //
@@ -344,15 +354,11 @@ CHIP_ERROR MockProtocolInitiator::OnMessageReceived(ExchangeContext * ec, const
     return err;
 }
 
-void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeHolder, TestExchangeHolder)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
-    gCtx = &ctx;
+    auto sessionHandle = GetSessionAliceToBob();
 
-    auto sessionHandle = ctx.GetSessionAliceToBob();
-
-    ctx.SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);
+    SetMRPMode(chip::Test::MessagingContext::MRPMode::kResponsive);
 
     //
     // #1: Initiator (AllocExchange)
@@ -366,14 +372,14 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         ChipLogProgress(ExchangeManager, "-------- #1: Initiator (AllocExchange) ----------");
 
         {
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kDontSendMsg1);
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kDontSendMsg1);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -389,19 +395,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         ChipLogProgress(ExchangeManager, "-------- #2: Initiator --X (SendErr) Msg1 --------- ");
 
         {
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kErrMsg1);
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kErrMsg1);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+            EXPECT_NE(err, CHIP_NO_ERROR);
         }
 
         //
         // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also
         // flush any pending messages in the queue.
         //
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        DrainAndServiceIO();
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -417,19 +423,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         ChipLogProgress(ExchangeManager, "-------- #3: Initiator --X (SessionReleased before) Msg1 --------- ");
 
         {
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg1Send);
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg1Send);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+            EXPECT_NE(err, CHIP_NO_ERROR);
         }
 
         //
         // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also
         // flush any pending messages in the queue.
         //
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        DrainAndServiceIO();
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -445,20 +451,20 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         ChipLogProgress(ExchangeManager, "-------- #4: Initiator --X (SendErr + SessionReleased after) Msg1 --------- ");
 
         {
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg1Send,
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg1Send,
                                             MockProtocolInitiator::BehaviorModifier::kErrMsg1);
-            MockProtocolResponder responder;
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+            EXPECT_NE(err, CHIP_NO_ERROR);
         }
 
         //
         // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also
         // flush any pending messages in the queue.
         //
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        DrainAndServiceIO();
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -474,19 +480,19 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         ChipLogProgress(ExchangeManager, "-------- #5: Initiator >-- Msg1 --X Responder ---------");
 
         {
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
         }
 
         //
         // Service IO AFTER the objects above cease to exist to prevent Msg1 from getting to Responder. This also
         // flush any pending messages in the queue.
         //
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        DrainAndServiceIO();
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -502,16 +508,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #6: Initiator >-- Msg1 --> Responder (WillSend) ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kHoldMsg2);
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kHoldMsg2);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -529,16 +535,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #7: Msg2 (SendFailure) X-- Responder ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kErrMsg2);
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kErrMsg2);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -554,16 +560,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #8: Msg2 (SessionReleased Before) X-- Responder ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kExpireSessionBeforeMsg2Send);
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kExpireSessionBeforeMsg2Send);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -579,17 +585,17 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #9: Msg2 (SendErr + SessionReleased after) X-- Responder ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kErrMsg2,
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kErrMsg2,
                                             MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg2Send);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -605,16 +611,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #10: (WillSend) Initiator <-- Msg2 <-- Responder ---------");
 
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kHoldMsg3);
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kHoldMsg3);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -630,16 +636,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #11: Initiator --X (SessionReleased before) Msg3 ------------");
 
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg3Send);
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kExpireSessionBeforeMsg3Send);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+            EXPECT_NE(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -657,17 +663,17 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #12: Initiator --X (SendErr + SessionReleased after) Msg3 ------------");
 
-            MockProtocolInitiator initiator(MockProtocolInitiator::BehaviorModifier::kErrMsg3,
+            MockProtocolInitiator initiator(*this, MockProtocolInitiator::BehaviorModifier::kErrMsg3,
                                             MockProtocolInitiator::BehaviorModifier::kExpireSessionAfterMsg3Send);
-            MockProtocolResponder responder;
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -685,16 +691,16 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #13: Initiator >-- Msg3 -->  Responder ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -711,13 +717,13 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #14: Initiator >-- Msg3 -->  Responder (SessionReleased) ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg3Receive);
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kExpireSessionAfterMsg3Receive);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
 
             //
             // Because of the session expiration right after Msg3 is received, it causes an abort of the underlying EC
@@ -730,11 +736,11 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
             // entry has been removed. To make this happen, drive the IO forward enough that a single re-transmission happens. This
             // will result in a duplicate message ACK being delivered by the responder, causing the EC to finally get released.
             //
-            ctx.GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
-                                            [&]() { return ctx.GetExchangeManager().GetNumActiveExchanges() == 0; });
+            GetIOContext().DriveIOUntil(System::Clock::Seconds16(5),
+                                        [&]() { return GetExchangeManager().GetNumActiveExchanges() == 0; });
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -750,22 +756,22 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #15: Initiator >-- Msg1 -->  Responder (WillSend) X2 ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder(MockProtocolResponder::BehaviorModifier::kHoldMsg2);
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this, MockProtocolResponder::BehaviorModifier::kHoldMsg2);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
 
             err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        ctx.DrainAndServiceIO();
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        DrainAndServiceIO();
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 
     //
@@ -784,58 +790,21 @@ void TestExchangeHolder(nlTestSuite * inSuite, void * inContext)
         {
             ChipLogProgress(ExchangeManager, "-------- #16: Initiator >-- Msg3 -->  Responder X2 ---------");
 
-            MockProtocolInitiator initiator;
-            MockProtocolResponder responder;
+            MockProtocolInitiator initiator(*this);
+            MockProtocolResponder responder(*this);
 
             auto err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
 
             err = initiator.StartInteraction(sessionHandle);
-            NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
 
-            ctx.DrainAndServiceIO();
+            DrainAndServiceIO();
         }
 
-        NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
     }
 }
-
-// Test Suite
-
-/**
- *  Test Suite that lists all the test functions.
- */
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("TestExchangeHolder", TestExchangeHolder),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "Test-TestExchangeHolder",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
 } // anonymous namespace
-
-/**
- *  Main
- */
-int TestExchangeHolder()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestExchangeHolder);
diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp
index efca83e6d1a92a..975078ede9bd78 100644
--- a/src/messaging/tests/TestExchangeMgr.cpp
+++ b/src/messaging/tests/TestExchangeMgr.cpp
@@ -20,12 +20,14 @@
  *    @file
  *      This file implements unit tests for the ExchangeManager implementation.
  */
+#include <errno.h>
+#include <utility>
+
+#include <gtest/gtest.h>
 
 #include <lib/core/CHIPCore.h>
 #include <lib/support/CHIPMem.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeMgr.h>
 #include <messaging/Flags.h>
@@ -34,12 +36,6 @@
 #include <transport/SessionManager.h>
 #include <transport/TransportMgr.h>
 
-#include <nlbyteorder.h>
-#include <nlunit-test.h>
-
-#include <errno.h>
-#include <utility>
-
 #if CHIP_CRYPTO_PSA
 #include "psa/crypto.h"
 #endif
@@ -51,18 +47,21 @@ using namespace chip::Inet;
 using namespace chip::Transport;
 using namespace chip::Messaging;
 
-struct TestContext : Test::LoopbackMessagingContext
+struct TestExchangeMgr : public chip::Test::LoopbackMessagingContext, public ::testing::Test
 {
-    // TODO Add TearDown function during changing test framework to Pigweed to make it more clear how does it work.
-    // Currently, the TearDown function is from LoopbackMessagingContext
+    static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); }
+
+    static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); }
+
     void SetUp() override
     {
 #if CHIP_CRYPTO_PSA
-        // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete
-        VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
+        ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS);
 #endif
         chip::Test::LoopbackMessagingContext::SetUp();
     }
+
+    void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); }
 };
 
 enum : uint8_t
@@ -115,207 +114,155 @@ class ExpireSessionFromTimeoutDelegate : public WaitForTimeoutDelegate
     }
 };
 
-void CheckNewContextTest(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckNewContextTest)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     MockAppDelegate mockAppDelegate;
-    ExchangeContext * ec1 = ctx.NewExchangeToBob(&mockAppDelegate);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(inSuite, ec1 != nullptr);
-    NL_TEST_ASSERT(inSuite, ec1->IsInitiator() == true);
-    NL_TEST_ASSERT(inSuite, ec1->GetSessionHandle() == ctx.GetSessionAliceToBob());
-    NL_TEST_ASSERT(inSuite, ec1->GetDelegate() == &mockAppDelegate);
+    ExchangeContext * ec1 = NewExchangeToBob(&mockAppDelegate);
+    ASSERT_NE(ec1, nullptr);
+    EXPECT_EQ(ec1->IsInitiator(), true);
+    EXPECT_EQ(ec1->GetSessionHandle(), GetSessionAliceToBob());
+    EXPECT_EQ(ec1->GetDelegate(), &mockAppDelegate);
 
-    ExchangeContext * ec2 = ctx.NewExchangeToAlice(&mockAppDelegate);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(inSuite, ec2 != nullptr);
-    NL_TEST_ASSERT(inSuite, ec2->GetExchangeId() > ec1->GetExchangeId());
-    NL_TEST_ASSERT(inSuite, ec2->GetSessionHandle() == ctx.GetSessionBobToAlice());
+    ExchangeContext * ec2 = NewExchangeToAlice(&mockAppDelegate);
+    ASSERT_NE(ec2, nullptr);
+    EXPECT_GT(ec2->GetExchangeId(), ec1->GetExchangeId());
+    EXPECT_EQ(ec2->GetSessionHandle(), GetSessionBobToAlice());
 
     ec1->Close();
     ec2->Close();
 }
 
-void CheckSessionExpirationBasics(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckSessionExpirationBasics)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     MockAppDelegate sendDelegate;
-    ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate);
+    ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate);
+    ASSERT_NE(ec1, nullptr);
 
     // Expire the session this exchange is supposedly on.
     ec1->GetSessionHandle()->AsSecureSession()->MarkForEviction();
 
     MockAppDelegate receiveDelegate;
     CHIP_ERROR err =
-        ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, &receiveDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+        GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1, &receiveDelegate);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                            SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck));
-    NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_NE(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, !receiveDelegate.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(receiveDelegate.IsOnMessageReceivedCalled);
     ec1->Close();
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // recreate closed session.
-    NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR);
+    EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR);
 }
 
-void CheckSessionExpirationTimeout(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckSessionExpirationTimeout)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     WaitForTimeoutDelegate sendDelegate;
-    ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate);
+    ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate);
 
     ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                      SendFlags(Messaging::SendMessageFlags::kExpectResponse).Set(Messaging::SendMessageFlags::kNoAutoRequestAck));
 
-    ctx.DrainAndServiceIO();
-    NL_TEST_ASSERT(inSuite, !sendDelegate.IsOnResponseTimeoutCalled);
+    DrainAndServiceIO();
+    EXPECT_FALSE(sendDelegate.IsOnResponseTimeoutCalled);
 
     // Expire the session this exchange is supposedly on.  This should close the exchange.
     ec1->GetSessionHandle()->AsSecureSession()->MarkForEviction();
-    NL_TEST_ASSERT(inSuite, sendDelegate.IsOnResponseTimeoutCalled);
+    EXPECT_TRUE(sendDelegate.IsOnResponseTimeoutCalled);
 
     // recreate closed session.
-    NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR);
+    EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR);
 }
 
-void CheckSessionExpirationDuringTimeout(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckSessionExpirationDuringTimeout)
 {
     using namespace chip::System::Clock::Literals;
 
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     ExpireSessionFromTimeoutDelegate sendDelegate;
-    ExchangeContext * ec1 = ctx.NewExchangeToBob(&sendDelegate);
+    ExchangeContext * ec1 = NewExchangeToBob(&sendDelegate);
 
     auto timeout = System::Clock::Timeout(100);
     ec1->SetResponseTimeout(timeout);
 
-    NL_TEST_ASSERT(inSuite, !sendDelegate.IsOnResponseTimeoutCalled);
+    EXPECT_FALSE(sendDelegate.IsOnResponseTimeoutCalled);
 
     ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                      SendFlags(Messaging::SendMessageFlags::kExpectResponse).Set(Messaging::SendMessageFlags::kNoAutoRequestAck));
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Wait for our timeout to elapse. Give it an extra 1000ms of slack,
     // because if we lose the timeslice for longer than the slack we could end
     // up breaking out of the loop before the timeout timer has actually fired.
-    ctx.GetIOContext().DriveIOUntil(timeout + 1000_ms32, [&sendDelegate] { return sendDelegate.IsOnResponseTimeoutCalled; });
+    GetIOContext().DriveIOUntil(timeout + 1000_ms32, [&sendDelegate] { return sendDelegate.IsOnResponseTimeoutCalled; });
 
-    NL_TEST_ASSERT(inSuite, sendDelegate.IsOnResponseTimeoutCalled);
+    EXPECT_TRUE(sendDelegate.IsOnResponseTimeoutCalled);
 
     // recreate closed session.
-    NL_TEST_ASSERT(inSuite, ctx.CreateSessionAliceToBob() == CHIP_NO_ERROR);
+    EXPECT_EQ(CreateSessionAliceToBob(), CHIP_NO_ERROR);
 }
 
-void CheckUmhRegistrationTest(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckUmhRegistrationTest)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     CHIP_ERROR err;
     MockAppDelegate mockAppDelegate;
 
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id, &mockAppDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id, &mockAppDelegate);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1, &mockAppDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1, &mockAppDelegate);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::BDX::Id);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Echo::Id);
-    NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Echo::Id);
+    EXPECT_NE(err, CHIP_NO_ERROR);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST2);
-    NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::Echo::Id, kMsgType_TEST2);
+    EXPECT_NE(err, CHIP_NO_ERROR);
 }
 
-void CheckExchangeMessages(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestExchangeMgr, CheckExchangeMessages)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     CHIP_ERROR err;
 
     // create solicited exchange
     MockAppDelegate mockSolicitedAppDelegate;
-    ExchangeContext * ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate);
+    ExchangeContext * ec1 = NewExchangeToAlice(&mockSolicitedAppDelegate);
 
     // create unsolicited exchange
     MockAppDelegate mockUnsolicitedAppDelegate;
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1,
-                                                                            &mockUnsolicitedAppDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1,
+                                                                        &mockUnsolicitedAppDelegate);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // send a malicious packet
     ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST2, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                      SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck));
 
-    ctx.DrainAndServiceIO();
-    NL_TEST_ASSERT(inSuite, !mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
+    DrainAndServiceIO();
+    EXPECT_FALSE(mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
 
-    ec1 = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate);
+    ec1 = NewExchangeToAlice(&mockSolicitedAppDelegate);
 
     // send a good packet
     ec1->SendMessage(Protocols::BDX::Id, kMsgType_TEST1, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                      SendFlags(Messaging::SendMessageFlags::kNoAutoRequestAck));
 
-    ctx.DrainAndServiceIO();
-    NL_TEST_ASSERT(inSuite, mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
+    DrainAndServiceIO();
+    EXPECT_TRUE(mockUnsolicitedAppDelegate.IsOnMessageReceivedCalled);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Protocols::BDX::Id, kMsgType_TEST1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 }
 
-// Test Suite
-
-/**
- *  Test Suite that lists all the test functions.
- */
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("Test ExchangeMgr::NewContext",               CheckNewContextTest),
-    NL_TEST_DEF("Test ExchangeMgr::CheckUmhRegistrationTest", CheckUmhRegistrationTest),
-    NL_TEST_DEF("Test ExchangeMgr::CheckExchangeMessages",    CheckExchangeMessages),
-    NL_TEST_DEF("Test OnConnectionExpired basics",            CheckSessionExpirationBasics),
-    NL_TEST_DEF("Test OnConnectionExpired timeout handling",  CheckSessionExpirationTimeout),
-    NL_TEST_DEF("Test session eviction in timeout handling",  CheckSessionExpirationDuringTimeout),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "Test-CHIP-ExchangeManager",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
 } // namespace
-
-/**
- *  Main
- */
-int TestExchangeMgr()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestExchangeMgr);
diff --git a/src/messaging/tests/TestMessagingLayer.cpp b/src/messaging/tests/TestMessagingLayer.cpp
index 00dca89f2b6639..4e52cb96972ea6 100644
--- a/src/messaging/tests/TestMessagingLayer.cpp
+++ b/src/messaging/tests/TestMessagingLayer.cpp
@@ -20,13 +20,15 @@
  *    @file
  *      This file implements unit tests for the ExchangeManager implementation.
  */
+#include <errno.h>
+#include <utility>
+
+#include <gtest/gtest.h>
 
 #include <lib/core/CHIPCore.h>
 #include <lib/support/CHIPFaultInjection.h>
 #include <lib/support/CHIPMem.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeMgr.h>
 #include <messaging/Flags.h>
@@ -36,12 +38,6 @@
 #include <transport/SessionManager.h>
 #include <transport/TransportMgr.h>
 
-#include <nlbyteorder.h>
-#include <nlunit-test.h>
-
-#include <errno.h>
-#include <utility>
-
 namespace {
 
 using namespace chip;
@@ -53,6 +49,17 @@ using namespace chip::System::Clock::Literals;
 
 using TestContext = Test::UDPMessagingContext;
 
+struct TestMessagingLayer : public chip::Test::UDPMessagingContext, public ::testing::Test
+{
+    static void SetUpTestSuite() { chip::Test::UDPMessagingContext::SetUpTestSuite(); }
+    static void TearDownTestSuite() { chip::Test::UDPMessagingContext::TearDownTestSuite(); }
+
+    // Performs setup for each individual test in the test suite
+    void SetUp() override { chip::Test::UDPMessagingContext::SetUp(); }
+
+    void TearDown() override { chip::Test::UDPMessagingContext::TearDown(); }
+};
+
 // The message timeout value in milliseconds.
 constexpr System::Clock::Timeout kMessageTimeout = System::Clock::Milliseconds32(100);
 
@@ -87,25 +94,23 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat
  *      - Confirm the message is sent successfully
  *      - Observe DUT response timeout with no response
  */
-void CheckExchangeOutgoingMessagesSuccess(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestMessagingLayer, CheckExchangeOutgoingMessagesSuccess)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     // create solicited exchange
     MockAppDelegate mockSolicitedAppDelegate;
-    ExchangeContext * ec = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate);
+    ExchangeContext * ec = NewExchangeToAlice(&mockSolicitedAppDelegate);
 
-    NL_TEST_ASSERT(inSuite, ec != nullptr);
+    ASSERT_NE(ec, nullptr);
     ec->SetResponseTimeout(kMessageTimeout);
 
     CHIP_ERROR err = ec->SendMessage(Echo::MsgType::EchoRequest, System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize),
                                      SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
 
     // Wait for the initial message to fail (should take 330-413ms)
-    ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; });
+    GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; });
 
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, mockSolicitedAppDelegate.IsOnResponseTimeoutCalled);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_TRUE(mockSolicitedAppDelegate.IsOnResponseTimeoutCalled);
 }
 
 /**
@@ -118,15 +123,13 @@ void CheckExchangeOutgoingMessagesSuccess(nlTestSuite * inSuite, void * inContex
  *      - Confirm the message is sent with failure
  *      - Confirm the DUT response timeout timer is cancelled
  */
-void CheckExchangeOutgoingMessagesFail(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestMessagingLayer, CheckExchangeOutgoingMessagesFail)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     // create solicited exchange
     MockAppDelegate mockSolicitedAppDelegate;
-    ExchangeContext * ec = ctx.NewExchangeToAlice(&mockSolicitedAppDelegate);
+    ExchangeContext * ec = NewExchangeToAlice(&mockSolicitedAppDelegate);
 
-    NL_TEST_ASSERT(inSuite, ec != nullptr);
+    ASSERT_NE(ec, nullptr);
     ec->SetResponseTimeout(kMessageTimeout);
 
     chip::FaultInjection::GetManager().FailAtFault(chip::FaultInjection::kFault_DropOutgoingUDPMsg, 0, 1);
@@ -135,48 +138,11 @@ void CheckExchangeOutgoingMessagesFail(nlTestSuite * inSuite, void * inContext)
                                      SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
 
     // Wait for the initial message to fail (should take 330-413ms)
-    ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; });
+    GetIOContext().DriveIOUntil(500_ms32, [&] { return mockSolicitedAppDelegate.IsOnMessageReceivedCalled; });
 
-    NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, !mockSolicitedAppDelegate.IsOnResponseTimeoutCalled);
+    EXPECT_NE(err, CHIP_NO_ERROR);
+    EXPECT_FALSE(mockSolicitedAppDelegate.IsOnResponseTimeoutCalled);
     ec->Close();
 }
 
-// Test Suite
-
-/**
- *  Test Suite that lists all the test functions.
- */
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("Test MessagingLayer::ExchangeOutgoingMessagesSuccess", CheckExchangeOutgoingMessagesSuccess),
-    NL_TEST_DEF("Test MessagingLayer::ExchangeOutgoingMessagesFail", CheckExchangeOutgoingMessagesFail),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "Test-CHIP-MessagingLayer",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
 } // namespace
-
-/**
- *  Main
- */
-int TestMessagingLayer()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestMessagingLayer);
diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp
index 68342838a735b1..d965c172a1c010 100644
--- a/src/messaging/tests/TestReliableMessageProtocol.cpp
+++ b/src/messaging/tests/TestReliableMessageProtocol.cpp
@@ -21,13 +21,13 @@
  *      This file implements unit tests for the ReliableMessageProtocol
  *      implementation.
  */
+#include <errno.h>
+
+#include <gtest/gtest.h>
 
 #include <app/icd/server/ICDServerConfig.h>
 #include <lib/core/CHIPCore.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <lib/support/UnitTestUtils.h>
 #include <messaging/ReliableMessageContext.h>
 #include <messaging/ReliableMessageMgr.h>
 #include <messaging/ReliableMessageProtocolConfig.h>
@@ -36,11 +36,6 @@
 #include <transport/SessionManager.h>
 #include <transport/TransportMgr.h>
 
-#include <nlbyteorder.h>
-#include <nlunit-test.h>
-
-#include <errno.h>
-
 #include <messaging/ExchangeContext.h>
 #include <messaging/ExchangeMgr.h>
 #include <messaging/Flags.h>
@@ -65,26 +60,30 @@ using namespace chip::System::Clock::Literals;
 
 const char PAYLOAD[] = "Hello!";
 
-class TestContext : public chip::Test::LoopbackMessagingContext
+class TestReliableMessageProtocol : public chip::Test::LoopbackMessagingContext, public ::testing::Test
 {
 public:
+    static void SetUpTestSuite() { chip::Test::LoopbackMessagingContext::SetUpTestSuite(); }
+    static void TearDownTestSuite() { chip::Test::LoopbackMessagingContext::TearDownTestSuite(); }
+
     // Performs setup for each individual test in the test suite
     void SetUp() override
     {
 #if CHIP_CRYPTO_PSA
-        // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete
-        VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
+        ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS);
 #endif
         chip::Test::LoopbackMessagingContext::SetUp();
         GetSessionAliceToBob()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()));
         GetSessionBobToAlice()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()));
     }
+
+    void TearDown() override { chip::Test::LoopbackMessagingContext::TearDown(); }
 };
 
 class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegate
 {
 public:
-    MockAppDelegate(TestContext & ctx) : mTestContext(ctx) {}
+    MockAppDelegate(TestReliableMessageProtocol & ctx) : mTestReliableMessageProtocol(ctx) {}
 
     CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override
     {
@@ -128,11 +127,8 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat
         }
         mExchange = ec;
 
-        if (mTestSuite != nullptr)
-        {
-            NL_TEST_ASSERT(mTestSuite, buffer->TotalLength() == sizeof(PAYLOAD));
-            NL_TEST_ASSERT(mTestSuite, memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()) == 0);
-        }
+        EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD));
+        EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0);
         return CHIP_NO_ERROR;
     }
 
@@ -155,7 +151,7 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat
             // Restart the MRP retransmit timer, now that we are not going to be
             // dropping acks anymore, so we send out pending retransmits, if
             // any, as needed.
-            mTestContext.GetExchangeManager().GetReliableMessageMgr()->StartTimer();
+            mTestReliableMessageProtocol.GetExchangeManager().GetReliableMessageMgr()->StartTimer();
         }
     }
 
@@ -164,10 +160,9 @@ class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegat
     bool mRetainExchange           = false;
     bool mResponseTimedOut         = false;
     ExchangeContext * mExchange    = nullptr;
-    nlTestSuite * mTestSuite       = nullptr;
 
 private:
-    TestContext & mTestContext;
+    TestReliableMessageProtocol & mTestReliableMessageProtocol;
     bool mDropAckResponse = false;
 };
 
@@ -199,11 +194,8 @@ class MockSessionEstablishmentDelegate : public UnsolicitedMessageHandler, publi
                                  System::PacketBufferHandle && buffer) override
     {
         IsOnMessageReceivedCalled = true;
-        if (mTestSuite != nullptr)
-        {
-            NL_TEST_ASSERT(mTestSuite, buffer->TotalLength() == sizeof(PAYLOAD));
-            NL_TEST_ASSERT(mTestSuite, memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()) == 0);
-        }
+        EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD));
+        EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0);
         return CHIP_NO_ERROR;
     }
 
@@ -213,7 +205,6 @@ class MockSessionEstablishmentDelegate : public UnsolicitedMessageHandler, publi
 
     bool IsOnMessageReceivedCalled = false;
     MockSessionEstablishmentExchangeDispatch mMessageDispatch;
-    nlTestSuite * mTestSuite = nullptr;
 };
 
 struct BackoffComplianceTestVector
@@ -316,7 +307,7 @@ struct BackoffComplianceTestVector theBackoffComplianceTestVector[] = { {
                                                                             .backoffMax  = System::Clock::Timeout(20'286'001),
                                                                         } };
 
-void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additionalMRPBackoffTime)
+void CheckGetBackoffImpl(System::Clock::Timeout additionalMRPBackoffTime)
 {
     ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(additionalMRPBackoffTime));
 
@@ -336,8 +327,8 @@ void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additiona
             ChipLogProgress(Test, "Backoff base %" PRIu32 " extra %" PRIu32 " # %d: %" PRIu32, test.backoffBase.count(),
                             extraBackoff.count(), test.sendCount, backoff.count());
 
-            NL_TEST_ASSERT(inSuite, backoff >= test.backoffMin + extraBackoff);
-            NL_TEST_ASSERT(inSuite, backoff <= test.backoffMax + extraBackoff);
+            EXPECT_GE(backoff, test.backoffMin + extraBackoff);
+            EXPECT_LE(backoff, test.backoffMax + extraBackoff);
         }
     }
 
@@ -346,52 +337,23 @@ void CheckGetBackoffImpl(nlTestSuite * inSuite, System::Clock::Timeout additiona
 
 } // namespace
 
-class TestReliableMessageProtocol
+TEST_F(TestReliableMessageProtocol, CheckAddClearRetrans)
 {
-public:
-    static void CheckAddClearRetrans(nlTestSuite * inSuite, void * inContext);
-    static void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext);
-    static void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * inContext);
-    static void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext);
-    static void CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext);
-    static void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext);
-    static void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext);
-    static void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext);
-    static void CheckDuplicateOldMessageClosedExchange(nlTestSuite * inSuite, void * inContext);
-    static void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext);
-    static void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext);
-    static void CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inContext);
-    static void CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext);
-    static void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext);
-    static void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inContext);
-    static void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext);
-    static void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext);
-    static void CheckIsPeerActiveNotInitiator(nlTestSuite * inSuite, void * inContext);
-    static void CheckGetBackoff(nlTestSuite * inSuite, void * inContext);
-    static void CheckGetBackoffAdditionalTime(nlTestSuite * inSuite, void * inContext);
-    static void CheckApplicationResponseDelayed(nlTestSuite * inSuite, void * inContext);
-    static void CheckApplicationResponseNeverComes(nlTestSuite * inSuite, void * inContext);
-};
+    MockAppDelegate mockAppDelegate(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate);
+    ASSERT_NE(exchange, nullptr);
 
-void TestReliableMessageProtocol::CheckAddClearRetrans(nlTestSuite * inSuite, void * inContext)
-{
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
-    MockAppDelegate mockAppDelegate(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
-
-    ReliableMessageMgr * rm     = ctx.GetExchangeManager().GetReliableMessageMgr();
+    ReliableMessageMgr * rm     = GetExchangeManager().GetReliableMessageMgr();
     ReliableMessageContext * rc = exchange->GetReliableMessageContext();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
-    NL_TEST_ASSERT(inSuite, rc != nullptr);
+    ASSERT_NE(rm, nullptr);
+    ASSERT_NE(rc, nullptr);
 
     ReliableMessageMgr::RetransTableEntry * entry;
 
     rm->AddToRetransTable(rc, &entry);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
     rm->ClearRetransTable(*entry);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     exchange->Close();
 }
@@ -422,26 +384,25 @@ void TestReliableMessageProtocol::CheckAddClearRetrans(nlTestSuite * inSuite, vo
  *      - PEER to acknowledge message
  *      - Observe DUT signal successful reliable transmission
  */
-void TestReliableMessageProtocol::CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessage)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
     BackoffComplianceTestVector * expectedBackoff;
     System::Clock::Timestamp now, startTime;
     System::Clock::Timeout timeoutTime, margin;
     margin = System::Clock::Timeout(15);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockSender(ctx);
+    MockAppDelegate mockSender(*this);
     // TODO: temporarily create a SessionHandle from node id, will be fix in PR 3602
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         System::Clock::Timestamp(300), // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -449,112 +410,111 @@ void TestReliableMessageProtocol::CheckResendApplicationMessage(nlTestSuite * in
     }));
 
     // Let's drop the initial message
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 4;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // Ensure the exchange stays open after we send (unlike the CheckCloseExchangeAndResendApplicationMessage case), by claiming to
     // expect a response.
     startTime = System::SystemClock().GetMonotonicTimestamp();
     err       = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the initial message was dropped and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 3);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 3u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the initial message to fail (should take 330-413ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
     now         = System::SystemClock().GetMonotonicTimestamp();
     timeoutTime = now - startTime;
     ChipLogProgress(Test, "Attempt #1  Timeout : %" PRIu32 "ms", timeoutTime.count());
     expectedBackoff = &theBackoffComplianceTestVector[0];
-    NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin);
+    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);
 
     startTime = System::SystemClock().GetMonotonicTimestamp();
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the 1st retry was dropped, and is still there in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the 1st retry to fail (should take 330-413ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
     now         = System::SystemClock().GetMonotonicTimestamp();
     timeoutTime = now - startTime;
     ChipLogProgress(Test, "Attempt #2  Timeout : %" PRIu32 "ms", timeoutTime.count());
     expectedBackoff = &theBackoffComplianceTestVector[1];
-    NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin);
+    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);
 
     startTime = System::SystemClock().GetMonotonicTimestamp();
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the 2nd retry was dropped, and is still there in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 3u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the 2nd retry to fail (should take 528-660ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
     now         = System::SystemClock().GetMonotonicTimestamp();
     timeoutTime = now - startTime;
     ChipLogProgress(Test, "Attempt #3  Timeout : %" PRIu32 "ms", timeoutTime.count());
     expectedBackoff = &theBackoffComplianceTestVector[2];
-    NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin);
+    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);
 
     startTime = System::SystemClock().GetMonotonicTimestamp();
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the 3rd retry was dropped, and is still there in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 4u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the 3rd retry to fail (should take 845-1056ms)
-    ctx.GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; });
+    GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; });
     now         = System::SystemClock().GetMonotonicTimestamp();
     timeoutTime = now - startTime;
     ChipLogProgress(Test, "Attempt #4  Timeout : %" PRIu32 "ms", timeoutTime.count());
     expectedBackoff = &theBackoffComplianceTestVector[3];
-    NL_TEST_ASSERT(inSuite, timeoutTime >= expectedBackoff->backoffMin - margin);
+    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);
 
     // Trigger final transmission
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the last retransmission was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 5);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_GE(loopback.mSentMessageCount, 5u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     exchange->Close();
 }
 
-void TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckCloseExchangeAndResendApplicationMessage)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockSender(ctx);
+    MockAppDelegate mockSender(*this);
     // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -562,58 +522,57 @@ void TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage(
     }));
 
     // Let's drop the initial message
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 2;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped, and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the first re-transmit (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was dropped, and is still there in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Wait for the second re-transmit (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 3);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_GE(loopback.mSentMessageCount, 3u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckFailedMessageRetainOnSend)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
     MockSessionEstablishmentDelegate mockSender;
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -622,88 +581,82 @@ void TestReliableMessageProtocol::CheckFailedMessageRetainOnSend(nlTestSuite * i
 
     mockSender.mMessageDispatch.mRetainMessageOnSend = false;
     // Let's drop the initial message
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 1;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
 
     // Wait for the first re-transmit (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit table is empty, as we did not provide a message to retain
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckUnencryptedMessageReceiveFailure)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     MockSessionEstablishmentDelegate mockReceiver;
-    CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Expect the received messages to be encrypted
     mockReceiver.mMessageDispatch.mRequireEncryption = true;
 
     MockSessionEstablishmentDelegate mockSender;
-    ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
 
     // We are sending a malicious packet, doesn't expect an ack
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kNoAutoRequestAck));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Test that the message was actually sent (and not dropped)
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
     // Test that the message was dropped by the receiver
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessageWithPeerExchange)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -711,61 +664,55 @@ void TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange(
     }));
 
     // Let's drop the initial message
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 1;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped, and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
 
     // Wait for the first re-transmit (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was not dropped, and is no longer in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
-
-    mockReceiver.mTestSuite = nullptr;
+    EXPECT_GE(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 }
 
-void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckDuplicateMessageClosedExchange)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
@@ -773,7 +720,7 @@ void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuit
     }));
 
     // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -783,56 +730,52 @@ void TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange(nlTestSuit
     mockReceiver.mRetainExchange = false;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent
     // The ack was dropped, and message was added to the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Let's not drop the duplicate message
     mockReceiver.SetDropAckResponse(false);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Wait for the first re-transmit and ack (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was sent and the ack was sent
     // and retransmit table was cleared
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckDuplicateOldMessageClosedExchange)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
@@ -840,7 +783,7 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS
     }));
 
     // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -850,17 +793,17 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS
     mockReceiver.mRetainExchange = false;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent
     // The ack was dropped, and message was added to the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Now send CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE + 2 messages to make
     // sure our original message is out of the message counter window.  These
@@ -870,70 +813,65 @@ void TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange(nlTestS
     for (size_t i = 0; i < extraMessages; ++i)
     {
         buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-        NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+        EXPECT_FALSE(buffer.IsNull());
 
-        ExchangeContext * newExchange = ctx.NewExchangeToAlice(&mockSender);
-        NL_TEST_ASSERT(inSuite, newExchange != nullptr);
+        ExchangeContext * newExchange = NewExchangeToAlice(&mockSender);
+        ASSERT_NE(newExchange, nullptr);
 
         mockReceiver.mRetainExchange = false;
 
         // Ensure the retransmit table has our one message right now
-        NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
         // Send without MRP.
         err = newExchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kNoAutoRequestAck);
-        NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-        ctx.DrainAndServiceIO();
+        EXPECT_EQ(err, CHIP_NO_ERROR);
+        DrainAndServiceIO();
 
         // Ensure the message was sent, but not added to the retransmit table.
-        NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1 + (i + 1));
-        NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-        NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+        EXPECT_EQ(loopback.mSentMessageCount, 1u + (i + 1u));
+        EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
     }
 
     // Let's not drop the duplicate message's ack.
     mockReceiver.SetDropAckResponse(false);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Wait for the first re-transmit and ack (should take 64ms)
     rm->StartTimer();
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3 + extraMessages; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3 + extraMessages; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was sent and the ack was sent
     // and retransmit table was cleared
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3 + extraMessages);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u + extraMessages);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckResendSessionEstablishmentMessageWithPeerExchange)
 {
     // Making this static to reduce stack usage, as some platforms have limits on stack size.
-    static Test::MessagingContext ctx;
-
-    TestContext & inctx = *static_cast<TestContext *>(inContext);
-
-    CHIP_ERROR err = ctx.InitFromExisting(inctx);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    static chip::Test::MessagingContext ctx;
+    CHIP_ERROR err = ctx.InitFromExisting(*this);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    ASSERT_FALSE(buffer.IsNull());
 
     MockSessionEstablishmentDelegate mockReceiver;
     err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     MockSessionEstablishmentDelegate mockSender;
     ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    ASSERT_NE(exchange, nullptr);
 
     ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -941,63 +879,57 @@ void TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeer
     }));
 
     // Let's drop the initial message
-    auto & loopback               = inctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 1;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    inctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped, and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
 
     // Wait for the first re-transmit (should take 64ms)
-    inctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
-    inctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was not dropped, and is no longer in the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount >= 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
-
-    mockReceiver.mTestSuite = nullptr;
+    EXPECT_GE(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    ctx.ShutdownAndRestoreExisting(inctx);
+    ctx.ShutdownAndRestoreExisting(*this);
 }
 
-void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckDuplicateMessage)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
@@ -1005,7 +937,7 @@ void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, v
     }));
 
     // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -1015,154 +947,142 @@ void TestReliableMessageProtocol::CheckDuplicateMessage(nlTestSuite * inSuite, v
     mockReceiver.mRetainExchange = true;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent
     // The ack was dropped, and message was added to the retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Let's not drop the duplicate message
     mockReceiver.SetDropAckResponse(false);
     mockReceiver.mRetainExchange = false;
 
     // Wait for the first re-transmit and ack (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
+    DrainAndServiceIO();
 
     // Ensure the retransmit message was sent and the ack was sent
     // and retransmit table was cleared
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     mockReceiver.CloseExchangeIfNeeded();
 }
 
-void TestReliableMessageProtocol::CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckReceiveAfterStandaloneAck)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // We send a message, have it get received by the peer, then an ack is
     // returned, then a reply is returned.  We need to keep the receiver
     // exchange alive until it does the message send (so we can send the
     // response from the receiver and so the initial sender exchange can get
     // it).
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
     mockReceiver.mRetainExchange  = true;
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we have not seen an ack yet.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
-    NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending());
+    EXPECT_TRUE(receiverRc->IsAckPending());
 
     // Send the standalone ack.
     receiverRc->SendStandaloneAckMessage();
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the ack was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have not gotten any app-level responses so far.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // And that we have now gotten our ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // Now send a message from the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response and its ack was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 4u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have received that response.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckPiggybackAfterPiggyback)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // We send a message, have it get received by the peer, have the peer return
     // a piggybacked ack.  Then we send a second message this time _not_
@@ -1170,7 +1090,7 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS
     // piggybacked.  We need to keep both exchanges alive for that (so we can
     // send the response from the receiver and so the initial sender exchange
     // can get it).
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -1178,45 +1098,45 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS
     mockSender.mRetainExchange    = true;
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we have not seen an ack yet.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
-    NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending());
+    EXPECT_TRUE(receiverRc->IsAckPending());
 
     // Ensure that we have not gotten any app-level responses or acks so far.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Now send a message from the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err =
         mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer),
                                             SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have received that response and it had a piggyback ack.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // Reset various state so we can measure things again.
     mockReceiver.IsOnMessageReceivedCalled = false;
@@ -1225,22 +1145,22 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS
 
     // Now send a new message to the other side, but don't ask for an ack.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer),
                                 SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we are not expecting an ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // Send the final response.  At this point we don't need to keep the
     // exchanges alive anymore.
@@ -1248,27 +1168,27 @@ void TestReliableMessageProtocol::CheckPiggybackAfterPiggyback(nlTestSuite * inS
     mockSender.mRetainExchange   = false;
 
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response and its ack was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 5);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 5u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have received that response and it had a piggyback ack.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckSendUnsolicitedStandaloneAckMessage)
 {
     /**
      * Tests sending a standalone ack message that is:
@@ -1278,68 +1198,62 @@ void TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage(nlTes
      * This is not a thing that would normally happen, but a malicious entity
      * could absolutely do this.
      */
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData("", 0);
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // We send a message, have it get received by the peer, expect an ack from
     // the peer.
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
 
     // Purposefully sending a standalone ack that requests an ack!
     err = exchange->SendMessage(SecureChannel::MsgType::StandaloneAck, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     // Needs a manual close, because SendMessage does not close for standalone acks.
     exchange->Close();
-    ctx.DrainAndServiceIO();
+    DrainAndServiceIO();
 
     // Ensure the message and its ack were sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that nothing is waiting for acks.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckSendStandaloneAckMessage)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
-    MockAppDelegate mockAppDelegate(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockAppDelegate);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockAppDelegate(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm     = ctx.GetExchangeManager().GetReliableMessageMgr();
+    ReliableMessageMgr * rm     = GetExchangeManager().GetReliableMessageMgr();
     ReliableMessageContext * rc = exchange->GetReliableMessageContext();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
-    NL_TEST_ASSERT(inSuite, rc != nullptr);
+    ASSERT_NE(rm, nullptr);
+    ASSERT_NE(rc, nullptr);
 
-    NL_TEST_ASSERT(inSuite, rc->SendStandaloneAckMessage() == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(rc->SendStandaloneAckMessage(), CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Need manual close because standalone acks don't close exchanges.
     exchange->Close();
 }
 
-void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckMessageAfterClosed)
 {
     /**
      * This test performs the following sequence of actions, where all messages
@@ -1355,32 +1269,26 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite,
      * responder closing the exchange after it sends the response.
      */
 
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -1388,49 +1296,49 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite,
     mockReceiver.mRetainExchange = true;
     mockSender.mRetainExchange   = true;
 
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.mReceivedPiggybackAck);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.mReceivedPiggybackAck);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck);
 
     // And that we have not seen an ack yet.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
-    NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending());
+    EXPECT_TRUE(receiverRc->IsAckPending());
 
     // Ensure that we have not gotten any app-level responses or acks so far.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Now send a message from the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have received that response and it had a piggyback ack.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
     // And that we are now waiting for an ack for the response.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // Reset various state so we can measure things again.
     mockReceiver.IsOnMessageReceivedCalled = false;
@@ -1440,31 +1348,31 @@ void TestReliableMessageProtocol::CheckMessageAfterClosed(nlTestSuite * inSuite,
 
     // Now send a second message to the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent (and the ack for it was also sent).
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 4u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was not received (because the exchange is closed on the
     // receiver).
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we are not expecting an ack; acks should have been flushed
     // immediately on the receiver, due to the exchange being closed.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckLostResponseWithPiggyback)
 {
     /**
      * This tests the following scenario:
@@ -1475,30 +1383,24 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i
      * 5) The responder retransmits the application-level response.
      * 4) The initiator should receive the application-level response.
      */
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // Make sure that we resend our message before the other side does.
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
@@ -1512,30 +1414,30 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i
     // we can send the response from the receiver), but don't need anything
     // special for the sender exchange, because it will be waiting for the
     // application-level response.
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
     mockReceiver.mRetainExchange  = true;
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we have not gotten any app-level responses or acks so far.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
     // Should have pending ack here.
-    NL_TEST_ASSERT(inSuite, receiverRc->IsAckPending());
+    EXPECT_TRUE(receiverRc->IsAckPending());
     // Make sure receiver resends after sender does, and there's enough of a gap
     // that we are very unlikely to actually trigger the resends on the receiver
     // when we trigger the resends on the sender.
@@ -1548,26 +1450,26 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i
     loopback.mNumMessagesToDrop = 1;
 
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     // Stop keeping receiver exchange alive.
     mockReceiver.mRetainExchange = true;
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response was sent but dropped.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
 
     // Ensure that we have not received that response.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.mReceivedPiggybackAck);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
     // We now have our un-acked message still waiting to retransmit and the
     // message that the other side sent is waiting for an ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 2);
 
     // Reset various state so we can measure things again.
     mockReceiver.IsOnMessageReceivedCalled = false;
@@ -1576,8 +1478,8 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i
     mockSender.mReceivedPiggybackAck       = false;
 
     // Wait for re-transmit from sender and ack (should take 64ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
+    DrainAndServiceIO();
 
     // We resent our first message, which did not make it to the app-level
     // listener on the receiver (because it's a duplicate) but did trigger a
@@ -1586,39 +1488,39 @@ void TestReliableMessageProtocol::CheckLostResponseWithPiggyback(nlTestSuite * i
     // Now the annoying part is that depending on how long we _actually_ slept
     // we might have also triggered the retransmit from the other side, even
     // though we did not want to.  Handle both cases here.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4 || loopback.mSentMessageCount == 6);
+    EXPECT_TRUE(loopback.mSentMessageCount == 4 || loopback.mSentMessageCount == 6);
     if (loopback.mSentMessageCount == 4)
     {
         // Just triggered the retransmit from the sender.
-        NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-        NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-        NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-        NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+        EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+        EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+        EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
     }
     else
     {
         // Also triggered the retransmit from the receiver.
-        NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-        NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-        NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-        NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+        EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+        EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+        EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+        EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
     }
 
     // Wait for re-transmit from receiver (should take 256ms)
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 6; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 6; });
+    DrainAndServiceIO();
 
     // And now we've definitely resent our response message, which should show
     // up as an app-level message and trigger a standalone ack.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 6);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mSentMessageCount, 6u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
 
     // Should be all done now.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckIsPeerActiveNotInitiator)
 {
     /**
      * This tests the following scenario:
@@ -1630,37 +1532,31 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in
      * 6) Initiator receives the response
      */
 
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
-
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    mockSender.mTestSuite = inSuite;
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
         1000_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
     }));
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 1;
     loopback.mDroppedMessageCount = 0;
@@ -1668,40 +1564,40 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in
     mockReceiver.mRetainExchange = true;
     mockSender.mRetainExchange   = true;
 
-    NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage());
+    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Verify that the first message is dropped
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
 
     // Make sure retransmit was not done before the idle restrans interval hits
-    ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 1; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 1; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage());
+    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());
 
     // // Make sure nothing happened
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
 
     // // Retrasnmit message
-    ctx.GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage());
+    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());
 
     // // Make sure nothing happened
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // // Verify that the receiver considers the sender is active
-    NL_TEST_ASSERT(inSuite, !exchange->HasReceivedAtLeastOneMessage());
-    NL_TEST_ASSERT(inSuite, mockReceiver.mExchange->HasReceivedAtLeastOneMessage());
+    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());
+    EXPECT_TRUE(mockReceiver.mExchange->HasReceivedAtLeastOneMessage());
 
     mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -1713,30 +1609,30 @@ void TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator(nlTestSuite * in
 
     // Now send a message from the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     // Make receiver message fail once
     loopback.mNumMessagesToDrop = 1;
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Make sure nothing happened
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 3);
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mSentMessageCount, 3u);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // // Retrasnmit message
-    ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 4; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 4; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 5);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mSentMessageCount, 5u);
 }
 
-void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckLostStandaloneAck)
 {
     /**
      * This tests the following scenario:
@@ -1748,37 +1644,31 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite,
      * This should succeed, with all application-level messages being delivered
      * and no crashes.
      */
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    mockSender.mTestSuite = inSuite;
-
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     // We send a message, the other side sends a standalone ack first (which is
     // lost), then an application response, then we respond to that response.
     // We need to keep both exchanges alive for that (so we can send the
     // response from the receiver and so the initial sender exchange can send a
     // response to that).
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = 0;
     loopback.mDroppedMessageCount = 0;
@@ -1789,48 +1679,48 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite,
     mockReceiver.SetDropAckResponse(true);
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
 
     // And that we have not gotten any app-level responses or acks so far.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
     // Ack should have been dropped.
-    NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending());
+    EXPECT_FALSE(receiverRc->IsAckPending());
 
     // Don't drop any more acks.
     mockReceiver.SetDropAckResponse(false);
 
     // Now send a message from the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer),
                                               SendFlags(SendMessageFlags::kExpectResponse));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the response was sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 2);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 2u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // Ensure that we have received that response and had a piggyback ack.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, mockSender.mReceivedPiggybackAck);
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
     // We now have just the received message waiting for an ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
 
     // And receiver still has no ack pending.
-    NL_TEST_ASSERT(inSuite, !receiverRc->IsAckPending());
+    EXPECT_FALSE(receiverRc->IsAckPending());
 
     // Reset various state so we can measure things again.
     mockReceiver.IsOnMessageReceivedCalled = false;
@@ -1843,67 +1733,64 @@ void TestReliableMessageProtocol::CheckLostStandaloneAck(nlTestSuite * inSuite,
 
     // Now send a new message to the other side.
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message and the standalone ack to it were sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 4);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 0);
+    EXPECT_EQ(loopback.mSentMessageCount, 4u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
 
     // And that it was received.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, mockReceiver.mReceivedPiggybackAck);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_TRUE(mockReceiver.mReceivedPiggybackAck);
 
     // At this point all our exchanges and reliable message contexts should be
     // dead, so we can't test anything about their state.
 
     // And that there are no un-acked messages left.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 }
 
-void TestReliableMessageProtocol::CheckGetBackoff(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckGetBackoff)
 {
-    CheckGetBackoffImpl(inSuite, System::Clock::kZero);
+    CheckGetBackoffImpl(System::Clock::kZero);
 }
 
-void TestReliableMessageProtocol::CheckGetBackoffAdditionalTime(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckGetBackoffAdditionalTime)
 {
-    CheckGetBackoffImpl(inSuite, System::Clock::Seconds32(1));
+    CheckGetBackoffImpl(System::Clock::Seconds32(1));
 }
 
-void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckApplicationResponseDelayed)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     CHIP_ERROR err = CHIP_NO_ERROR;
 
     // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
-    ctx.ExpireSessionBobToAlice();
-    ctx.ExpireSessionAliceToBob();
-    err = ctx.CreateCASESessionBobToAlice();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    err = ctx.CreateCASESessionAliceToBob();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    ExpireSessionBobToAlice();
+    ExpireSessionAliceToBob();
+    err = CreateCASESessionBobToAlice();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    err = CreateCASESessionAliceToBob();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    mockReceiver.mTestSuite      = inSuite;
     mockReceiver.mRetainExchange = true;
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -1913,51 +1800,51 @@ void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite *
     constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message.
 
     // Let's drop all but the last MRP transmit.
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = kMaxMRPTransmits - 1;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     exchange->SetResponseTimeout(3000_ms32);
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped, and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == kMaxMRPTransmits - 2);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // Wait for all but the last retransmit to happen.
-    ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
+    DrainAndServiceIO();
 
     // Ensure that nothing has been sent yet.
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // Now allow through the next message (our last retransmit), but make sure
     // there is no standalone ack for it.
     mockReceiver.SetDropAckResponse(true);
-    ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
+    DrainAndServiceIO();
 
     // Verify that message was sent and received but nothing else has been sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);    // We have no ack yet.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We have no ack yet.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
 
     // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly.
     mockReceiver.SetDropAckResponse(false);
@@ -1973,99 +1860,93 @@ void TestReliableMessageProtocol::CheckApplicationResponseDelayed(nlTestSuite *
     }));
 
     buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
+    EXPECT_FALSE(buffer.IsNull());
 
     err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // At this point, we should have two MRP contexts pending.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 2);    // We have no ack yet.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 2);        // We have no ack yet.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
 
     // Now wait for all but the last retransmit to happen from the other side.
-    ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits - 1; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits - 1; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
     // We might have timed our MRP resends out, or not, but the other side is waiting for an ack.
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1 || rm->TestGetCountRetransTable() == 2);
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_TRUE(rm->TestGetCountRetransTable() == 1 || rm->TestGetCountRetransTable() == 2);
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
 
     // Now wait for us to time out our MRP context for sure.
-    ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 1; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 1; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);    // We timed out our MRP context.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
-    NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut);          // We did not time out yet.
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We timed out our MRP context.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.
 
     // Now wait for the last retransmit (and our ack) to to happen.
-    ctx.GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
-    ctx.DrainAndServiceIO();
-
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits + 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);    // Everything has been acked.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, mockSender.IsOnMessageReceivedCalled);   // We got the response.
-    NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut);          // We did not time out yet.
+    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
+    DrainAndServiceIO();
 
-    mockReceiver.mTestSuite = nullptr;
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits + 1);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // Everything has been acked.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);   // We got the response.
+    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.
 
     // Ensure that we did not mark any sessions defunct.
-    NL_TEST_ASSERT(inSuite, !ctx.GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
-    NL_TEST_ASSERT(inSuite, !ctx.GetSessionAliceToBob()->AsSecureSession()->IsDefunct());
+    EXPECT_FALSE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
+    EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct());
 
     // Reset our sessions, so other tests get the usual PASE session
-    ctx.ExpireSessionBobToAlice();
-    ctx.ExpireSessionAliceToBob();
-    err = ctx.CreateSessionBobToAlice();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    err = ctx.CreateSessionAliceToBob();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    ExpireSessionBobToAlice();
+    ExpireSessionAliceToBob();
+    err = CreateSessionBobToAlice();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    err = CreateSessionAliceToBob();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 }
 
-void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestReliableMessageProtocol, CheckApplicationResponseNeverComes)
 {
-    TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
-
     CHIP_ERROR err = CHIP_NO_ERROR;
 
     // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
-    ctx.ExpireSessionBobToAlice();
-    ctx.ExpireSessionAliceToBob();
-    err = ctx.CreateCASESessionBobToAlice();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    err = ctx.CreateCASESessionAliceToBob();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    ExpireSessionBobToAlice();
+    ExpireSessionAliceToBob();
+    err = CreateCASESessionBobToAlice();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    err = CreateCASESessionAliceToBob();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
-    NL_TEST_ASSERT(inSuite, !buffer.IsNull());
-
-    MockAppDelegate mockReceiver(ctx);
-    err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_FALSE(buffer.IsNull());
 
-    mockReceiver.mTestSuite = inSuite;
+    MockAppDelegate mockReceiver(*this);
+    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    MockAppDelegate mockSender(ctx);
-    ExchangeContext * exchange = ctx.NewExchangeToAlice(&mockSender);
-    NL_TEST_ASSERT(inSuite, exchange != nullptr);
+    MockAppDelegate mockSender(*this);
+    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
+    ASSERT_NE(exchange, nullptr);
 
-    ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
-    NL_TEST_ASSERT(inSuite, rm != nullptr);
+    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
+    ASSERT_NE(rm, nullptr);
 
     exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
         30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
@@ -2075,94 +1956,92 @@ void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite
     constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message.
 
     // Let's drop all but the last MRP transmit.
-    auto & loopback               = ctx.GetLoopback();
+    auto & loopback               = GetLoopback();
     loopback.mSentMessageCount    = 0;
     loopback.mNumMessagesToDrop   = kMaxMRPTransmits - 1;
     loopback.mDroppedMessageCount = 0;
 
     // Ensure the retransmit table is empty right now
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
 
     exchange->SetResponseTimeout(2500_ms32);
     err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    ctx.DrainAndServiceIO();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    DrainAndServiceIO();
 
     // Ensure the message was dropped, and was added to retransmit table
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == kMaxMRPTransmits - 2);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u);
+    EXPECT_EQ(loopback.mSentMessageCount, 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // Wait for all but the last retransmit to happen.
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
+    DrainAndServiceIO();
 
     // Ensure that nothing has been sent yet.
-    NL_TEST_ASSERT(inSuite, loopback.mNumMessagesToDrop == 0);
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);
-    NL_TEST_ASSERT(inSuite, !mockReceiver.IsOnMessageReceivedCalled);
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);
+    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
+    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
 
     // Now allow through the next message (our last retransmit), but make sure
     // there is no standalone ack for it.
     mockReceiver.SetDropAckResponse(true);
-    ctx.GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
+    DrainAndServiceIO();
 
     // Verify that message was sent and received but nothing else has been sent.
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 1);    // We have no ack yet.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We have no ack yet.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
 
     // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly.
     mockReceiver.SetDropAckResponse(false);
 
     // Now wait for us to time out our MRP context.
-    ctx.GetIOContext().DriveIOUntil(1000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(1000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);    // We timed out our MRP context.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
-    NL_TEST_ASSERT(inSuite, !mockSender.mResponseTimedOut);          // We did not time out yet.
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // We timed out our MRP context.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
+    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.
 
     // Now wait for our exchange to time out.
-    ctx.GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.mResponseTimedOut; });
-    ctx.DrainAndServiceIO();
+    GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.mResponseTimedOut; });
+    DrainAndServiceIO();
 
-    NL_TEST_ASSERT(inSuite, loopback.mSentMessageCount == kMaxMRPTransmits);
-    NL_TEST_ASSERT(inSuite, loopback.mDroppedMessageCount == kMaxMRPTransmits - 1);
-    NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0);    // We timed this out long ago.
-    NL_TEST_ASSERT(inSuite, mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
-    NL_TEST_ASSERT(inSuite, !mockSender.IsOnMessageReceivedCalled);  // We never got a response.
-    NL_TEST_ASSERT(inSuite, mockSender.mResponseTimedOut);           // We tiemd out
-
-    mockReceiver.mTestSuite = nullptr;
+    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
+    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
+    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // We timed this out long ago.
+    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
+    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We never got a response.
+    EXPECT_TRUE(mockSender.mResponseTimedOut);           // We tiemd out
 
     // We should have marked out session defunct.
-    NL_TEST_ASSERT(inSuite, ctx.GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
+    EXPECT_TRUE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
     // Other side had no reason to mark its session defunct.
-    NL_TEST_ASSERT(inSuite, !ctx.GetSessionAliceToBob()->AsSecureSession()->IsDefunct());
+    EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct());
 
     // Reset our sessions, so other tests get the usual PASE session
-    ctx.ExpireSessionBobToAlice();
-    ctx.ExpireSessionAliceToBob();
-    err = ctx.CreateSessionBobToAlice();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    err = ctx.CreateSessionAliceToBob();
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-
-    err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    ExpireSessionBobToAlice();
+    ExpireSessionAliceToBob();
+    err = CreateSessionBobToAlice();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    err = CreateSessionAliceToBob();
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+
+    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 }
 
 /**
@@ -2179,66 +2058,3 @@ void TestReliableMessageProtocol::CheckApplicationResponseNeverComes(nlTestSuite
  *    (this is the part that needs testing!)
  * 8. A sends message 5 to B.
  */
-
-const nlTest sTests[] = {
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckAddClearRetrans", TestReliableMessageProtocol::CheckAddClearRetrans),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckResendApplicationMessage",
-                TestReliableMessageProtocol::CheckResendApplicationMessage),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckCloseExchangeAndResendApplicationMessage",
-                TestReliableMessageProtocol::CheckCloseExchangeAndResendApplicationMessage),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckFailedMessageRetainOnSend",
-                TestReliableMessageProtocol::CheckFailedMessageRetainOnSend),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckResendApplicationMessageWithPeerExchange",
-                TestReliableMessageProtocol::CheckResendApplicationMessageWithPeerExchange),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckResendSessionEstablishmentMessageWithPeerExchange",
-                TestReliableMessageProtocol::CheckResendSessionEstablishmentMessageWithPeerExchange),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateMessage", TestReliableMessageProtocol::CheckDuplicateMessage),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateMessageClosedExchange",
-                TestReliableMessageProtocol::CheckDuplicateMessageClosedExchange),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckDuplicateOldMessageClosedExchange",
-                TestReliableMessageProtocol::CheckDuplicateOldMessageClosedExchange),
-    NL_TEST_DEF("Test that a reply after a standalone ack comes through correctly",
-                TestReliableMessageProtocol::CheckReceiveAfterStandaloneAck),
-    NL_TEST_DEF("Test that a reply to a non-MRP message piggybacks an ack if there were MRP things happening on the context before",
-                TestReliableMessageProtocol::CheckPiggybackAfterPiggyback),
-    NL_TEST_DEF("Test sending an unsolicited ack-soliciting 'standalone ack' message",
-                TestReliableMessageProtocol::CheckSendUnsolicitedStandaloneAckMessage),
-    NL_TEST_DEF("Test ReliableMessageMgr::CheckSendStandaloneAckMessage",
-                TestReliableMessageProtocol::CheckSendStandaloneAckMessage),
-    NL_TEST_DEF("Test command, response, default response, with receiver closing exchange after sending response",
-                TestReliableMessageProtocol::CheckMessageAfterClosed),
-    NL_TEST_DEF("Test that unencrypted message is dropped if exchange requires encryption",
-                TestReliableMessageProtocol::CheckUnencryptedMessageReceiveFailure),
-    NL_TEST_DEF("Test that dropping an application-level message with a piggyback ack works ok once both sides retransmit",
-                TestReliableMessageProtocol::CheckLostResponseWithPiggyback),
-    NL_TEST_DEF("Test that an application-level response-to-response after a lost standalone ack to the initial message works",
-                TestReliableMessageProtocol::CheckLostStandaloneAck),
-    NL_TEST_DEF("Test Is Peer Active Retry logic", TestReliableMessageProtocol::CheckIsPeerActiveNotInitiator),
-    NL_TEST_DEF("Test MRP backoff algorithm", TestReliableMessageProtocol::CheckGetBackoff),
-    NL_TEST_DEF("Test MRP backoff algorithm with additional time", TestReliableMessageProtocol::CheckGetBackoffAdditionalTime),
-    // TODO: Re-enable this test, after changing test to use Mock clock / DriveIO rather than DriveIOUntil.
-    // Issue: https://github.com/project-chip/connectedhomeip/issues/32440
-    // NL_TEST_DEF("Test an application response that comes after MRP retransmits run out",
-    //            TestReliableMessageProtocol::CheckApplicationResponseDelayed),
-    NL_TEST_DEF("Test an application response that never comes, so MRP retransmits run out and then exchange times out",
-                TestReliableMessageProtocol::CheckApplicationResponseNeverComes),
-    NL_TEST_SENTINEL(),
-};
-
-// clang-format off
-nlTestSuite sSuite = {
-    "Test-CHIP-ReliableMessageProtocol",
-    &sTests[0],
-    NL_TEST_WRAP_FUNCTION(TestContext::SetUpTestSuite),
-    NL_TEST_WRAP_FUNCTION(TestContext::TearDownTestSuite),
-    NL_TEST_WRAP_METHOD(TestContext, SetUp),
-    NL_TEST_WRAP_METHOD(TestContext, TearDown),
-};
-// clang-format on
-
-int TestReliableMessageProtocolSuite()
-{
-    return chip::ExecuteTestsWithContext<TestContext>(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestReliableMessageProtocolSuite)
diff --git a/src/test_driver/nrfconnect/main/runner.cpp b/src/test_driver/nrfconnect/main/runner.cpp
index 1cd57d0bbbd406..d779f1d5300d09 100644
--- a/src/test_driver/nrfconnect/main/runner.cpp
+++ b/src/test_driver/nrfconnect/main/runner.cpp
@@ -35,8 +35,9 @@ extern "C" int main(void)
     VerifyOrDie(settings_subsys_init() == 0);
 
     LOG_INF("Starting CHIP tests!");
-    int status = RunRegisteredUnitTests();
+    int status = 0;
     status += chip::test::RunAllTests();
+    status += RunRegisteredUnitTests();
     LOG_INF("CHIP test status: %d", status);
 
     _exit(status);
diff --git a/src/test_driver/openiotsdk/unit-tests/test_components.txt b/src/test_driver/openiotsdk/unit-tests/test_components.txt
index 8c59caffcf8de4..35ba62bc492d6d 100644
--- a/src/test_driver/openiotsdk/unit-tests/test_components.txt
+++ b/src/test_driver/openiotsdk/unit-tests/test_components.txt
@@ -20,3 +20,4 @@ SecureChannelTests
 ICDServerTests
 DataModelTests
 InetLayerTests
+MessagingLayerTests
diff --git a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
index 55ebc4e3cd7e7e..d57fda14efe12f 100644
--- a/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
+++ b/src/test_driver/openiotsdk/unit-tests/test_components_nl.txt
@@ -1,3 +1,2 @@
 AppTests
-MessagingLayerTests
 SecureChannelTestsNL