diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn
index c1973be185cbac..afb9a2ae66f12b 100644
--- a/src/app/tests/BUILD.gn
+++ b/src/app/tests/BUILD.gn
@@ -139,12 +139,24 @@ chip_test_suite("tests") {
   output_name = "libAppTests"
 
   test_sources = [
+    "TestAttributeAccessInterfaceCache.cpp",
+    "TestAttributePathExpandIterator.cpp",
+    "TestAttributePersistenceProvider.cpp",
+    "TestAttributeValueDecoder.cpp",
+    "TestAttributeValueEncoder.cpp",
     "TestBindingTable.cpp",
     "TestBuilderParser.cpp",
     "TestMessageDef.cpp",
     "TestNullable.cpp",
+    "TestNumericAttributeTraits.cpp",
+    "TestOperationalStateClusterObjects.cpp",
+    "TestPendingNotificationMap.cpp",
+    "TestPendingResponseTrackerImpl.cpp",
+    "TestPowerSourceCluster.cpp",
     "TestStatusIB.cpp",
     "TestStatusResponseMessage.cpp",
+    "TestTestEventTriggerDelegate.cpp",
+    "TestTimeSyncDataProvider.cpp",
   ]
 
   if (!chip_fake_platform) {
@@ -158,6 +170,7 @@ chip_test_suite("tests") {
     ":ember-apptest-compatibility",
     ":operational-state-test-srcs",
     ":ota-requestor-test-srcs",
+    ":power-cluster-test-srcs",
     ":time-sync-data-provider-test-srcs",
     "${chip_root}/src/app",
     "${chip_root}/src/app/common:cluster-objects",
@@ -165,9 +178,15 @@ chip_test_suite("tests") {
     "${chip_root}/src/app/tests:helpers",
     "${chip_root}/src/app/util/mock:mock_ember",
     "${chip_root}/src/lib/core",
+    "${chip_root}/src/lib/core:string-builder-adapters",
     "${chip_root}/src/lib/support:test_utils",
     "${chip_root}/src/lib/support:testing",
   ]
+
+  # DefaultICDClientStorage assumes that raw AES key is used by the application
+  if (chip_crypto != "psa") {
+    test_sources += [ "TestDefaultICDClientStorage.cpp" ]
+  }
 }
 
 chip_test_suite_using_nltest("tests_nltest") {
@@ -176,11 +195,6 @@ chip_test_suite_using_nltest("tests_nltest") {
   test_sources = [
     "TestAclAttribute.cpp",
     "TestAclEvent.cpp",
-    "TestAttributeAccessInterfaceCache.cpp",
-    "TestAttributePathExpandIterator.cpp",
-    "TestAttributePersistenceProvider.cpp",
-    "TestAttributeValueDecoder.cpp",
-    "TestAttributeValueEncoder.cpp",
     "TestBasicCommandPathRegistry.cpp",
     "TestClusterInfo.cpp",
     "TestCommandInteraction.cpp",
@@ -193,24 +207,12 @@ chip_test_suite_using_nltest("tests_nltest") {
     "TestEventPathParams.cpp",
     "TestFabricScopedEventLogging.cpp",
     "TestInteractionModelEngine.cpp",
-    "TestNumericAttributeTraits.cpp",
-    "TestOperationalStateClusterObjects.cpp",
-    "TestPendingNotificationMap.cpp",
-    "TestPendingResponseTrackerImpl.cpp",
-    "TestPowerSourceCluster.cpp",
     "TestReadInteraction.cpp",
     "TestReportingEngine.cpp",
-    "TestTestEventTriggerDelegate.cpp",
-    "TestTimeSyncDataProvider.cpp",
     "TestTimedHandler.cpp",
     "TestWriteInteraction.cpp",
   ]
 
-  # DefaultICDClientStorage assumes that raw AES key is used by the application
-  if (chip_crypto != "psa") {
-    test_sources += [ "TestDefaultICDClientStorage.cpp" ]
-  }
-
   #
   # On NRF platforms, the allocation of a large number of pbufs in this test
   # to exercise chunking causes it to run out of memory. For now, disable it there.
diff --git a/src/app/tests/TestAttributeAccessInterfaceCache.cpp b/src/app/tests/TestAttributeAccessInterfaceCache.cpp
index 47b8e6d921de94..28aa91db42b16f 100644
--- a/src/app/tests/TestAttributeAccessInterfaceCache.cpp
+++ b/src/app/tests/TestAttributeAccessInterfaceCache.cpp
@@ -18,15 +18,15 @@
 
 #include <app/AttributeAccessInterface.h>
 #include <app/AttributeAccessInterfaceCache.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <lib/core/StringBuilderAdapters.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 using namespace chip::app;
 
 namespace {
 
-void TestBasicLifecycle(nlTestSuite * inSuite, void * inContext)
+TEST(TestAttributeAccessInterfaceCache, TestBasicLifecycle)
 {
     using CacheResult = AttributeAccessInterfaceCache::CacheResult;
 
@@ -44,86 +44,58 @@ void TestBasicLifecycle(nlTestSuite * inSuite, void * inContext)
     // Cache can keep track of at least 1 entry,
     AttributeAccessInterface * entry = nullptr;
 
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, entry == nullptr);
+    EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(entry, nullptr);
     cache.MarkUsed(1, 1, accessor1);
 
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kDefinitelyUsed);
-    NL_TEST_ASSERT(inSuite, entry == accessor1);
+    EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kDefinitelyUsed);
+    EXPECT_EQ(entry, accessor1);
 
     entry = nullptr;
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, entry == nullptr);
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, entry == nullptr);
+    EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(entry, nullptr);
+    EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(entry, nullptr);
 
     cache.MarkUsed(1, 2, accessor1);
 
     entry = nullptr;
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kDefinitelyUsed);
-    NL_TEST_ASSERT(inSuite, entry == accessor1);
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss);
+    EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kDefinitelyUsed);
+    EXPECT_EQ(entry, accessor1);
+    EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss);
 
     cache.MarkUsed(1, 2, accessor2);
 
     entry = nullptr;
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kDefinitelyUsed);
-    NL_TEST_ASSERT(inSuite, entry == accessor2);
+    EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kDefinitelyUsed);
+    EXPECT_EQ(entry, accessor2);
     // The following should not crash (e.g. output not used if nullptr).
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, nullptr) == CacheResult::kDefinitelyUsed);
+    EXPECT_EQ(cache.Get(1, 2, nullptr), CacheResult::kDefinitelyUsed);
 
     // Setting used to nullptr == does not mark used.
     cache.MarkUsed(1, 2, nullptr);
     entry = nullptr;
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, entry == nullptr);
+    EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(entry, nullptr);
 
     cache.Invalidate();
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 1, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, entry == nullptr);
-    NL_TEST_ASSERT(inSuite, cache.Get(1, 2, &entry) == CacheResult::kCacheMiss);
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 1, &entry) == CacheResult::kCacheMiss);
+    EXPECT_EQ(cache.Get(1, 1, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(entry, nullptr);
+    EXPECT_EQ(cache.Get(1, 2, &entry), CacheResult::kCacheMiss);
+    EXPECT_EQ(cache.Get(2, 1, &entry), CacheResult::kCacheMiss);
 
     // Marking unused works, keeps single entry, and is invalidated when invalidated fully.
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) != CacheResult::kDefinitelyUnused);
-    NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused);
+    EXPECT_NE(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused);
+    EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused);
     cache.MarkUnused(2, 2);
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) == CacheResult::kDefinitelyUnused);
-    NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused);
+    EXPECT_EQ(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused);
+    EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused);
 
     cache.MarkUnused(3, 3);
-    NL_TEST_ASSERT(inSuite, cache.Get(2, 2, nullptr) != CacheResult::kDefinitelyUnused);
-    NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) == CacheResult::kDefinitelyUnused);
+    EXPECT_NE(cache.Get(2, 2, nullptr), CacheResult::kDefinitelyUnused);
+    EXPECT_EQ(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused);
 
     cache.Invalidate();
-    NL_TEST_ASSERT(inSuite, cache.Get(3, 3, nullptr) != CacheResult::kDefinitelyUnused);
+    EXPECT_NE(cache.Get(3, 3, nullptr), CacheResult::kDefinitelyUnused);
 }
-
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("Basic AttributeAccessInterfaceCache lifecycle works", TestBasicLifecycle),
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
 } // namespace
-
-int TestAttributeAccessInterfaceCache()
-{
-    // clang-format off
-    nlTestSuite theSuite =
-    {
-        "Test for AttributeAccessInterface cache utility",
-        &sTests[0],
-        nullptr,
-        nullptr
-    };
-    // clang-format on
-
-    nlTestRunner(&theSuite, nullptr);
-
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAttributeAccessInterfaceCache)
diff --git a/src/app/tests/TestAttributePathExpandIterator.cpp b/src/app/tests/TestAttributePathExpandIterator.cpp
index e5505320193b81..309ca1386905f5 100644
--- a/src/app/tests/TestAttributePathExpandIterator.cpp
+++ b/src/app/tests/TestAttributePathExpandIterator.cpp
@@ -22,14 +22,13 @@
 #include <app/EventManagement.h>
 #include <app/util/mock/Constants.h>
 #include <lib/core/CHIPCore.h>
+#include <lib/core/StringBuilderAdapters.h>
 #include <lib/core/TLVDebug.h>
 #include <lib/support/CodeUtils.h>
 #include <lib/support/DLLUtil.h>
 #include <lib/support/LinkedList.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <lib/support/logging/CHIPLogging.h>
-
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 using namespace chip::Test;
@@ -39,7 +38,7 @@ namespace {
 
 using P = app::ConcreteAttributePath;
 
-void TestAllWildcard(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestAllWildcard)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
 
@@ -136,17 +135,18 @@ void TestAllWildcard(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestWildcardEndpoint)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
-    clusInfo.mValue.mClusterId   = Test::MockClusterId(3);
-    clusInfo.mValue.mAttributeId = Test::MockAttributeId(3);
+    clusInfo.mValue.mClusterId   = chip::Test::MockClusterId(3);
+    clusInfo.mValue.mAttributeId = chip::Test::MockAttributeId(3);
 
     app::ConcreteAttributePath path;
     P paths[] = {
@@ -159,16 +159,17 @@ void TestWildcardEndpoint(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestWildcardCluster(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestWildcardCluster)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
-    clusInfo.mValue.mEndpointId  = Test::kMockEndpoint3;
+    clusInfo.mValue.mEndpointId  = chip::Test::kMockEndpoint3;
     clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id;
 
     app::ConcreteAttributePath path;
@@ -185,16 +186,17 @@ void TestWildcardCluster(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestWildcardClusterGlobalAttributeNotInMetadata)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
-    clusInfo.mValue.mEndpointId  = Test::kMockEndpoint3;
+    clusInfo.mValue.mEndpointId  = chip::Test::kMockEndpoint3;
     clusInfo.mValue.mAttributeId = app::Clusters::Globals::Attributes::AttributeList::Id;
 
     app::ConcreteAttributePath path;
@@ -211,17 +213,18 @@ void TestWildcardClusterGlobalAttributeNotInMetadata(nlTestSuite * apSuite, void
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestWildcardAttribute)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
-    clusInfo.mValue.mEndpointId = Test::kMockEndpoint2;
-    clusInfo.mValue.mClusterId  = Test::MockClusterId(3);
+    clusInfo.mValue.mEndpointId = chip::Test::kMockEndpoint2;
+    clusInfo.mValue.mClusterId  = chip::Test::MockClusterId(3);
 
     app::ConcreteAttributePath path;
     P paths[] = {
@@ -244,18 +247,19 @@ void TestWildcardAttribute(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestNoWildcard(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestNoWildcard)
 {
     SingleLinkedListNode<app::AttributePathParams> clusInfo;
-    clusInfo.mValue.mEndpointId  = Test::kMockEndpoint2;
-    clusInfo.mValue.mClusterId   = Test::MockClusterId(3);
-    clusInfo.mValue.mAttributeId = Test::MockAttributeId(3);
+    clusInfo.mValue.mEndpointId  = chip::Test::kMockEndpoint2;
+    clusInfo.mValue.mClusterId   = chip::Test::MockClusterId(3);
+    clusInfo.mValue.mAttributeId = chip::Test::MockAttributeId(3);
 
     app::ConcreteAttributePath path;
     P paths[] = {
@@ -268,33 +272,34 @@ void TestNoWildcard(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-void TestMultipleClusInfo(nlTestSuite * apSuite, void * apContext)
+TEST(TestAttributePathExpandIterator, TestMultipleClusInfo)
 {
 
     SingleLinkedListNode<app::AttributePathParams> clusInfo1;
 
     SingleLinkedListNode<app::AttributePathParams> clusInfo2;
-    clusInfo2.mValue.mClusterId   = Test::MockClusterId(3);
-    clusInfo2.mValue.mAttributeId = Test::MockAttributeId(3);
+    clusInfo2.mValue.mClusterId   = chip::Test::MockClusterId(3);
+    clusInfo2.mValue.mAttributeId = chip::Test::MockAttributeId(3);
 
     SingleLinkedListNode<app::AttributePathParams> clusInfo3;
-    clusInfo3.mValue.mEndpointId  = Test::kMockEndpoint3;
+    clusInfo3.mValue.mEndpointId  = chip::Test::kMockEndpoint3;
     clusInfo3.mValue.mAttributeId = app::Clusters::Globals::Attributes::ClusterRevision::Id;
 
     SingleLinkedListNode<app::AttributePathParams> clusInfo4;
-    clusInfo4.mValue.mEndpointId = Test::kMockEndpoint2;
-    clusInfo4.mValue.mClusterId  = Test::MockClusterId(3);
+    clusInfo4.mValue.mEndpointId = chip::Test::kMockEndpoint2;
+    clusInfo4.mValue.mClusterId  = chip::Test::MockClusterId(3);
 
     SingleLinkedListNode<app::AttributePathParams> clusInfo5;
-    clusInfo5.mValue.mEndpointId  = Test::kMockEndpoint2;
-    clusInfo5.mValue.mClusterId   = Test::MockClusterId(3);
-    clusInfo5.mValue.mAttributeId = Test::MockAttributeId(3);
+    clusInfo5.mValue.mEndpointId  = chip::Test::kMockEndpoint2;
+    clusInfo5.mValue.mClusterId   = chip::Test::MockClusterId(3);
+    clusInfo5.mValue.mAttributeId = chip::Test::MockAttributeId(3);
 
     clusInfo1.mpNext = &clusInfo2;
     clusInfo2.mpNext = &clusInfo3;
@@ -411,60 +416,11 @@ void TestMultipleClusInfo(nlTestSuite * apSuite, void * apContext)
     {
         ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId,
                       ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId));
-        NL_TEST_ASSERT(apSuite, index < ArraySize(paths) && paths[index] == path);
+        EXPECT_LT(index, ArraySize(paths));
+        EXPECT_EQ(paths[index], path);
         index++;
     }
-    NL_TEST_ASSERT(apSuite, index == ArraySize(paths));
+    EXPECT_EQ(index, ArraySize(paths));
 }
 
-static int TestSetup(void * inContext)
-{
-    return SUCCESS;
-}
-
-/**
- *  Tear down the test suite.
- */
-static int TestTeardown(void * inContext)
-{
-    return SUCCESS;
-}
-
-/**
- *   Test Suite. It lists all the test functions.
- */
-
-// clang-format off
-const nlTest sTests[] =
-{
-        NL_TEST_DEF("TestAllWildcard", TestAllWildcard),
-        NL_TEST_DEF("TestWildcardEndpoint", TestWildcardEndpoint),
-        NL_TEST_DEF("TestWildcardCluster", TestWildcardCluster),
-        NL_TEST_DEF("TestWildcardClusterGlobalAttributeNotInMetadata",
-                    TestWildcardClusterGlobalAttributeNotInMetadata),
-        NL_TEST_DEF("TestWildcardAttribute", TestWildcardAttribute),
-        NL_TEST_DEF("TestNoWildcard", TestNoWildcard),
-        NL_TEST_DEF("TestMultipleClusInfo", TestMultipleClusInfo),
-        NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "TestAttributePathExpandIterator",
-    &sTests[0],
-    TestSetup,
-    TestTeardown,
-};
-// clang-format on
-
 } // namespace
-
-int TestAttributePathExpandIterator()
-{
-    nlTestRunner(&sSuite, nullptr);
-    return (nlTestRunnerStats(&sSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAttributePathExpandIterator)
diff --git a/src/app/tests/TestAttributePersistenceProvider.cpp b/src/app/tests/TestAttributePersistenceProvider.cpp
index 9c75715d14e03d..feda9e6d154bc1 100644
--- a/src/app/tests/TestAttributePersistenceProvider.cpp
+++ b/src/app/tests/TestAttributePersistenceProvider.cpp
@@ -24,9 +24,9 @@
 
 #include <app-common/zap-generated/cluster-objects.h>
 #include <app/DefaultAttributePersistenceProvider.h>
+#include <lib/core/StringBuilderAdapters.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 using namespace chip::app;
@@ -36,48 +36,36 @@ const ConcreteAttributePath TestConcretePath = ConcreteAttributePath(1, 1, 1);
 
 namespace {
 
-/**
- *  Set up the test suite.
- */
-int Test_Setup(void * inContext)
-{
-    CHIP_ERROR error = chip::Platform::MemoryInit();
-    VerifyOrReturnError(error == CHIP_NO_ERROR, FAILURE);
-    return SUCCESS;
-}
-
-/**
- *  Tear down the test suite.
- */
-int Test_Teardown(void * inContext)
+class TestAttributePersistenceProvider : public ::testing::Test
 {
-    chip::Platform::MemoryShutdown();
-    return SUCCESS;
-}
+public:
+    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
+    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
+};
 
 /**
  * Tests the storage and retrival of data from the KVS as ByteSpan
  */
-void TestStorageAndRetrivalByteSpans(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalByteSpans)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     ChipError err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Store ByteSpan of size 1
     uint8_t valueArray[1] = { 0x42 };
     ByteSpan value(valueArray);
     err = persistenceProvider.SafeWriteValue(TestConcretePath, value);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     uint8_t getArray[1];
     MutableByteSpan valueReadBack(getArray);
     err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
 
     // Finishing
     persistenceProvider.Shutdown();
@@ -89,17 +77,16 @@ void TestStorageAndRetrivalByteSpans(nlTestSuite * inSuite, void * inContext)
  * @param testValue The test value to store and retrieve
  */
 template <typename T>
-void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider,
-                                              T testValue)
+void testHelperStorageAndRetrivalScalarValues(DefaultAttributePersistenceProvider & persistenceProvider, T testValue)
 {
     CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     T valueReadBack = 0;
     err             = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, valueReadBack == testValue);
+    EXPECT_EQ(valueReadBack, testValue);
 }
 
 /**
@@ -108,55 +95,55 @@ void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttr
  * @param testValue The test value to store and retrieve
  */
 template <typename T>
-void testHelperStorageAndRetrivalScalarValues(nlTestSuite * inSuite, DefaultAttributePersistenceProvider & persistenceProvider,
+void testHelperStorageAndRetrivalScalarValues(DefaultAttributePersistenceProvider & persistenceProvider,
                                               DataModel::Nullable<T> testValue)
 {
     CHIP_ERROR err = persistenceProvider.WriteScalarValue(TestConcretePath, testValue);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     DataModel::Nullable<T> valueReadBack(0);
     err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, valueReadBack == testValue);
+    EXPECT_EQ(valueReadBack, testValue);
 }
 
 /**
  * Tests the storage and retrival of data from the KVS of types  bool, uint8_t, uint16_t, uint32_t, uint64_t.
  */
-void TestStorageAndRetrivalScalarValues(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalScalarValues)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Test bool
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(false));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, bool(true));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(true));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(false));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, bool(true));
 
     // Test uint8_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(42));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint8_t(0xff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(42));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint8_t(0xff));
 
     // Test uint16_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0x0101));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint16_t(0xffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0x0101));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint16_t(0xffff));
 
     // Test uint32_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0x01ffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint32_t(0xffffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0x01ffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint32_t(0xffffffff));
 
     // Test uint64_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0x0100000001));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, uint64_t(0xffffffffffffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0x0100000001));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, uint64_t(0xffffffffffffffff));
 
     // Finishing
     persistenceProvider.Shutdown();
@@ -165,34 +152,34 @@ void TestStorageAndRetrivalScalarValues(nlTestSuite * inSuite, void * inContext)
 /**
  * Tests the storage and retrival of data from the KVS of types  int8_t, int16_t, int32_t, int64_t.
  */
-void TestStorageAndRetrivalSignedScalarValues(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalSignedScalarValues)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Test int8_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(42));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int8_t(-127));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(42));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int8_t(-127));
 
     // Test int16_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x7fff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int16_t(0x8000));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0x7fff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int16_t(0x8000));
 
     // Test int32_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x7fffffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int32_t(0x80000000));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0x7fffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int32_t(0x80000000));
 
     // Test int64_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x7fffffffffffffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, int64_t(0x8000000000000000));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0x7fffffffffffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, int64_t(0x8000000000000000));
 
     // Finishing
     persistenceProvider.Shutdown();
@@ -201,54 +188,54 @@ void TestStorageAndRetrivalSignedScalarValues(nlTestSuite * inSuite, void * inCo
 /**
  * Tests the storage and retrival of data from the KVS of DataModel::Nullable types bool, uint8_t, uint16_t, uint32_t, uint64_t.
  */
-void TestStorageAndRetrivalNullableScalarValues(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalNullableScalarValues)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Test bool
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(true));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(false));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<bool>(true));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<bool>(true));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<bool>(false));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<bool>(true));
     auto nullValBool = DataModel::Nullable<bool>();
     nullValBool.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullValBool);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullValBool);
 
     // Test uint8_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(42));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint8_t>(0xfe));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint8_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint8_t>(42));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint8_t>(0xfe));
     auto nullVal8 = DataModel::Nullable<uint8_t>();
     nullVal8.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal8);
 
     // Test uint16_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0x0101));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint16_t>(0xfffe));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint16_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint16_t>(0x0101));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint16_t>(0xfffe));
     auto nullVal16 = DataModel::Nullable<uint16_t>();
     nullVal16.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal16);
 
     // Test uint32_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0x01ffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint32_t>(0xfffffffe));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint32_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint32_t>(0x01ffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint32_t>(0xfffffffe));
     auto nullVal32 = DataModel::Nullable<uint32_t>();
     nullVal32.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal32);
 
     // Test uint64_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0x0100000001));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<uint64_t>(0xfffffffffffffffe));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint64_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint64_t>(0x0100000001));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<uint64_t>(0xfffffffffffffffe));
     auto nullVal64 = DataModel::Nullable<uint64_t>();
     nullVal64.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal64);
 
     // Finishing
     persistenceProvider.Shutdown();
@@ -257,46 +244,46 @@ void TestStorageAndRetrivalNullableScalarValues(nlTestSuite * inSuite, void * in
 /**
  * Tests the storage and retrival of data from the KVS of DataModel::Nullable types int8_t, int16_t, int32_t, int64_t.
  */
-void TestStorageAndRetrivalSignedNullableScalarValues(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestStorageAndRetrivalSignedNullableScalarValues)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Test int8_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(42));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int8_t>(-127));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int8_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int8_t>(42));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int8_t>(-127));
     auto nullVal8 = DataModel::Nullable<int8_t>();
     nullVal8.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal8);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal8);
 
     // Test int16_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(0x7fff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int16_t>(-0x7fff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int16_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int16_t>(0x7fff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int16_t>(-0x7fff));
     auto nullVal16 = DataModel::Nullable<int16_t>();
     nullVal16.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal16);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal16);
 
     // Test int32_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(0x7fffffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int32_t>(-0x7fffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int32_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int32_t>(0x7fffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int32_t>(-0x7fffffff));
     auto nullVal32 = DataModel::Nullable<int32_t>();
     nullVal32.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal32);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal32);
 
     // Test int64_t
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(0));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(0x7fffffffffffffff));
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, DataModel::Nullable<int64_t>(-0x7fffffffffffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int64_t>(0));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int64_t>(0x7fffffffffffffff));
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, DataModel::Nullable<int64_t>(-0x7fffffffffffffff));
     auto nullVal64 = DataModel::Nullable<int64_t>();
     nullVal64.SetNull();
-    testHelperStorageAndRetrivalScalarValues(inSuite, persistenceProvider, nullVal64);
+    testHelperStorageAndRetrivalScalarValues(persistenceProvider, nullVal64);
 
     // Finishing
     persistenceProvider.Shutdown();
@@ -305,85 +292,62 @@ void TestStorageAndRetrivalSignedNullableScalarValues(nlTestSuite * inSuite, voi
 /**
  * Test that the correct error is given when trying to read a value with a buffer that's too small.
  */
-void TestBufferTooSmallErrors(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestAttributePersistenceProvider, TestBufferTooSmallErrors)
 {
     TestPersistentStorageDelegate storageDelegate;
     DefaultAttributePersistenceProvider persistenceProvider;
 
     // Init
     CHIP_ERROR err = persistenceProvider.Init(&storageDelegate);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Store large data
     uint8_t valueArray[9] = { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 };
     ByteSpan value(valueArray);
     err = persistenceProvider.SafeWriteValue(TestConcretePath, value);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Confirm the daya is there
     uint8_t getArray[9];
     MutableByteSpan valueReadBack(getArray);
     err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBack);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_TRUE(std::equal(valueReadBack.begin(), valueReadBack.end(), value.begin(), value.end()));
 
     // Fail to get data as ByteSpace of size 0
     uint8_t getArray0[0];
     MutableByteSpan valueReadBackByteSpan0(getArray0, 0);
     err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan0);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Fail to get data as ByteSpace of size > 0 but < required
     uint8_t getArray8[8];
     MutableByteSpan valueReadBackByteSpan8(getArray8, sizeof(getArray8));
     err = persistenceProvider.SafeReadValue(TestConcretePath, valueReadBackByteSpan8);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Fail to get value as uint8_t
     uint8_t valueReadBack8;
     err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack8);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Fail to get value as uint16_t
     uint16_t valueReadBack16;
     err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack16);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Fail to get value as uint32_t
     uint32_t valueReadBack32;
     err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack32);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Fail to get value as uint64_t
     uint64_t valueReadBack64;
     err = persistenceProvider.ReadScalarValue(TestConcretePath, valueReadBack64);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
 
     // Finishing
     persistenceProvider.Shutdown();
 }
 
 } // anonymous namespace
-
-namespace {
-const nlTest sTests[] = {
-    NL_TEST_DEF("Storage and retrival of ByteSpans", TestStorageAndRetrivalByteSpans),
-    NL_TEST_DEF("Storage and retrival of unsigned scalar values", TestStorageAndRetrivalScalarValues),
-    NL_TEST_DEF("Storage and retrival of signed scalar values", TestStorageAndRetrivalSignedScalarValues),
-    NL_TEST_DEF("Storage and retrival of unsigned nullable scalar values", TestStorageAndRetrivalNullableScalarValues),
-    NL_TEST_DEF("Storage and retrival of signed nullable scalar values", TestStorageAndRetrivalSignedNullableScalarValues),
-    NL_TEST_DEF("Small buffer errors", TestBufferTooSmallErrors),
-    NL_TEST_SENTINEL()
-};
-}
-
-int TestAttributePersistenceProvider()
-{
-    nlTestSuite theSuite = { "AttributePersistenceProvider", &sTests[0], Test_Setup, Test_Teardown };
-
-    nlTestRunner(&theSuite, nullptr);
-
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAttributePersistenceProvider)
diff --git a/src/app/tests/TestAttributeValueDecoder.cpp b/src/app/tests/TestAttributeValueDecoder.cpp
index c25738588e6afa..b63e66464e885d 100644
--- a/src/app/tests/TestAttributeValueDecoder.cpp
+++ b/src/app/tests/TestAttributeValueDecoder.cpp
@@ -18,16 +18,17 @@
 
 /**
  *    @file
- *      This file implements unit tests for CommandPathParams
+ *      This file implements unit tests for AttributeValueDecoder
  *
  */
 
+#include <lib/core/StringBuilderAdapters.h>
+#include <pw_unit_test/framework.h>
+
 #include <app-common/zap-generated/cluster-objects.h>
 #include <app/AttributeValueDecoder.h>
 #include <app/MessageDef/AttributeDataIB.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
 
 using namespace chip;
 using namespace chip::app;
@@ -62,7 +63,7 @@ struct TestSetup
     TLVWriter writer;
 };
 
-void TestOverwriteFabricIndexInStruct(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueDecoder, TestOverwriteFabricIndexInStruct)
 {
     TestSetup setup;
     CHIP_ERROR err;
@@ -73,29 +74,29 @@ void TestOverwriteFabricIndexInStruct(nlTestSuite * aSuite, void * aContext)
     item.fabricIndex = 0;
 
     err = setup.Encode(item);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     TLV::TLVReader reader;
     TLVType ignored;
     reader.Init(setup.buf, setup.writer.GetLengthWritten());
 
     err = reader.Next();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = reader.EnterContainer(ignored);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = reader.Next();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     AttributeValueDecoder decoder(reader, subjectDescriptor);
     err = decoder.Decode(decodeItem);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, decodeItem.fabricIndex == kTestFabricIndex);
+    EXPECT_EQ(decodeItem.fabricIndex, kTestFabricIndex);
 }
 
-void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueDecoder, TestOverwriteFabricIndexInListOfStructs)
 {
     TestSetup setup;
     CHIP_ERROR err;
@@ -109,7 +110,7 @@ void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aConte
     }
 
     err = setup.Encode(DataModel::List<Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type>(items));
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     TLV::TLVReader reader;
     TLVType ignored;
@@ -118,44 +119,27 @@ void TestOverwriteFabricIndexInListOfStructs(nlTestSuite * aSuite, void * aConte
     reader.Init(setup.buf, setup.writer.GetLengthWritten());
 
     err = reader.Next();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = reader.EnterContainer(ignored);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = reader.Next();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     AttributeValueDecoder decoder(reader, subjectDescriptor);
     err = decoder.Decode(decodeItems);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = decodeItems.ComputeSize(&decodeCount);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, decodeCount == kTestListElements);
+    EXPECT_EQ(decodeCount, kTestListElements);
     for (auto iter = decodeItems.begin(); iter.Next();)
     {
         const auto & entry = iter.GetValue();
-        NL_TEST_ASSERT(aSuite, entry.fabricIndex == kTestFabricIndex);
+        EXPECT_EQ(entry.fabricIndex, kTestFabricIndex);
     }
 }
 
 } // anonymous namespace
-
-namespace {
-const nlTest sTests[] = { NL_TEST_DEF("TestOverwriteFabricIndexInStruct", TestOverwriteFabricIndexInStruct),
-                          NL_TEST_DEF("TestOverwriteFabricIndexInListOfStructs", TestOverwriteFabricIndexInListOfStructs),
-                          NL_TEST_SENTINEL() };
-}
-
-int TestAttributeValueDecoder()
-{
-    nlTestSuite theSuite = { "AttributeValueDecoder", &sTests[0], nullptr, nullptr };
-
-    nlTestRunner(&theSuite, nullptr);
-
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAttributeValueDecoder)
diff --git a/src/app/tests/TestAttributeValueEncoder.cpp b/src/app/tests/TestAttributeValueEncoder.cpp
index 085c4f870cdf64..77a344b6bd6572 100644
--- a/src/app/tests/TestAttributeValueEncoder.cpp
+++ b/src/app/tests/TestAttributeValueEncoder.cpp
@@ -18,10 +18,15 @@
 
 /**
  *    @file
- *      This file implements unit tests for CommandPathParams
+ *      This file implements unit tests for AttributeValueEncoder
  *
  */
 
+#include <optional>
+
+#include <lib/core/StringBuilderAdapters.h>
+#include <pw_unit_test/framework.h>
+
 #include <app-common/zap-generated/cluster-objects.h>
 #include <app/AttributeValueEncoder.h>
 #include <app/MessageDef/AttributeDataIB.h>
@@ -30,10 +35,6 @@
 #include <lib/core/TLVTags.h>
 #include <lib/core/TLVWriter.h>
 #include <lib/support/CodeUtils.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
-
-#include <optional>
 
 using namespace chip;
 using namespace chip::app;
@@ -75,7 +76,7 @@ Access::SubjectDescriptor DescriptorWithFabric(FabricIndex fabricIndex)
 template <size_t N>
 struct LimitedTestSetup
 {
-    LimitedTestSetup(nlTestSuite * aSuite, const FabricIndex aFabricIndex = kUndefinedFabricIndex,
+    LimitedTestSetup(const FabricIndex aFabricIndex      = kUndefinedFabricIndex,
                      const AttributeEncodeState & aState = AttributeEncodeState()) :
         encoder(builder, DescriptorWithFabric(aFabricIndex),
                 ConcreteAttributePath(kRandomEndpointId, kRandomClusterId, kRandomAttributeId), kRandomDataVersion,
@@ -85,11 +86,11 @@ struct LimitedTestSetup
         {
             TLVType ignored;
             CHIP_ERROR err = writer.StartContainer(AnonymousTag(), kTLVType_Structure, ignored);
-            NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
         }
         {
             CHIP_ERROR err = builder.Init(&writer, 1);
-            NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+            EXPECT_EQ(err, CHIP_NO_ERROR);
         }
     }
 
@@ -103,11 +104,11 @@ using TestSetup = LimitedTestSetup<1024>;
 
 // Macro so we get better error reporting in terms of which test failed, because
 // the reporting uses __LINE__.
-#define VERIFY_BUFFER_STATE(aSuite, aSetup, aExpected)                                                                             \
+#define VERIFY_BUFFER_STATE(aSetup, aExpected)                                                                                     \
     do                                                                                                                             \
     {                                                                                                                              \
-        NL_TEST_ASSERT(aSuite, aSetup.writer.GetLengthWritten() == sizeof(aExpected));                                             \
-        NL_TEST_ASSERT(aSuite, memcmp(aSetup.buf, aExpected, sizeof(aExpected)) == 0);                                             \
+        EXPECT_EQ(aSetup.writer.GetLengthWritten(), sizeof(aExpected));                                                            \
+        EXPECT_EQ(memcmp(aSetup.buf, aExpected, sizeof(aExpected)), 0);                                                            \
         if (aSetup.writer.GetLengthWritten() != sizeof(aExpected) || memcmp(aSetup.buf, aExpected, sizeof(aExpected)) != 0)        \
         {                                                                                                                          \
             printf("Encoded: \n");                                                                                                 \
@@ -125,19 +126,19 @@ using TestSetup = LimitedTestSetup<1024>;
         }                                                                                                                          \
     } while (0)
 
-void TestEncodeNothing(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeNothing)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     // Just have an anonymous struct marker, and the AttributeReportIBs opened.
     const uint8_t expected[] = { 0x15, 0x36, 0x01 };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeBool(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeBool)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     CHIP_ERROR err = test.encoder.Encode(true);
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     const uint8_t expected[] = {
         // clang-format off
         0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01)
@@ -154,15 +155,15 @@ void TestEncodeBool(nlTestSuite * aSuite, void * aContext)
         0x18, // End of container
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeListOfBools1(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListOfBools1)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     bool list[]    = { true, false };
     CHIP_ERROR err = test.encoder.Encode(DataModel::List<bool>(list));
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     const uint8_t expected[] = {
         // clang-format off
         0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01)
@@ -182,12 +183,12 @@ void TestEncodeListOfBools1(nlTestSuite * aSuite, void * aContext)
         0x18, // End of attribute structure
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListOfBools2)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     bool list[]    = { true, false };
     CHIP_ERROR err = test.encoder.EncodeList([&list](const auto & encoder) -> CHIP_ERROR {
         for (auto & item : list)
@@ -196,7 +197,7 @@ void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext)
         }
         return CHIP_NO_ERROR;
     });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     const uint8_t expected[] = {
         // clang-format off
         0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01)
@@ -216,7 +217,7 @@ void TestEncodeListOfBools2(nlTestSuite * aSuite, void * aContext)
         0x18, // End of attribute structure
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
 constexpr uint8_t emptyListExpected[] = {
@@ -238,25 +239,25 @@ constexpr uint8_t emptyListExpected[] = {
     // clang-format on
 };
 
-void TestEncodeEmptyList1(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeEmptyList1)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     CHIP_ERROR err = test.encoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
-    VERIFY_BUFFER_STATE(aSuite, test, emptyListExpected);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    VERIFY_BUFFER_STATE(test, emptyListExpected);
 }
 
-void TestEncodeEmptyList2(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeEmptyList2)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
     CHIP_ERROR err = test.encoder.EncodeEmptyList();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
-    VERIFY_BUFFER_STATE(aSuite, test, emptyListExpected);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    VERIFY_BUFFER_STATE(test, emptyListExpected);
 }
 
-void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeFabricScoped)
 {
-    TestSetup test(aSuite, kTestFabricIndex);
+    TestSetup test(kTestFabricIndex);
     Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type items[3];
     items[0].fabricIndex = 1;
     items[1].fabricIndex = 2;
@@ -270,7 +271,7 @@ void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext)
         }
         return CHIP_NO_ERROR;
     });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     const uint8_t expected[] = {
         // clang-format off
         0x15, 0x36, 0x01, // Test overhead, Start Anonymous struct + Start 1 byte Tag Array + Tag (01)
@@ -292,10 +293,10 @@ void TestEncodeFabricScoped(nlTestSuite * aSuite, void * aContext)
         0x18, // End of attribute structure
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListChunking)
 {
     AttributeEncodeState state;
 
@@ -316,9 +317,9 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext)
         // corresponding to the "test overhead" container starts.  But TLVWriter automatically
         // reserves space when containers are opened, so we have to have enough space to have
         // encoded those last two close containers.
-        LimitedTestSetup<30> test1(aSuite, kTestFabricIndex);
+        LimitedTestSetup<30> test1(kTestFabricIndex);
         CHIP_ERROR err = test1.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
         state = test1.encoder.GetState();
 
         const uint8_t expected[] = {
@@ -340,14 +341,14 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext)
             0x18, // End of attribute structure
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test1, expected);
+        VERIFY_BUFFER_STATE(test1, expected);
     }
     {
         // Use 30 bytes buffer to force chunking after the second "false". The kTestFabricIndex is
         // not effective in this test.
-        LimitedTestSetup<30> test2(aSuite, 0, state);
+        LimitedTestSetup<30> test2(0, state);
         CHIP_ERROR err = test2.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
         state = test2.encoder.GetState();
 
         const uint8_t expected[] = {
@@ -367,13 +368,13 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext)
             0x18, // End of container
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test2, expected);
+        VERIFY_BUFFER_STATE(test2, expected);
     }
     {
         // Allow encoding everything else. The kTestFabricIndex is not effective in this test.
-        TestSetup test3(aSuite, 0, state);
+        TestSetup test3(0, state);
         CHIP_ERROR err = test3.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         const uint8_t expected[] = {
             // clang-format off
@@ -416,11 +417,11 @@ void TestEncodeListChunking(nlTestSuite * aSuite, void * aContext)
             0x18, // End of container
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test3, expected);
+        VERIFY_BUFFER_STATE(test3, expected);
     }
 }
 
-void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListChunking2)
 {
     AttributeEncodeState state;
 
@@ -441,9 +442,9 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
         // corresponding to the "test overhead" container starts.  But TLVWriter automatically
         // reserves space when containers are opened, so we have to have enough space to have
         // encoded those last two close containers.
-        LimitedTestSetup<28> test1(aSuite, kTestFabricIndex);
+        LimitedTestSetup<28> test1(kTestFabricIndex);
         CHIP_ERROR err = test1.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
         state = test1.encoder.GetState();
 
         const uint8_t expected[] = {
@@ -463,14 +464,14 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
             0x18, // End of attribute structure
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test1, expected);
+        VERIFY_BUFFER_STATE(test1, expected);
     }
     {
         // Use 30 bytes buffer to force chunking after the first "true". The kTestFabricIndex is not
         // effective in this test.
-        LimitedTestSetup<30> test2(aSuite, 0, state);
+        LimitedTestSetup<30> test2(0, state);
         CHIP_ERROR err = test2.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
         state = test2.encoder.GetState();
 
         const uint8_t expected[] = {
@@ -490,14 +491,14 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
             0x18, // End of container
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test2, expected);
+        VERIFY_BUFFER_STATE(test2, expected);
     }
     {
         // Use 60 bytes buffer to force chunking after the second "false". The kTestFabricIndex is not
         // effective in this test.
-        LimitedTestSetup<60> test3(aSuite, 0, state);
+        LimitedTestSetup<60> test3(0, state);
         CHIP_ERROR err = test3.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_TRUE(err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL);
         state = test3.encoder.GetState();
 
         const uint8_t expected[] = {
@@ -529,13 +530,13 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
             0x18, // End of container
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test3, expected);
+        VERIFY_BUFFER_STATE(test3, expected);
     }
     {
         // Allow encoding everything else. The kTestFabricIndex is not effective in this test.
-        TestSetup test4(aSuite, 0, state);
+        TestSetup test4(0, state);
         CHIP_ERROR err = test4.encoder.EncodeList(listEncoder);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         const uint8_t expected[] = {
             // clang-format off
@@ -578,27 +579,27 @@ void TestEncodeListChunking2(nlTestSuite * aSuite, void * aContext)
             0x18, // End of container
             // clang-format on
         };
-        VERIFY_BUFFER_STATE(aSuite, test4, expected);
+        VERIFY_BUFFER_STATE(test4, expected);
     }
 }
 
-void TestEncodePreEncoded(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodePreEncoded)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
 
     uint8_t buffer[128];
     TLV::TLVWriter writer;
     writer.Init(buffer);
     // Use a random tag that is not the right tag.
     CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x5678fedc), "hello");
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = writer.Finalize();
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     ByteSpan value(buffer, writer.GetLengthWritten());
     err = test.encoder.Encode(DataModel::PreEncodedValue(value));
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     const uint8_t expected[] = {
         // clang-format off
@@ -616,12 +617,12 @@ void TestEncodePreEncoded(nlTestSuite * aSuite, void * aContext)
         0x18, // End of container
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListOfPreEncoded)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
 
     uint8_t buffers[2][128];
     std::optional<DataModel::PreEncodedValue> values[2];
@@ -631,10 +632,10 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
         writer.Init(buffers[0]);
         // Use a random tag that is not the right tag.
         CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x5678fedc), "hello");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten()));
     }
@@ -644,10 +645,10 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
         writer.Init(buffers[1]);
         // Use a random tag that is not the right tag.
         CHIP_ERROR err = writer.PutString(TLV::ProfileTag(0x1234abcd, 0x00010002), "bye");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten()));
     }
@@ -659,7 +660,7 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
         }
         return CHIP_NO_ERROR;
     });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     const uint8_t expected[] = {
         // clang-format off
@@ -680,12 +681,12 @@ void TestEncodeListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
         0x18, // End of container
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeListOfFabricScopedPreEncoded)
 {
-    TestSetup test(aSuite);
+    TestSetup test{};
 
     uint8_t buffers[2][128];
     std::optional<DataModel::FabricScopedPreEncodedValue> values[2];
@@ -697,19 +698,19 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex
         TLV::TLVType outerContainerType;
         CHIP_ERROR err =
             writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x5678fedc), TLV::kTLVType_Structure, outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.PutString(TLV::ContextTag(7), "hello");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Put(kFabricIndexTag, kTestFabricIndex);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.EndContainer(outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten()));
     }
@@ -721,19 +722,19 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex
         TLV::TLVType outerContainerType;
         CHIP_ERROR err =
             writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x00010002), TLV::kTLVType_Structure, outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.PutString(TLV::ContextTag(7), "bye");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Put(kFabricIndexTag, static_cast<FabricIndex>(kTestFabricIndex + 1));
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.EndContainer(outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten()));
     }
@@ -745,7 +746,7 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex
         }
         return CHIP_NO_ERROR;
     });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     const uint8_t expected[] = {
         // clang-format off
@@ -772,12 +773,12 @@ void TestEncodeListOfFabricScopedPreEncoded(nlTestSuite * aSuite, void * aContex
         0x18, // End of container
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
-void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aContext)
+TEST(TestAttributeValueEncoder, TestEncodeFabricFilteredListOfPreEncoded)
 {
-    TestSetup test(aSuite, kTestFabricIndex);
+    TestSetup test(kTestFabricIndex);
 
     uint8_t buffers[2][128];
     std::optional<DataModel::FabricScopedPreEncodedValue> values[2];
@@ -789,19 +790,19 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont
         TLV::TLVType outerContainerType;
         CHIP_ERROR err =
             writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x5678fedc), TLV::kTLVType_Structure, outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.PutString(TLV::ContextTag(7), "hello");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Put(kFabricIndexTag, kTestFabricIndex);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.EndContainer(outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[0].emplace(ByteSpan(buffers[0], writer.GetLengthWritten()));
     }
@@ -813,19 +814,19 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont
         TLV::TLVType outerContainerType;
         CHIP_ERROR err =
             writer.StartContainer(TLV::ProfileTag(0x1234abcd, 0x00010002), TLV::kTLVType_Structure, outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.PutString(TLV::ContextTag(7), "bye");
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Put(kFabricIndexTag, static_cast<FabricIndex>(kTestFabricIndex + 1));
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.EndContainer(outerContainerType);
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = writer.Finalize();
-        NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         values[1].emplace(ByteSpan(buffers[1], writer.GetLengthWritten()));
     }
@@ -837,7 +838,7 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont
         }
         return CHIP_NO_ERROR;
     });
-    NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     const uint8_t expected[] = {
         // clang-format off
@@ -861,42 +862,9 @@ void TestEncodeFabricFilteredListOfPreEncoded(nlTestSuite * aSuite, void * aCont
         0x18, // End of container
         // clang-format on
     };
-    VERIFY_BUFFER_STATE(aSuite, test, expected);
+    VERIFY_BUFFER_STATE(test, expected);
 }
 
 #undef VERIFY_BUFFER_STATE
 
 } // anonymous namespace
-
-namespace {
-const nlTest sTests[] = {
-    // clang-format off
-    NL_TEST_DEF("TestEncodeNothing", TestEncodeNothing),
-    NL_TEST_DEF("TestEncodeBool", TestEncodeBool),
-    NL_TEST_DEF("TestEncodeEmptyList1", TestEncodeEmptyList1),
-    NL_TEST_DEF("TestEncodeEmptyList2", TestEncodeEmptyList2),
-    NL_TEST_DEF("TestEncodeListOfBools1", TestEncodeListOfBools1),
-    NL_TEST_DEF("TestEncodeListOfBools2", TestEncodeListOfBools2),
-    NL_TEST_DEF("TestEncodeListChunking", TestEncodeListChunking),
-    NL_TEST_DEF("TestEncodeListChunking2", TestEncodeListChunking2),
-    NL_TEST_DEF("TestEncodeFabricScoped", TestEncodeFabricScoped),
-    NL_TEST_DEF("TestEncodePreEncoded", TestEncodePreEncoded),
-    NL_TEST_DEF("TestEncodeListOfPreEncoded", TestEncodeListOfPreEncoded),
-    NL_TEST_DEF("TestEncodeListFabricScopedPreEncoded", TestEncodeListOfPreEncoded),
-    NL_TEST_DEF("TestEncodeListOfFabricScopedPreEncoded", TestEncodeListOfFabricScopedPreEncoded),
-    NL_TEST_DEF("TestEncodeFabricFilteredListOfPreEncoded", TestEncodeFabricFilteredListOfPreEncoded),
-    NL_TEST_SENTINEL()
-    // clang-format on
-};
-}
-
-int TestAttributeValueEncoder()
-{
-    nlTestSuite theSuite = { "AttributeValueEncoder", &sTests[0], nullptr, nullptr };
-
-    nlTestRunner(&theSuite, nullptr);
-
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestAttributeValueEncoder)
diff --git a/src/app/tests/TestDefaultICDClientStorage.cpp b/src/app/tests/TestDefaultICDClientStorage.cpp
index 62787a2c9e4144..e9761656bd192b 100644
--- a/src/app/tests/TestDefaultICDClientStorage.cpp
+++ b/src/app/tests/TestDefaultICDClientStorage.cpp
@@ -17,7 +17,7 @@
 
 #include <lib/support/Span.h>
 #include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 #include <system/SystemPacketBuffer.h>
 
 #include <app/icd/client/DefaultICDClientStorage.h>
@@ -55,7 +55,14 @@ struct TestClientInfo : public ICDClientInfo
     }
 };
 
-void TestClientInfoCount(nlTestSuite * apSuite, void * apContext)
+class TestDefaultICDClientStorage : public ::testing::Test
+{
+public:
+    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
+    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
+};
+
+TEST_F(TestDefaultICDClientStorage, TestClientInfoCount)
 {
     CHIP_ERROR err       = CHIP_NO_ERROR;
     FabricIndex fabricId = 1;
@@ -67,9 +74,9 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext)
     {
         DefaultICDClientStorage manager;
         err = manager.Init(&clientInfoStorage, &keystore);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         err = manager.UpdateFabricList(fabricId);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         // Write some ClientInfos and see the counts are correct
         ICDClientInfo clientInfo1;
         clientInfo1.peer_node = ScopedNodeId(nodeId1, fabricId);
@@ -78,38 +85,38 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext)
         ICDClientInfo clientInfo3;
         clientInfo3.peer_node = ScopedNodeId(nodeId1, fabricId);
         err                   = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1));
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         err = manager.StoreEntry(clientInfo1);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2));
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         err = manager.StoreEntry(clientInfo2);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3));
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         err = manager.StoreEntry(clientInfo3);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
 
         ICDClientInfo clientInfo;
         // Make sure iterator counts correctly
         auto * iterator = manager.IterateICDClientInfo();
         // same nodeId for clientInfo2 and clientInfo3, so the new one replace old one
-        NL_TEST_ASSERT(apSuite, iterator->Count() == 2);
+        EXPECT_EQ(iterator->Count(), 2u);
 
-        NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo));
-        NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId2);
-        NL_TEST_ASSERT(apSuite, iterator->Next(clientInfo));
-        NL_TEST_ASSERT(apSuite, clientInfo.peer_node.GetNodeId() == nodeId1);
+        EXPECT_TRUE(iterator->Next(clientInfo));
+        EXPECT_EQ(clientInfo.peer_node.GetNodeId(), nodeId2);
+        EXPECT_TRUE(iterator->Next(clientInfo));
+        EXPECT_EQ(clientInfo.peer_node.GetNodeId(), nodeId1);
 
         iterator->Release();
 
         // Delete all and verify iterator counts 0
         err = manager.DeleteAllEntries(fabricId);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         iterator = manager.IterateICDClientInfo();
-        NL_TEST_ASSERT(apSuite, iterator->Count() == 0);
+        EXPECT_EQ(iterator->Count(), 0u);
 
         // Verify ClientInfos manually count correctly
         size_t count = 0;
@@ -118,19 +125,19 @@ void TestClientInfoCount(nlTestSuite * apSuite, void * apContext)
             count++;
         }
         iterator->Release();
-        NL_TEST_ASSERT(apSuite, count == 0);
+        EXPECT_EQ(count, 0u);
     }
 
     {
         DefaultICDClientStorage manager;
         err = manager.Init(&clientInfoStorage, &keystore);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         err = manager.UpdateFabricList(fabricId);
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
     }
 }
 
-void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext)
+TEST_F(TestDefaultICDClientStorage, TestClientInfoCountMultipleFabric)
 {
     CHIP_ERROR err        = CHIP_NO_ERROR;
     FabricIndex fabricId1 = 1;
@@ -142,11 +149,11 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext)
     TestPersistentStorageDelegate clientInfoStorage;
     TestSessionKeystoreImpl keystore;
     err = manager.Init(&clientInfoStorage, &keystore);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.UpdateFabricList(fabricId1);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.UpdateFabricList(fabricId2);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Write some ClientInfos and see the counts are correct
     ICDClientInfo clientInfo1;
@@ -157,39 +164,39 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext)
     clientInfo3.peer_node = ScopedNodeId(nodeId3, fabricId2);
 
     err = manager.SetKey(clientInfo1, ByteSpan(kKeyBuffer1));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.StoreEntry(clientInfo1);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = manager.SetKey(clientInfo2, ByteSpan(kKeyBuffer2));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.StoreEntry(clientInfo2);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = manager.SetKey(clientInfo3, ByteSpan(kKeyBuffer3));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.StoreEntry(clientInfo3);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     // Make sure iterator counts correctly
     auto * iterator = manager.IterateICDClientInfo();
-    NL_TEST_ASSERT(apSuite, iterator->Count() == 3);
+    EXPECT_EQ(iterator->Count(), 3u);
     iterator->Release();
 
     // Delete all and verify iterator counts 0
     err = manager.DeleteEntry(ScopedNodeId(nodeId1, fabricId1));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     iterator = manager.IterateICDClientInfo();
-    NL_TEST_ASSERT(apSuite, iterator != nullptr);
+    ASSERT_NE(iterator, nullptr);
     DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iterator);
-    NL_TEST_ASSERT(apSuite, iterator->Count() == 2);
+    EXPECT_EQ(iterator->Count(), 2u);
 
     err = manager.DeleteEntry(ScopedNodeId(nodeId2, fabricId1));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(apSuite, iterator->Count() == 1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(iterator->Count(), 1u);
 
     err = manager.DeleteEntry(ScopedNodeId(nodeId3, fabricId2));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(apSuite, iterator->Count() == 0);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(iterator->Count(), 0u);
 
     // Verify ClientInfos manually count correctly
     size_t count = 0;
@@ -199,10 +206,10 @@ void TestClientInfoCountMultipleFabric(nlTestSuite * apSuite, void * apContext)
         count++;
     }
 
-    NL_TEST_ASSERT(apSuite, count == 0);
+    EXPECT_FALSE(count);
 }
 
-void TestProcessCheckInPayload(nlTestSuite * apSuite, void * apContext)
+TEST_F(TestDefaultICDClientStorage, TestProcessCheckInPayload)
 {
     CHIP_ERROR err       = CHIP_NO_ERROR;
     FabricIndex fabricId = 1;
@@ -212,98 +219,41 @@ void TestProcessCheckInPayload(nlTestSuite * apSuite, void * apContext)
 
     DefaultICDClientStorage manager;
     err = manager.Init(&clientInfoStorage, &keystore);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.UpdateFabricList(fabricId);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     // Populate clientInfo
     ICDClientInfo clientInfo;
     clientInfo.peer_node = ScopedNodeId(nodeId, fabricId);
 
     err = manager.SetKey(clientInfo, ByteSpan(kKeyBuffer1));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = manager.StoreEntry(clientInfo);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     uint32_t counter                  = 1;
     System::PacketBufferHandle buffer = MessagePacketBuffer::New(chip::Protocols::SecureChannel::CheckinMessage::kMinPayloadSize);
     MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() };
     err = chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload(
         clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     buffer->SetDataLength(static_cast<uint16_t>(output.size()));
     ICDClientInfo decodeClientInfo;
     uint32_t checkInCounter = 0;
     ByteSpan payload{ buffer->Start(), buffer->DataLength() };
     err = manager.ProcessCheckInPayload(payload, decodeClientInfo, checkInCounter);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // 2. Use a key not available in the storage for encoding
     err = manager.SetKey(clientInfo, ByteSpan(kKeyBuffer2));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     err = chip::Protocols::SecureChannel::CheckinMessage::GenerateCheckinMessagePayload(
         clientInfo.aes_key_handle, clientInfo.hmac_key_handle, counter, ByteSpan(), output);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     buffer->SetDataLength(static_cast<uint16_t>(output.size()));
     ByteSpan payload1{ buffer->Start(), buffer->DataLength() };
     err = manager.ProcessCheckInPayload(payload1, decodeClientInfo, checkInCounter);
-    NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NOT_FOUND);
-}
-
-/**
- *  Set up the test suite.
- */
-int TestClientInfo_Setup(void * apContext)
-{
-    VerifyOrReturnError(CHIP_NO_ERROR == Platform::MemoryInit(), FAILURE);
-
-    return SUCCESS;
+    EXPECT_EQ(err, CHIP_ERROR_NOT_FOUND);
 }
-
-/**
- *  Tear down the test suite.
- */
-int TestClientInfo_Teardown(void * apContext)
-{
-    Platform::MemoryShutdown();
-    return SUCCESS;
-}
-
-// Test Suite
-
-/**
- *  Test Suite that lists all the test functions.
- */
-// clang-format off
-static const nlTest sTests[] =
-{
-    NL_TEST_DEF("TestClientInfoCount", TestClientInfoCount),
-    NL_TEST_DEF("TestClientInfoCountMultipleFabric", TestClientInfoCountMultipleFabric),
-    NL_TEST_DEF("TestProcessCheckInPayload", TestProcessCheckInPayload),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-static nlTestSuite sSuite =
-{
-    "TestDefaultICDClientStorage",
-    &sTests[0],
-    &TestClientInfo_Setup, &TestClientInfo_Teardown
-};
-// clang-format on
-
-/**
- *  Main
- */
-int TestDefaultICDClientStorage()
-{
-    // Run test suit against one context
-    nlTestRunner(&sSuite, nullptr);
-
-    return (nlTestRunnerStats(&sSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestDefaultICDClientStorage)
diff --git a/src/app/tests/TestNumericAttributeTraits.cpp b/src/app/tests/TestNumericAttributeTraits.cpp
index a88f3925c2a1d0..6d6c35735066a4 100644
--- a/src/app/tests/TestNumericAttributeTraits.cpp
+++ b/src/app/tests/TestNumericAttributeTraits.cpp
@@ -27,8 +27,8 @@
  *
  */
 
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <lib/core/StringBuilderAdapters.h>
+#include <pw_unit_test/framework.h>
 
 // We are testing the odd-sized-integers.h module
 #include <app/util/odd-sized-integers.h>
@@ -38,7 +38,7 @@ using namespace chip::app;
 
 namespace {
 
-void Test_UINT8(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT8)
 {
     // Unsigned 8-bit Integer : 1 byte, endianness does not matter.
     using IntType     = NumericAttributeTraits<uint8_t>;
@@ -53,8 +53,8 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 0xFF;
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1);
+    EXPECT_EQ(sizeof(sValue), 1u);
+    EXPECT_GE(sizeof(wValue), 1u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, &storageTestData, sizeof(sValue));
@@ -63,7 +63,7 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 17);
+    EXPECT_EQ(wValue, 17u);
 
     StorageType sNewValue;
 
@@ -71,22 +71,22 @@ void Test_UINT8(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_SINT8(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT8)
 {
     // Signed 8-bit Integer : 1 byte, endianness does not matter.
     using IntType     = NumericAttributeTraits<int8_t>;
@@ -101,8 +101,8 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = -128; // 0x80
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1);
+    EXPECT_EQ(sizeof(sValue), 1u);
+    EXPECT_GE(sizeof(wValue), 1u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, &storageTestData, sizeof(sValue));
@@ -111,7 +111,7 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 17);
+    EXPECT_EQ(wValue, 17);
 
     StorageType sNewValue;
 
@@ -119,19 +119,19 @@ void Test_SINT8(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
 enum class SimpleEnum : uint8_t
@@ -140,7 +140,7 @@ enum class SimpleEnum : uint8_t
     kOne  = 1,
 };
 
-void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SimpleEnum)
 {
     // Unsigned 8-bit Integer : 1 byte, endianness does not matter.
     using IntType     = NumericAttributeTraits<SimpleEnum>;
@@ -155,8 +155,8 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = static_cast<SimpleEnum>(0xFF);
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 1);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 1);
+    EXPECT_EQ(sizeof(sValue), 1u);
+    EXPECT_GE(sizeof(wValue), 1u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, &storageTestData, sizeof(sValue));
@@ -165,7 +165,7 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == SimpleEnum::kOne);
+    EXPECT_EQ(wValue, SimpleEnum::kOne);
 
     StorageType sNewValue;
 
@@ -173,19 +173,19 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(&storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
 ////////////////////////////////////////////////////////////
@@ -200,7 +200,7 @@ void Test_SimpleEnum(nlTestSuite * apSuite, void * apContext)
 // $$$$$$$$/       $$/       $$$$$$$/  $$$$$$/    $$/     //
 //                                                        //
 ////////////////////////////////////////////////////////////
-void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT24_LE)
 {
     // Unsigned 24-bit Integer : 3 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<3, false>, false>;
@@ -215,8 +215,8 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 16777215; // 0xFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 3);
+    EXPECT_EQ(sizeof(sValue), 3u);
+    EXPECT_GE(sizeof(wValue), 3u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -225,7 +225,7 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456);
+    EXPECT_EQ(wValue, 0x123456u);
 
     StorageType sNewValue;
 
@@ -233,22 +233,22 @@ void Test_UINT24_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT24_BE)
 {
     // Unsigned 24-bit Integer : 3 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<3, false>, true>;
@@ -263,8 +263,8 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 16777215; // 0xFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 3);
+    EXPECT_EQ(sizeof(sValue), 3u);
+    EXPECT_GE(sizeof(wValue), 3u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -273,7 +273,7 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456);
+    EXPECT_EQ(wValue, 0x123456u);
 
     StorageType sNewValue;
 
@@ -281,22 +281,22 @@ void Test_UINT24_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT24_LE)
 {
     // Signed 24-bit Integer : 3 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<3, true>, false>;
@@ -315,10 +315,10 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -8388608;             // -0x800000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 3);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 3);
+    EXPECT_EQ(sizeof(sValuePos), 3u);
+    EXPECT_GE(sizeof(wValuePos), 3u);
+    EXPECT_EQ(sizeof(sValueNeg), 3u);
+    EXPECT_GE(sizeof(wValueNeg), 3u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -329,8 +329,8 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -340,8 +340,8 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -349,19 +349,19 @@ void Test_SINT24_LE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
-void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT24_BE)
 {
     // Signed 24-bit Integer : 3 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<3, true>, true>;
@@ -380,10 +380,10 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -8388608;             // -0x800000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 3);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 3);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 3);
+    EXPECT_EQ(sizeof(sValuePos), 3u);
+    EXPECT_GE(sizeof(wValuePos), 3u);
+    EXPECT_EQ(sizeof(sValueNeg), 3u);
+    EXPECT_GE(sizeof(wValueNeg), 3u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -394,8 +394,8 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -405,8 +405,8 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -414,16 +414,16 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
 ////////////////////////////////////////////////////////////
@@ -438,7 +438,7 @@ void Test_SINT24_BE(nlTestSuite * apSuite, void * apContext)
 //       $$/  $$$$$$/        $$$$$$$/  $$$$$$/    $$/     //
 //                                                        //
 ////////////////////////////////////////////////////////////
-void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT40_LE)
 {
     // Unsigned 40-bit Integer : 5 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<5, false>, false>;
@@ -453,8 +453,8 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 1099511627775; // 0xFFFFFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 5);
+    EXPECT_EQ(sizeof(sValue), 5u);
+    EXPECT_GE(sizeof(wValue), 5u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -463,7 +463,7 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789A);
+    EXPECT_EQ(wValue, 0x123456789Au);
 
     StorageType sNewValue;
 
@@ -471,22 +471,22 @@ void Test_UINT40_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT40_BE)
 {
     // Unsigned 40-bit Integer : 5 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<5, false>, true>;
@@ -500,8 +500,8 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext)
     const StorageType storageTestData              = { 0x12, 0x34, 0x56, 0x78, 0x9A };
     const WorkingType workingTestUnsignedNullValue = 1099511627775; // 0xFFFFFFFFFF
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 5);
+    EXPECT_EQ(sizeof(sValue), 5u);
+    EXPECT_GE(sizeof(wValue), 5u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -510,7 +510,7 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789A);
+    EXPECT_EQ(wValue, 0x123456789Au);
 
     StorageType sNewValue;
 
@@ -518,22 +518,22 @@ void Test_UINT40_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT40_LE)
 {
     // Signed 40-bit Integer : 5 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<5, true>, false>;
@@ -552,10 +552,10 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -549755813888; // -0x8000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 5);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 5);
+    EXPECT_EQ(sizeof(sValuePos), 5u);
+    EXPECT_GE(sizeof(wValuePos), 5u);
+    EXPECT_EQ(sizeof(sValueNeg), 5u);
+    EXPECT_GE(sizeof(wValueNeg), 5u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -566,8 +566,8 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -577,8 +577,8 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -586,19 +586,19 @@ void Test_SINT40_LE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
-void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT40_BE)
 {
     // Signed 40-bit Integer : 5 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<5, true>, true>;
@@ -617,10 +617,10 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -549755813888; // -0x8000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 5);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 5);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 5);
+    EXPECT_EQ(sizeof(sValuePos), 5u);
+    EXPECT_GE(sizeof(wValuePos), 5u);
+    EXPECT_EQ(sizeof(sValueNeg), 5u);
+    EXPECT_GE(sizeof(wValueNeg), 5u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -631,8 +631,8 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -642,8 +642,8 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -651,16 +651,16 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
 ////////////////////////////////////////////////////////////
@@ -675,7 +675,7 @@ void Test_SINT40_BE(nlTestSuite * apSuite, void * apContext)
 //       $$/  $$$$$$/        $$$$$$$/  $$$$$$/    $$/     //
 //                                                        //
 ////////////////////////////////////////////////////////////
-void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT48_LE)
 {
     // Unsigned 48-bit Integer : 6 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<6, false>, false>;
@@ -690,8 +690,8 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 281474976710655; // 0xFFFFFFFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 6);
+    EXPECT_EQ(sizeof(sValue), 6u);
+    EXPECT_GE(sizeof(wValue), 6u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -700,7 +700,7 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABC);
+    EXPECT_EQ(wValue, 0x123456789ABCu);
 
     StorageType sNewValue;
 
@@ -708,22 +708,22 @@ void Test_UINT48_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT48_BE)
 {
     // Unsigned 48-bit Integer : 6 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<6, false>, true>;
@@ -738,8 +738,8 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 281474976710655; // 0xFFFFFFFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 6);
+    EXPECT_EQ(sizeof(sValue), 6u);
+    EXPECT_GE(sizeof(wValue), 6u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -748,7 +748,7 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABC);
+    EXPECT_EQ(wValue, 0x123456789ABCu);
 
     StorageType sNewValue;
 
@@ -756,22 +756,22 @@ void Test_UINT48_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT48_LE)
 {
     // Signed 48-bit Integer : 6 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<6, true>, false>;
@@ -790,10 +790,10 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -140737488355328; // -0x800000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 6);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 6);
+    EXPECT_EQ(sizeof(sValuePos), 6u);
+    EXPECT_GE(sizeof(wValuePos), 6u);
+    EXPECT_EQ(sizeof(sValueNeg), 6u);
+    EXPECT_GE(sizeof(wValueNeg), 6u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -804,8 +804,8 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -815,8 +815,8 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -824,19 +824,19 @@ void Test_SINT48_LE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
-void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT48_BE)
 {
     // Signed 48-bit Integer : 6 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<6, true>, true>;
@@ -855,10 +855,10 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -140737488355328; // -0x800000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 6);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 6);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 6);
+    EXPECT_EQ(sizeof(sValuePos), 6u);
+    EXPECT_GE(sizeof(wValuePos), 6u);
+    EXPECT_EQ(sizeof(sValueNeg), 6u);
+    EXPECT_GE(sizeof(wValueNeg), 6u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -869,8 +869,8 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -880,8 +880,8 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -889,16 +889,16 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
 ////////////////////////////////////////////////////////////
@@ -913,7 +913,7 @@ void Test_SINT48_BE(nlTestSuite * apSuite, void * apContext)
 //  $$$$$$/   $$$$$$/        $$$$$$$/  $$$$$$/    $$/     //
 //                                                        //
 ////////////////////////////////////////////////////////////
-void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT56_LE)
 {
     // Unsigned 56-bit Integer : 7 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<7, false>, false>;
@@ -928,8 +928,8 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 72057594037927935; // 0xFFFFFFFFFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 7);
+    EXPECT_EQ(sizeof(sValue), 7u);
+    EXPECT_GE(sizeof(wValue), 7u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -938,7 +938,7 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABCDE);
+    EXPECT_EQ(wValue, 0x123456789ABCDEu);
 
     StorageType sNewValue;
 
@@ -946,22 +946,22 @@ void Test_UINT56_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_UINT56_BE)
 {
     // Unsigned 56-bit Integer : 7 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<7, false>, true>;
@@ -976,8 +976,8 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestUnsignedNullValue = 72057594037927935; // 0xFFFFFFFFFFFFFF
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValue) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValue) >= 7);
+    EXPECT_EQ(sizeof(sValue), 7u);
+    EXPECT_GE(sizeof(wValue), 7u);
 
     // Initialize the Storage Value with the test-buffer
     memcpy(&sValue, storageTestData, sizeof(sValue));
@@ -986,7 +986,7 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext)
     wValue = IntType::StorageToWorking(sValue);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValue == 0x123456789ABCDE);
+    EXPECT_EQ(wValue, 0x123456789ABCDEu);
 
     StorageType sNewValue;
 
@@ -994,22 +994,22 @@ void Test_UINT56_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValue, sNewValue);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestData, &sNewValue, sizeof(sNewValue)) == 0);
+    EXPECT_EQ(memcmp(storageTestData, &sNewValue, sizeof(sNewValue)), 0);
 
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestUnsignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestUnsignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
 }
 
-void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT56_LE)
 {
     // Signed 56-bit Integer : 6 bytes - little-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<7, true>, false>;
@@ -1028,10 +1028,10 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -36028797018963968; // -0x80000000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 7);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 7);
+    EXPECT_EQ(sizeof(sValuePos), 7u);
+    EXPECT_GE(sizeof(wValuePos), 7u);
+    EXPECT_EQ(sizeof(sValueNeg), 7u);
+    EXPECT_GE(sizeof(wValueNeg), 7u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -1042,8 +1042,8 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -1053,8 +1053,8 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -1062,19 +1062,19 @@ void Test_SINT56_LE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
-void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext)
+TEST(TestNumericAttributeTraits, Test_SINT56_BE)
 {
     // Signed 56-bit Integer : 7 bytes - big-endian
     using IntType     = NumericAttributeTraits<OddSizedInteger<7, true>, true>;
@@ -1093,10 +1093,10 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext)
     const WorkingType workingTestSignedNullValue = -36028797018963968; // -0x80000000000000
 
     // 1) Verify the size of the types
-    NL_TEST_ASSERT(apSuite, sizeof(sValuePos) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValuePos) >= 7);
-    NL_TEST_ASSERT(apSuite, sizeof(sValueNeg) == 7);
-    NL_TEST_ASSERT(apSuite, sizeof(wValueNeg) >= 7);
+    EXPECT_EQ(sizeof(sValuePos), 7u);
+    EXPECT_GE(sizeof(wValuePos), 7u);
+    EXPECT_EQ(sizeof(sValueNeg), 7u);
+    EXPECT_GE(sizeof(wValueNeg), 7u);
 
     // Initialize the Storage Values with the test-buffer
     memcpy(&sValuePos, storageTestDataPos, sizeof(sValuePos));
@@ -1107,8 +1107,8 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext)
     wValueNeg = IntType::StorageToWorking(sValueNeg);
 
     // 2) Verify that the correct storage format has been used
-    NL_TEST_ASSERT(apSuite, wValuePos == workingDataPos);
-    NL_TEST_ASSERT(apSuite, wValueNeg == workingDataNeg);
+    EXPECT_EQ(wValuePos, workingDataPos);
+    EXPECT_EQ(wValueNeg, workingDataNeg);
 
     StorageType sNewValuePos;
     StorageType sNewValueNeg;
@@ -1118,8 +1118,8 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext)
     IntType::WorkingToStorage(wValueNeg, sNewValueNeg);
 
     // 3) Verify that the bytes are located as intended
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)) == 0);
-    NL_TEST_ASSERT(apSuite, memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)) == 0);
+    EXPECT_EQ(memcmp(storageTestDataPos, &sNewValuePos, sizeof(sNewValuePos)), 0);
+    EXPECT_EQ(memcmp(storageTestDataNeg, &sNewValueNeg, sizeof(sNewValueNeg)), 0);
 
     StorageType sNullValue;
     WorkingType wNullValue;
@@ -1127,82 +1127,16 @@ void Test_SINT56_BE(nlTestSuite * apSuite, void * apContext)
     // Set Storage value to Null
     IntType::SetNull(sNullValue);
     wNullValue = IntType::StorageToWorking(sNullValue);
-    NL_TEST_ASSERT(apSuite, wNullValue == workingTestSignedNullValue);
-    NL_TEST_ASSERT(apSuite, (IntType::IsNullValue(sNullValue) == true));
+    EXPECT_EQ(wNullValue, workingTestSignedNullValue);
+    EXPECT_TRUE(IntType::IsNullValue(sNullValue));
 
     // Verify that null values can fit into not nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, sNullValue) == true));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(false, wNullValue) == true));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, sNullValue));
+    EXPECT_TRUE(IntType::CanRepresentValue(false, wNullValue));
 
     // Verify that null values can't fit into nullable
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, sNullValue) == false));
-    NL_TEST_ASSERT(apSuite, (IntType::CanRepresentValue(true, wNullValue) == false));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, sNullValue));
+    EXPECT_FALSE(IntType::CanRepresentValue(true, wNullValue));
 }
 
-static int TestSetup(void * inContext)
-{
-    return SUCCESS;
-}
-
-/**
- *  Tear down the test suite.
- */
-static int TestTeardown(void * inContext)
-{
-    return SUCCESS;
-}
-
-/**
- *   Test Suite. It lists all the test functions.
- */
-
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("Test_UINT8", Test_UINT8),
-    NL_TEST_DEF("Test_SINT8", Test_SINT8),
-    NL_TEST_DEF("Test_SimpleEnum", Test_SimpleEnum),
-
-    NL_TEST_DEF("Test_UINT24_LE",Test_UINT24_LE),
-    NL_TEST_DEF("Test_SINT24_LE",Test_SINT24_LE),
-    NL_TEST_DEF("Test_UINT24_BE",Test_UINT24_BE),
-    NL_TEST_DEF("Test_SINT24_BE",Test_SINT24_BE),
-
-    NL_TEST_DEF("Test_UINT40_LE",Test_UINT40_LE),
-    NL_TEST_DEF("Test_SINT40_LE",Test_SINT40_LE),
-    NL_TEST_DEF("Test_UINT40_BE",Test_UINT40_BE),
-    NL_TEST_DEF("Test_SINT40_BE",Test_SINT40_BE),
-
-    NL_TEST_DEF("Test_UINT48_LE",Test_UINT48_LE),
-    NL_TEST_DEF("Test_SINT48_LE",Test_SINT48_LE),
-    NL_TEST_DEF("Test_UINT48_BE",Test_UINT48_BE),
-    NL_TEST_DEF("Test_SINT48_BE",Test_SINT48_BE),
-
-    NL_TEST_DEF("Test_UINT56_LE",Test_UINT56_LE),
-    NL_TEST_DEF("Test_SINT56_LE",Test_SINT56_LE),
-    NL_TEST_DEF("Test_UINT56_BE",Test_UINT56_BE),
-    NL_TEST_DEF("Test_SINT56_BE",Test_SINT56_BE),
-
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-// clang-format off
-nlTestSuite theSuite =
-{
-    "TestNumericAttributeTraits",
-    &sTests[0],
-    TestSetup,
-    TestTeardown
-};
-// clang-format on
-
 } // namespace
-
-int TestNumericAttributeTraits()
-{
-    nlTestRunner(&theSuite, nullptr);
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestNumericAttributeTraits)
diff --git a/src/app/tests/TestOperationalStateClusterObjects.cpp b/src/app/tests/TestOperationalStateClusterObjects.cpp
index 9f7d1e1efcadac..2b305949d8fe8d 100644
--- a/src/app/tests/TestOperationalStateClusterObjects.cpp
+++ b/src/app/tests/TestOperationalStateClusterObjects.cpp
@@ -17,9 +17,8 @@
 
 #include <app/clusters/operational-state-server/operational-state-cluster-objects.h>
 #include <lib/core/CHIPPersistentStorageDelegate.h>
-#include <lib/support/UnitTestRegistration.h>
-
-#include <nlunit-test.h>
+#include <lib/core/StringBuilderAdapters.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 using namespace chip::DeviceLayer;
@@ -27,31 +26,38 @@ using namespace chip::app::Clusters::OperationalState;
 
 namespace {
 
-void TestStructGenericOperationalStateConstructorWithOnlyStateID(nlTestSuite * inSuite, void * inContext)
+class TestOperationalStateClusterObjects : public ::testing::Test
+{
+public:
+    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
+    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
+};
+
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateConstructorWithOnlyStateID)
 {
     using namespace chip::app::Clusters::OperationalState;
     // General state: Stopped
     GenericOperationalState operationalStateStopped(to_underlying(OperationalStateEnum::kStopped));
-    NL_TEST_ASSERT(inSuite, operationalStateStopped.operationalStateID == to_underlying(OperationalStateEnum::kStopped));
-    NL_TEST_ASSERT(inSuite, operationalStateStopped.operationalStateLabel.HasValue() == false);
+    EXPECT_EQ(operationalStateStopped.operationalStateID, to_underlying(OperationalStateEnum::kStopped));
+    EXPECT_FALSE(operationalStateStopped.operationalStateLabel.HasValue());
 
     // General state: Running
     GenericOperationalState operationalStateRunning(to_underlying(OperationalStateEnum::kRunning));
-    NL_TEST_ASSERT(inSuite, operationalStateRunning.operationalStateID == to_underlying(OperationalStateEnum::kRunning));
-    NL_TEST_ASSERT(inSuite, operationalStateRunning.operationalStateLabel.HasValue() == false);
+    EXPECT_EQ(operationalStateRunning.operationalStateID, to_underlying(OperationalStateEnum::kRunning));
+    EXPECT_FALSE(operationalStateRunning.operationalStateLabel.HasValue());
 
     // General state: Paused
     GenericOperationalState operationalStatePaused(to_underlying(OperationalStateEnum::kPaused));
-    NL_TEST_ASSERT(inSuite, operationalStatePaused.operationalStateID == to_underlying(OperationalStateEnum::kPaused));
-    NL_TEST_ASSERT(inSuite, operationalStatePaused.operationalStateLabel.HasValue() == false);
+    EXPECT_EQ(operationalStatePaused.operationalStateID, to_underlying(OperationalStateEnum::kPaused));
+    EXPECT_FALSE(operationalStatePaused.operationalStateLabel.HasValue());
 
     // General state: Error
     GenericOperationalState operationalStateError(to_underlying(OperationalStateEnum::kError));
-    NL_TEST_ASSERT(inSuite, operationalStateError.operationalStateID == to_underlying(OperationalStateEnum::kError));
-    NL_TEST_ASSERT(inSuite, operationalStateError.operationalStateLabel.HasValue() == false);
+    EXPECT_EQ(operationalStateError.operationalStateID, to_underlying(OperationalStateEnum::kError));
+    EXPECT_FALSE(operationalStateError.operationalStateLabel.HasValue());
 }
 
-void TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -66,14 +72,13 @@ void TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel(nlTest
     GenericOperationalState operationalState(to_underlying(ManufactureOperationalStateEnum::kRebooting),
                                              Optional<CharSpan>(CharSpan::fromCharString(buffer)));
 
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == strlen(buffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)) == 0);
+    EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting));
+    EXPECT_TRUE(operationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), strlen(buffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)), 0);
 }
 
-void TestStructGenericOperationalStateCopyConstructor(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateCopyConstructor)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -89,18 +94,16 @@ void TestStructGenericOperationalStateCopyConstructor(nlTestSuite * inSuite, voi
 
     GenericOperationalState desOperationalState(srcOperationalState);
 
-    NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateID == srcOperationalState.operationalStateID);
-    NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalState.operationalStateLabel.Value().size() ==
-                       srcOperationalState.operationalStateLabel.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalState.operationalStateLabel.Value().data()),
-                          const_cast<char *>(srcOperationalState.operationalStateLabel.Value().data()),
-                          desOperationalState.operationalStateLabel.Value().size()) == 0);
+    EXPECT_EQ(desOperationalState.operationalStateID, srcOperationalState.operationalStateID);
+    EXPECT_TRUE(desOperationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(desOperationalState.operationalStateLabel.Value().size(), srcOperationalState.operationalStateLabel.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalState.operationalStateLabel.Value().data()),
+                     const_cast<char *>(srcOperationalState.operationalStateLabel.Value().data()),
+                     desOperationalState.operationalStateLabel.Value().size()),
+              0);
 }
 
-void TestStructGenericOperationalStateCopyAssignment(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateCopyAssignment)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -116,18 +119,16 @@ void TestStructGenericOperationalStateCopyAssignment(nlTestSuite * inSuite, void
 
     GenericOperationalState desOperationalState = srcOperationalState;
 
-    NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateID == srcOperationalState.operationalStateID);
-    NL_TEST_ASSERT(inSuite, desOperationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalState.operationalStateLabel.Value().size() ==
-                       srcOperationalState.operationalStateLabel.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalState.operationalStateLabel.Value().data()),
-                          const_cast<char *>(srcOperationalState.operationalStateLabel.Value().data()),
-                          desOperationalState.operationalStateLabel.Value().size()) == 0);
+    EXPECT_EQ(desOperationalState.operationalStateID, srcOperationalState.operationalStateID);
+    EXPECT_TRUE(desOperationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(desOperationalState.operationalStateLabel.Value().size(), srcOperationalState.operationalStateLabel.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalState.operationalStateLabel.Value().data()),
+                     const_cast<char *>(srcOperationalState.operationalStateLabel.Value().data()),
+                     desOperationalState.operationalStateLabel.Value().size()),
+              0);
 }
 
-void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalStateFuncSet)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -144,17 +145,16 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo
 
     // change state without label
     operationalState.Set(to_underlying(OperationalStateEnum::kStopped));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(OperationalStateEnum::kStopped));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == false);
+    EXPECT_EQ(operationalState.operationalStateID, to_underlying(OperationalStateEnum::kStopped));
+    EXPECT_FALSE(operationalState.operationalStateLabel.HasValue());
 
     // change state with label
     operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting),
                          Optional<CharSpan>(CharSpan::fromCharString(buffer)));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == strlen(buffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)) == 0);
+    EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting));
+    EXPECT_TRUE(operationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), strlen(buffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, strlen(buffer)), 0);
 
     // change state with label, label len = kOperationalStateLabelMaxSize
     for (size_t i = 0; i < sizeof(buffer); i++)
@@ -163,11 +163,10 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo
     }
     operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting),
                          Optional<CharSpan>(CharSpan(buffer, sizeof(buffer))));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == sizeof(buffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, sizeof(buffer)) == 0);
+    EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting));
+    EXPECT_TRUE(operationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), sizeof(buffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer, sizeof(buffer)), 0);
 
     // change state with label, label len larger than kOperationalStateLabelMaxSize
     char buffer2[kOperationalStateLabelMaxSize + 1];
@@ -178,51 +177,47 @@ void TestStructGenericOperationalStateFuncSet(nlTestSuite * inSuite, void * inCo
     }
     operationalState.Set(to_underlying(ManufactureOperationalStateEnum::kRebooting),
                          Optional<CharSpan>(CharSpan(buffer2, sizeof(buffer2))));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateID == to_underlying(ManufactureOperationalStateEnum::kRebooting));
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalState.operationalStateLabel.Value().size() == kOperationalStateLabelMaxSize);
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer2,
-                          kOperationalStateLabelMaxSize) == 0);
+    EXPECT_EQ(operationalState.operationalStateID, to_underlying(ManufactureOperationalStateEnum::kRebooting));
+    EXPECT_TRUE(operationalState.operationalStateLabel.HasValue());
+    EXPECT_EQ(operationalState.operationalStateLabel.Value().size(), kOperationalStateLabelMaxSize);
+    EXPECT_EQ(
+        memcmp(const_cast<char *>(operationalState.operationalStateLabel.Value().data()), buffer2, kOperationalStateLabelMaxSize),
+        0);
 }
 
-void TestStructGenericOperationalErrorConstructorWithOnlyStateID(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithOnlyStateID)
 {
     using namespace chip::app::Clusters::OperationalState;
     // General errors: NoError
     GenericOperationalError operationalErrorNoErr(to_underlying(ErrorStateEnum::kNoError));
 
-    NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateID == to_underlying(ErrorStateEnum::kNoError));
-    NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalErrorNoErr.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalErrorNoErr.errorStateID, to_underlying(ErrorStateEnum::kNoError));
+    EXPECT_FALSE(operationalErrorNoErr.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalErrorNoErr.errorStateDetails.HasValue());
 
     // General errors: UnableToStartOrResume
     GenericOperationalError operationalErrorUnableToStartOrResume(to_underlying(ErrorStateEnum::kUnableToStartOrResume));
 
-    NL_TEST_ASSERT(inSuite,
-                   operationalErrorUnableToStartOrResume.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalErrorUnableToStartOrResume.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalErrorUnableToStartOrResume.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalErrorUnableToStartOrResume.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_FALSE(operationalErrorUnableToStartOrResume.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalErrorUnableToStartOrResume.errorStateDetails.HasValue());
 
     // General errors: UnableToCompleteOperation
     GenericOperationalError operationalErrorkUnableToCompleteOperation(to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
 
-    NL_TEST_ASSERT(inSuite,
-                   operationalErrorkUnableToCompleteOperation.errorStateID ==
-                       to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
-    NL_TEST_ASSERT(inSuite, operationalErrorkUnableToCompleteOperation.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalErrorkUnableToCompleteOperation.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalErrorkUnableToCompleteOperation.errorStateID, to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
+    EXPECT_FALSE(operationalErrorkUnableToCompleteOperation.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalErrorkUnableToCompleteOperation.errorStateDetails.HasValue());
 
     // General errors: CommandInvalidInState
     GenericOperationalError operationalErrorCommandInvalidInState(to_underlying(ErrorStateEnum::kCommandInvalidInState));
 
-    NL_TEST_ASSERT(inSuite,
-                   operationalErrorCommandInvalidInState.errorStateID == to_underlying(ErrorStateEnum::kCommandInvalidInState));
-    NL_TEST_ASSERT(inSuite, operationalErrorCommandInvalidInState.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalErrorCommandInvalidInState.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalErrorCommandInvalidInState.errorStateID, to_underlying(ErrorStateEnum::kCommandInvalidInState));
+    EXPECT_FALSE(operationalErrorCommandInvalidInState.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalErrorCommandInvalidInState.errorStateDetails.HasValue());
 }
 
-void TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -237,16 +232,14 @@ void TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel(nlTest
     GenericOperationalError operationalError(to_underlying(ManufactureOperationalErrorEnum::kLowBattery),
                                              Optional<CharSpan>(CharSpan::fromCharString(labelBuffer)));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ManufactureOperationalErrorEnum::kLowBattery));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) ==
-                       0);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ManufactureOperationalErrorEnum::kLowBattery));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0);
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 }
 
-void TestStructGenericOperationalErrorConstructorWithFullParam(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorConstructorWithFullParam)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -263,21 +256,17 @@ void TestStructGenericOperationalErrorConstructorWithFullParam(nlTestSuite * inS
                                              Optional<CharSpan>(CharSpan::fromCharString(labelBuffer)),
                                              Optional<CharSpan>(CharSpan::fromCharString(detailBuffer)));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ManufactureOperationalErrorEnum::kLowBattery));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) ==
-                       0);
-
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == strlen(detailBuffer));
-    NL_TEST_ASSERT(
-        inSuite,
-        memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)) == 0);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ManufactureOperationalErrorEnum::kLowBattery));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0);
+
+    EXPECT_TRUE(operationalError.errorStateDetails.HasValue());
+    EXPECT_EQ(operationalError.errorStateDetails.Value().size(), strlen(detailBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)), 0);
 }
 
-void TestStructGenericOperationalErrorCopyConstructor(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorCopyConstructor)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -296,25 +285,23 @@ void TestStructGenericOperationalErrorCopyConstructor(nlTestSuite * inSuite, voi
 
     // call copy constructor
     GenericOperationalError desOperationalError(srcOperationalError);
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateID == srcOperationalError.errorStateID);
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalError.errorStateLabel.Value().size() == srcOperationalError.errorStateLabel.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalError.errorStateLabel.Value().data()),
-                          const_cast<char *>(srcOperationalError.errorStateLabel.Value().data()),
-                          desOperationalError.errorStateLabel.Value().size()) == 0);
-
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateDetails.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalError.errorStateDetails.Value().size() == srcOperationalError.errorStateDetails.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalError.errorStateDetails.Value().data()),
-                          const_cast<char *>(srcOperationalError.errorStateDetails.Value().data()),
-                          desOperationalError.errorStateDetails.Value().size()) == 0);
+    EXPECT_EQ(desOperationalError.errorStateID, srcOperationalError.errorStateID);
+    EXPECT_TRUE(desOperationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(desOperationalError.errorStateLabel.Value().size(), srcOperationalError.errorStateLabel.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalError.errorStateLabel.Value().data()),
+                     const_cast<char *>(srcOperationalError.errorStateLabel.Value().data()),
+                     desOperationalError.errorStateLabel.Value().size()),
+              0);
+
+    EXPECT_TRUE(desOperationalError.errorStateDetails.HasValue());
+    EXPECT_EQ(desOperationalError.errorStateDetails.Value().size(), srcOperationalError.errorStateDetails.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalError.errorStateDetails.Value().data()),
+                     const_cast<char *>(srcOperationalError.errorStateDetails.Value().data()),
+                     desOperationalError.errorStateDetails.Value().size()),
+              0);
 }
 
-void TestStructGenericOperationalErrorCopyAssignment(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorCopyAssignment)
 {
     using namespace chip::app::Clusters::OperationalState;
 
@@ -333,25 +320,23 @@ void TestStructGenericOperationalErrorCopyAssignment(nlTestSuite * inSuite, void
 
     // call copy assignment
     GenericOperationalError desOperationalError = srcOperationalError;
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateID == srcOperationalError.errorStateID);
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalError.errorStateLabel.Value().size() == srcOperationalError.errorStateLabel.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalError.errorStateLabel.Value().data()),
-                          const_cast<char *>(srcOperationalError.errorStateLabel.Value().data()),
-                          desOperationalError.errorStateLabel.Value().size()) == 0);
-
-    NL_TEST_ASSERT(inSuite, desOperationalError.errorStateDetails.HasValue() == true);
-    NL_TEST_ASSERT(inSuite,
-                   desOperationalError.errorStateDetails.Value().size() == srcOperationalError.errorStateDetails.Value().size());
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(desOperationalError.errorStateDetails.Value().data()),
-                          const_cast<char *>(srcOperationalError.errorStateDetails.Value().data()),
-                          desOperationalError.errorStateDetails.Value().size()) == 0);
+    EXPECT_EQ(desOperationalError.errorStateID, srcOperationalError.errorStateID);
+    EXPECT_TRUE(desOperationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(desOperationalError.errorStateLabel.Value().size(), srcOperationalError.errorStateLabel.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalError.errorStateLabel.Value().data()),
+                     const_cast<char *>(srcOperationalError.errorStateLabel.Value().data()),
+                     desOperationalError.errorStateLabel.Value().size()),
+              0);
+
+    EXPECT_TRUE(desOperationalError.errorStateDetails.HasValue());
+    EXPECT_EQ(desOperationalError.errorStateDetails.Value().size(), srcOperationalError.errorStateDetails.Value().size());
+    EXPECT_EQ(memcmp(const_cast<char *>(desOperationalError.errorStateDetails.Value().data()),
+                     const_cast<char *>(srcOperationalError.errorStateDetails.Value().data()),
+                     desOperationalError.errorStateDetails.Value().size()),
+              0);
 }
 
-void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestOperationalStateClusterObjects, TestStructGenericOperationalErrorFuncSet)
 {
     using namespace chip::app::Clusters::OperationalState;
     enum class ManufactureOperationalErrorEnum : uint8_t
@@ -366,46 +351,40 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo
     // General errors: NoError
     GenericOperationalError operationalError(to_underlying(ErrorStateEnum::kNoError));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kNoError));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kNoError));
+    EXPECT_FALSE(operationalError.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 
     // call Set with stateId
     operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == false);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_FALSE(operationalError.errorStateLabel.HasValue());
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 
     // call Set with stateId and StateLabel
     operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume),
                          Optional<CharSpan>(CharSpan::fromCharString(labelBuffer)));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) ==
-                       0);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0);
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 
     // call Set with stateId, StateLabel and StateDetails
     operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume),
                          Optional<CharSpan>(CharSpan::fromCharString(labelBuffer)),
                          Optional<CharSpan>(CharSpan::fromCharString(detailBuffer)));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == strlen(labelBuffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)) ==
-                       0);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), strlen(labelBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, strlen(labelBuffer)), 0);
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == strlen(detailBuffer));
-    NL_TEST_ASSERT(
-        inSuite,
-        memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)) == 0);
+    EXPECT_TRUE(operationalError.errorStateDetails.HasValue());
+    EXPECT_EQ(operationalError.errorStateDetails.Value().size(), strlen(detailBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer, strlen(detailBuffer)), 0);
 
     // change state with label, label len = kOperationalStateLabelMaxSize
     for (size_t i = 0; i < sizeof(labelBuffer); i++)
@@ -415,13 +394,11 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo
     operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume),
                          Optional<CharSpan>(CharSpan(labelBuffer, sizeof(labelBuffer))));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == sizeof(labelBuffer));
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, sizeof(labelBuffer)) ==
-                       0);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), sizeof(labelBuffer));
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer, sizeof(labelBuffer)), 0);
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 
     // change state with label, label len = kOperationalStateLabelMaxSize + 1
     char labelBuffer2[kOperationalErrorLabelMaxSize + 1];
@@ -432,13 +409,13 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo
     operationalError.Set(to_underlying(ErrorStateEnum::kUnableToStartOrResume),
                          Optional<CharSpan>(CharSpan(labelBuffer2, sizeof(labelBuffer2))));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == kOperationalErrorLabelMaxSize);
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer2,
-                          kOperationalErrorLabelMaxSize) == 0);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == false);
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), kOperationalErrorLabelMaxSize);
+    EXPECT_EQ(
+        memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer2, kOperationalErrorLabelMaxSize),
+        0);
+    EXPECT_FALSE(operationalError.errorStateDetails.HasValue());
 
     // change state with label and details, details len = kOperationalErrorDetailsMaxSize + 1
     char detailBuffer2[kOperationalErrorDetailsMaxSize + 1];
@@ -450,62 +427,19 @@ void TestStructGenericOperationalErrorFuncSet(nlTestSuite * inSuite, void * inCo
                          Optional<CharSpan>(CharSpan(labelBuffer2, sizeof(labelBuffer2))),
                          Optional<CharSpan>(CharSpan(detailBuffer2, sizeof(detailBuffer2))));
 
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateID == to_underlying(ErrorStateEnum::kUnableToStartOrResume));
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.HasValue() == true);
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateLabel.Value().size() == kOperationalErrorLabelMaxSize);
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer2,
-                          kOperationalErrorLabelMaxSize) == 0);
-
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.HasValue() == true);
-
-    NL_TEST_ASSERT(inSuite, operationalError.errorStateDetails.Value().size() == kOperationalErrorDetailsMaxSize);
-    NL_TEST_ASSERT(inSuite,
-                   memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer2,
-                          kOperationalErrorDetailsMaxSize) == 0);
-}
-
-const nlTest sTests[] = {
-    NL_TEST_DEF("Test struct GenericOperationalState: constructor with only StateID",
-                TestStructGenericOperationalStateConstructorWithOnlyStateID),
-    NL_TEST_DEF("Test struct GenericOperationalState: constructor with StateID and StateLabel",
-                TestStructGenericOperationalStateConstructorWithStateIDAndStateLabel),
-    NL_TEST_DEF("Test struct GenericOperationalState: copy constructor", TestStructGenericOperationalStateCopyConstructor),
-    NL_TEST_DEF("Test struct GenericOperationalState: copy assignment", TestStructGenericOperationalStateCopyAssignment),
-    NL_TEST_DEF("Test struct GenericOperationalState: member function 'Set'", TestStructGenericOperationalStateFuncSet),
-    NL_TEST_DEF("Test struct GenericOperationalError: constructor with only StateID",
-                TestStructGenericOperationalErrorConstructorWithOnlyStateID),
-    NL_TEST_DEF("Test struct GenericOperationalError: constructor with StateID and StateLabel",
-                TestStructGenericOperationalErrorConstructorWithStateIDAndStateLabel),
-    NL_TEST_DEF("Test struct GenericOperationalError: constructor with StateID, StateLabel and StateDetail",
-                TestStructGenericOperationalErrorConstructorWithFullParam),
-    NL_TEST_DEF("Test struct GenericOperationalError: copy constructor", TestStructGenericOperationalErrorCopyConstructor),
-    NL_TEST_DEF("Test struct GenericOperationalError: copy assignment", TestStructGenericOperationalErrorCopyAssignment),
-    NL_TEST_DEF("Test struct GenericOperationalError: member function 'Set'", TestStructGenericOperationalErrorFuncSet),
-    NL_TEST_SENTINEL()
-};
+    EXPECT_EQ(operationalError.errorStateID, to_underlying(ErrorStateEnum::kUnableToStartOrResume));
+    EXPECT_TRUE(operationalError.errorStateLabel.HasValue());
+    EXPECT_EQ(operationalError.errorStateLabel.Value().size(), kOperationalErrorLabelMaxSize);
+    EXPECT_EQ(
+        memcmp(const_cast<char *>(operationalError.errorStateLabel.Value().data()), labelBuffer2, kOperationalErrorLabelMaxSize),
+        0);
 
-int TestSetup(void * inContext)
-{
-    VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE);
-    return SUCCESS;
-}
+    EXPECT_TRUE(operationalError.errorStateDetails.HasValue());
 
-int TestTearDown(void * inContext)
-{
-    chip::Platform::MemoryShutdown();
-    return SUCCESS;
+    EXPECT_EQ(operationalError.errorStateDetails.Value().size(), kOperationalErrorDetailsMaxSize);
+    EXPECT_EQ(memcmp(const_cast<char *>(operationalError.errorStateDetails.Value().data()), detailBuffer2,
+                     kOperationalErrorDetailsMaxSize),
+              0);
 }
 
 } // namespace
-
-int TestOperationalStateClusterObjects()
-{
-    nlTestSuite theSuite = { "Test Operational State Cluster Objects tests", &sTests[0], TestSetup, TestTearDown };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestOperationalStateClusterObjects)
diff --git a/src/app/tests/TestPendingNotificationMap.cpp b/src/app/tests/TestPendingNotificationMap.cpp
index 98e27cb5f7b45a..5a98abc3dfdbbe 100644
--- a/src/app/tests/TestPendingNotificationMap.cpp
+++ b/src/app/tests/TestPendingNotificationMap.cpp
@@ -15,12 +15,12 @@
  *    limitations under the License.
  */
 
+#include <pw_unit_test/framework.h>
+
 #include <app/clusters/bindings/PendingNotificationMap.h>
 #include <app/util/binding-table.h>
 #include <app/util/config.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
 
 using chip::BindingTable;
 using chip::ClusterId;
@@ -33,6 +33,16 @@ using chip::PendingNotificationMap;
 
 namespace {
 
+class TestPendingNotificationMap : public ::testing::Test
+{
+public:
+    static void SetUpTestSuite()
+    {
+        static chip::TestPersistentStorageDelegate storage;
+        BindingTable::GetInstance().SetPersistentStorage(&storage);
+    }
+};
+
 void ClearBindingTable(BindingTable & table)
 {
     auto iter = table.begin();
@@ -50,103 +60,83 @@ void CreateDefaultFullBindingTable(BindingTable & table)
     }
 }
 
-void TestEmptyMap(nlTestSuite * aSuite, void * aContext)
+TEST_F(TestPendingNotificationMap, TestEmptyMap)
 {
     PendingNotificationMap pendingMap;
-    NL_TEST_ASSERT(aSuite, pendingMap.begin() == pendingMap.end());
+    EXPECT_EQ(pendingMap.begin(), pendingMap.end());
     chip::ScopedNodeId peer;
-    NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(peer) == CHIP_ERROR_NOT_FOUND);
+    EXPECT_EQ(pendingMap.FindLRUConnectPeer(peer), CHIP_ERROR_NOT_FOUND);
 }
 
-void TestAddRemove(nlTestSuite * aSuite, void * aContext)
+TEST_F(TestPendingNotificationMap, TestAddRemove)
 {
     PendingNotificationMap pendingMap;
     ClearBindingTable(BindingTable::GetInstance());
     CreateDefaultFullBindingTable(BindingTable::GetInstance());
     for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++)
     {
-        NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(i, nullptr) == CHIP_NO_ERROR);
+        EXPECT_EQ(pendingMap.AddPendingNotification(i, nullptr), CHIP_NO_ERROR);
     }
     // Confirm adding in one more element fails
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(MATTER_BINDING_TABLE_SIZE, nullptr) == CHIP_ERROR_NO_MEMORY);
+    EXPECT_EQ(pendingMap.AddPendingNotification(MATTER_BINDING_TABLE_SIZE, nullptr), CHIP_ERROR_NO_MEMORY);
 
     auto iter = pendingMap.begin();
     for (uint8_t i = 0; i < MATTER_BINDING_TABLE_SIZE; i++)
     {
         PendingNotificationEntry entry = *iter;
-        NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == i);
+        EXPECT_EQ(entry.mBindingEntryId, i);
         ++iter;
     }
-    NL_TEST_ASSERT(aSuite, iter == pendingMap.end());
+    EXPECT_EQ(iter, pendingMap.end());
     pendingMap.RemoveAllEntriesForNode(chip::ScopedNodeId());
     uint8_t expectedEntryIndecies[] = { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
     iter                            = pendingMap.begin();
     for (uint8_t ch : expectedEntryIndecies)
     {
         PendingNotificationEntry entry = *iter;
-        NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == ch);
+        EXPECT_EQ(entry.mBindingEntryId, ch);
         ++iter;
     }
-    NL_TEST_ASSERT(aSuite, iter == pendingMap.end());
+    EXPECT_EQ(iter, pendingMap.end());
     pendingMap.RemoveAllEntriesForFabric(0);
     iter = pendingMap.begin();
     for (uint8_t i = 0; i < 10; i++)
     {
         PendingNotificationEntry entry = *iter;
-        NL_TEST_ASSERT(aSuite, entry.mBindingEntryId == 10 + i);
+        EXPECT_EQ(entry.mBindingEntryId, 10u + i);
         ++iter;
     }
-    NL_TEST_ASSERT(aSuite, iter == pendingMap.end());
+    EXPECT_EQ(iter, pendingMap.end());
     pendingMap.RemoveAllEntriesForFabric(1);
-    NL_TEST_ASSERT(aSuite, pendingMap.begin() == pendingMap.end());
+    EXPECT_EQ(pendingMap.begin(), pendingMap.end());
 }
 
-void TestLRUEntry(nlTestSuite * aSuite, void * aContext)
+TEST_F(TestPendingNotificationMap, TestLRUEntry)
 {
     PendingNotificationMap pendingMap;
     ClearBindingTable(BindingTable::GetInstance());
     CreateDefaultFullBindingTable(BindingTable::GetInstance());
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(0, nullptr) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(1, nullptr) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(5, nullptr) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(7, nullptr) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, pendingMap.AddPendingNotification(11, nullptr) == CHIP_NO_ERROR);
+    EXPECT_EQ(pendingMap.AddPendingNotification(0, nullptr), CHIP_NO_ERROR);
+    EXPECT_EQ(pendingMap.AddPendingNotification(1, nullptr), CHIP_NO_ERROR);
+    EXPECT_EQ(pendingMap.AddPendingNotification(5, nullptr), CHIP_NO_ERROR);
+    EXPECT_EQ(pendingMap.AddPendingNotification(7, nullptr), CHIP_NO_ERROR);
+    EXPECT_EQ(pendingMap.AddPendingNotification(11, nullptr), CHIP_NO_ERROR);
 
     chip::ScopedNodeId node;
 
-    NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 0 && node.GetNodeId() == 1);
+    EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR);
+    EXPECT_EQ(node.GetFabricIndex(), 0u);
+    EXPECT_EQ(node.GetNodeId(), 1u);
 
     pendingMap.RemoveEntry(1);
-    NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 0 && node.GetNodeId() == 0);
+    EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR);
+    EXPECT_EQ(node.GetFabricIndex(), 0u);
+    EXPECT_EQ(node.GetNodeId(), 0u);
 
     pendingMap.RemoveAllEntriesForFabric(0);
-    NL_TEST_ASSERT(aSuite, pendingMap.FindLRUConnectPeer(node) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, node.GetFabricIndex() == 1 && node.GetNodeId() == 1);
+    EXPECT_EQ(pendingMap.FindLRUConnectPeer(node), CHIP_NO_ERROR);
+    EXPECT_EQ(node.GetFabricIndex(), 1u);
+    EXPECT_EQ(node.GetNodeId(), 1u);
 }
 
 } // namespace
-
-int TestPeindingNotificationMap()
-{
-    static nlTest sTests[] = {
-        NL_TEST_DEF("TestEmptyMap", TestEmptyMap),
-        NL_TEST_DEF("TestAddRemove", TestAddRemove),
-        NL_TEST_DEF("TestLRUEntry", TestLRUEntry),
-        NL_TEST_SENTINEL(),
-    };
-
-    nlTestSuite theSuite = {
-        "PendingNotificationMap",
-        &sTests[0],
-        nullptr,
-        nullptr,
-    };
-    chip::TestPersistentStorageDelegate storage;
-    BindingTable::GetInstance().SetPersistentStorage(&storage);
-    nlTestRunner(&theSuite, nullptr);
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestPeindingNotificationMap)
diff --git a/src/app/tests/TestPendingResponseTrackerImpl.cpp b/src/app/tests/TestPendingResponseTrackerImpl.cpp
index da6239434cd3b1..2ccd5380642786 100644
--- a/src/app/tests/TestPendingResponseTrackerImpl.cpp
+++ b/src/app/tests/TestPendingResponseTrackerImpl.cpp
@@ -15,75 +15,75 @@
  *    limitations under the License.
  */
 
-#include <app/PendingResponseTrackerImpl.h>
-#include <lib/support/UnitTestRegistration.h>
-
 #include <algorithm>
 #include <nlunit-test.h>
 #include <vector>
 
+#include <app/PendingResponseTrackerImpl.h>
+#include <pw_unit_test/framework.h>
+
 namespace {
 
 using namespace chip;
 
-void TestPendingResponseTracker_FillEntireTracker(nlTestSuite * inSuite, void * inContext)
+TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_FillEntireTracker)
 {
     chip::app::PendingResponseTrackerImpl pendingResponseTracker;
     for (uint16_t commandRef = 0; commandRef < std::numeric_limits<uint16_t>::max(); commandRef++)
     {
-        NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef));
-        NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef));
-        NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef));
+        EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef));
     }
 
-    NL_TEST_ASSERT(inSuite, std::numeric_limits<uint16_t>::max() == pendingResponseTracker.Count());
+    EXPECT_EQ(std::numeric_limits<uint16_t>::max(), pendingResponseTracker.Count());
 
     for (uint16_t commandRef = 0; commandRef < std::numeric_limits<uint16_t>::max(); commandRef++)
     {
-        NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Remove(commandRef));
-        NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Remove(commandRef));
+        EXPECT_EQ(false, pendingResponseTracker.IsTracked(commandRef));
     }
-    NL_TEST_ASSERT(inSuite, 0 == pendingResponseTracker.Count());
+    EXPECT_EQ(0u, pendingResponseTracker.Count());
 }
 
-void TestPendingResponseTracker_FillSingleEntryInTracker(nlTestSuite * inSuite, void * inContext)
+TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_FillSingleEntryInTracker)
 {
     chip::app::PendingResponseTrackerImpl pendingResponseTracker;
 
     // The value 40 is arbitrary; any value would work for this purpose.
     uint16_t commandRefToSet = 40;
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRefToSet));
+    EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRefToSet));
 
     for (uint16_t commandRef = 0; commandRef < std::numeric_limits<uint16_t>::max(); commandRef++)
     {
         bool expectedIsSetResult = (commandRef == commandRefToSet);
-        NL_TEST_ASSERT(inSuite, expectedIsSetResult == pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_EQ(expectedIsSetResult, pendingResponseTracker.IsTracked(commandRef));
     }
 }
 
-void TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails(nlTestSuite * inSuite, void * inContext)
+TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails)
 {
     chip::app::PendingResponseTrackerImpl pendingResponseTracker;
 
     // The value 40 is arbitrary; any value would work for this purpose.
     uint16_t commandRef = 40;
-    NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef));
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_KEY_NOT_FOUND == pendingResponseTracker.Remove(commandRef));
+    EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef));
+    EXPECT_EQ(CHIP_ERROR_KEY_NOT_FOUND, pendingResponseTracker.Remove(commandRef));
 }
 
-void TestPendingResponseTracker_AddingSecondEntryFails(nlTestSuite * inSuite, void * inContext)
+TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_AddingSecondEntryFails)
 {
     chip::app::PendingResponseTrackerImpl pendingResponseTracker;
 
     // The value 40 is arbitrary; any value would work for this purpose.
     uint16_t commandRef = 40;
-    NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef));
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef));
-    NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef));
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_INVALID_ARGUMENT == pendingResponseTracker.Add(commandRef));
+    EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef));
+    EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef));
+    EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef));
+    EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, pendingResponseTracker.Add(commandRef));
 }
 
-void TestPendingResponseTracker_PopFindsAllPendingRequests(nlTestSuite * inSuite, void * inContext)
+TEST(TestPendingResponseTrackerImpl, TestPendingResponseTracker_PopFindsAllPendingRequests)
 {
     chip::app::PendingResponseTrackerImpl pendingResponseTracker;
 
@@ -91,45 +91,23 @@ void TestPendingResponseTracker_PopFindsAllPendingRequests(nlTestSuite * inSuite
     std::vector<uint16_t> requestsToAdd = { 0, 50, 2, 2000 };
     for (const uint16_t & commandRef : requestsToAdd)
     {
-        NL_TEST_ASSERT(inSuite, false == pendingResponseTracker.IsTracked(commandRef));
-        NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == pendingResponseTracker.Add(commandRef));
-        NL_TEST_ASSERT(inSuite, true == pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_FALSE(pendingResponseTracker.IsTracked(commandRef));
+        EXPECT_EQ(CHIP_NO_ERROR, pendingResponseTracker.Add(commandRef));
+        EXPECT_TRUE(pendingResponseTracker.IsTracked(commandRef));
     }
 
-    NL_TEST_ASSERT(inSuite, requestsToAdd.size() == pendingResponseTracker.Count());
+    EXPECT_EQ(requestsToAdd.size(), pendingResponseTracker.Count());
 
     for (size_t i = 0; i < requestsToAdd.size(); i++)
     {
         auto commandRef = pendingResponseTracker.PopPendingResponse();
-        NL_TEST_ASSERT(inSuite, true == commandRef.HasValue());
+        EXPECT_TRUE(commandRef.HasValue());
         bool expectedCommandRef = std::find(requestsToAdd.begin(), requestsToAdd.end(), commandRef.Value()) != requestsToAdd.end();
-        NL_TEST_ASSERT(inSuite, true == expectedCommandRef);
+        EXPECT_TRUE(expectedCommandRef);
     }
-    NL_TEST_ASSERT(inSuite, 0 == pendingResponseTracker.Count());
+    EXPECT_EQ(0u, pendingResponseTracker.Count());
     auto commandRef = pendingResponseTracker.PopPendingResponse();
-    NL_TEST_ASSERT(inSuite, false == commandRef.HasValue());
+    EXPECT_FALSE(commandRef.HasValue());
 }
 
 } // namespace
-
-#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn)
-/**
- *   Test Suite. It lists all the test functions.
- */
-static const nlTest sTests[] = { NL_TEST_DEF_FN(TestPendingResponseTracker_FillEntireTracker),
-                                 NL_TEST_DEF_FN(TestPendingResponseTracker_FillSingleEntryInTracker),
-                                 NL_TEST_DEF_FN(TestPendingResponseTracker_RemoveNonExistentEntryInTrackerFails),
-                                 NL_TEST_DEF_FN(TestPendingResponseTracker_AddingSecondEntryFails),
-                                 NL_TEST_DEF_FN(TestPendingResponseTracker_PopFindsAllPendingRequests),
-                                 NL_TEST_SENTINEL() };
-
-int TestPendingResponseTracker()
-{
-    nlTestSuite theSuite = { "CHIP PendingResponseTrackerImpl tests", &sTests[0], nullptr, nullptr };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestPendingResponseTracker)
diff --git a/src/app/tests/TestPowerSourceCluster.cpp b/src/app/tests/TestPowerSourceCluster.cpp
index 374b9619d38684..99bc972381d389 100644
--- a/src/app/tests/TestPowerSourceCluster.cpp
+++ b/src/app/tests/TestPowerSourceCluster.cpp
@@ -15,50 +15,39 @@
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+#include <vector>
 
 #include "lib/support/CHIPMem.h"
 #include <app-common/zap-generated/cluster-objects.h>
 #include <app/clusters/power-source-server/power-source-server.h>
+#include <app/tests/ember-test-compatibility.h>
 #include <app/util/attribute-storage.h>
 #include <lib/core/ErrorStr.h>
+#include <lib/core/StringBuilderAdapters.h>
 #include <lib/core/TLV.h>
 #include <lib/core/TLVDebug.h>
 #include <lib/core/TLVUtilities.h>
 #include <lib/support/CHIPCounter.h>
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <messaging/ExchangeContext.h>
 #include <messaging/Flags.h>
-#include <nlunit-test.h>
 #include <protocols/interaction_model/Constants.h>
-
-#include <vector>
-
-namespace {
-chip::EndpointId numEndpoints = 0;
-}
-extern uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster,
-                                                     uint16_t fixedClusterServerEndpointCount)
-{
-    // Very simple mapping here, we're just going to return the endpoint that matches the given endpoint index because the test
-    // uses the endpoints in order.
-    if (endpoint >= numEndpoints)
-    {
-        return kEmberInvalidEndpointIndex;
-    }
-    return endpoint;
-}
+#include <pw_unit_test/framework.h>
 
 namespace chip {
 namespace app {
 
-class TestPowerSourceCluster
+class TestPowerSourceCluster : public ::testing::Test
 {
 public:
-    static void TestEndpointList(nlTestSuite * apSuite, void * apContext);
+    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
+    static void TearDownTestSuite()
+    {
+        chip::app::Clusters::PowerSourceServer::Instance().Shutdown();
+        chip::Platform::MemoryShutdown();
+    }
 };
 
-std::vector<EndpointId> ReadEndpointsThroughAttributeReader(nlTestSuite * apSuite, EndpointId endpoint)
+std::vector<EndpointId> ReadEndpointsThroughAttributeReader(EndpointId endpoint)
 {
     Clusters::PowerSourceAttrAccess & attrAccess = Clusters::TestOnlyGetPowerSourceAttrAccess();
     CHIP_ERROR err                               = CHIP_NO_ERROR;
@@ -85,7 +74,7 @@ std::vector<EndpointId> ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit
 
     err = attrAccess.Read(readPath, aEncoder);
 
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Read out from the buffer. This comes back as a nested struct
     // AttributeReportIBs is a list of
@@ -114,13 +103,13 @@ std::vector<EndpointId> ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit
     {
         attrDataReader.Next();
     }
-    NL_TEST_ASSERT(apSuite, IsContextTag(attrDataReader.GetTag()));
-    NL_TEST_ASSERT(apSuite, TagNumFromTag(attrDataReader.GetTag()) == 2);
+    EXPECT_TRUE(IsContextTag(attrDataReader.GetTag()));
+    EXPECT_EQ(TagNumFromTag(attrDataReader.GetTag()), 2u);
 
     // OK, we should be in the right spot now, let's decode the list.
     Clusters::PowerSource::Attributes::EndpointList::TypeInfo::DecodableType list;
     err = list.Decode(attrDataReader);
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     std::vector<EndpointId> ret;
     auto iter = list.begin();
     while (iter.Next())
@@ -130,7 +119,7 @@ std::vector<EndpointId> ReadEndpointsThroughAttributeReader(nlTestSuite * apSuit
     return ret;
 }
 
-void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apContext)
+TEST_F(TestPowerSourceCluster, TestEndpointList)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
 
@@ -139,8 +128,8 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo
     // test that when we read everything we get an empty list as nothing has been set up yet
     for (EndpointId i = 0; i < 11; ++i)
     {
-        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(apSuite, i);
-        NL_TEST_ASSERT(apSuite, vec.size() == 0);
+        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(i);
+        EXPECT_EQ(vec.size(), 0u);
     }
 
     if (powerSourceServer.GetNumSupportedEndpointLists() < 2 ||
@@ -159,42 +148,42 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo
 
     // we checked earlier that this fit
     // This test just uses endpoints in order, so we want to set endpoints from
-    // 0 to numEndpoints - 1, and use this for overflow checking
-    numEndpoints = static_cast<EndpointId>(powerSourceServer.GetNumSupportedEndpointLists());
+    // 0 to chip::Test::numEndpoints - 1, and use this for overflow checking
+    chip::Test::numEndpoints = static_cast<EndpointId>(powerSourceServer.GetNumSupportedEndpointLists());
 
     // Endpoint 0 - list of 5
     err = powerSourceServer.SetEndpointList(0, Span<EndpointId>(list0));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     const Span<EndpointId> * readBack = powerSourceServer.GetEndpointList(0);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-    NL_TEST_ASSERT(apSuite, readBack->size() == 5);
+    ASSERT_NE(readBack, nullptr);
+    EXPECT_EQ(readBack->size(), 5u);
     for (size_t i = 0; i < readBack->size(); ++i)
     {
-        NL_TEST_ASSERT(apSuite, readBack->data()[i] == list0[i]);
+        EXPECT_EQ(readBack->data()[i], list0[i]);
     }
 
     // Endpoint 1 - list of 10
     err = powerSourceServer.SetEndpointList(1, Span<EndpointId>(list1));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     readBack = powerSourceServer.GetEndpointList(1);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-    NL_TEST_ASSERT(apSuite, readBack->size() == 10);
+    ASSERT_NE(readBack, nullptr);
+    EXPECT_EQ(readBack->size(), 10u);
     for (size_t i = 0; i < readBack->size(); ++i)
     {
-        NL_TEST_ASSERT(apSuite, readBack->data()[i] == list1[i]);
+        EXPECT_EQ(readBack->data()[i], list1[i]);
     }
 
     // Remaining endpoints - list of 1
-    for (EndpointId ep = 2; ep < numEndpoints; ++ep)
+    for (EndpointId ep = 2; ep < chip::Test::numEndpoints; ++ep)
     {
         err = powerSourceServer.SetEndpointList(ep, Span<EndpointId>(listRest));
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         readBack = powerSourceServer.GetEndpointList(ep);
-        NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-        NL_TEST_ASSERT(apSuite, readBack->size() == 1);
+        ASSERT_NE(readBack, nullptr);
+        EXPECT_EQ(readBack->size(), 1u);
         if (readBack->size() == 1)
         {
-            NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]);
+            EXPECT_EQ(readBack->data()[0], listRest[0]);
         }
     }
 
@@ -203,38 +192,38 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo
     // *****************
     // pick a random endpoint number for the power cluster - it doesn't matter, we don't have space anyway.
     err = powerSourceServer.SetEndpointList(55, Span<EndpointId>(listRest));
-    NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_NO_MEMORY);
+    EXPECT_EQ(err, CHIP_ERROR_NO_MEMORY);
 
     // *****************
     // Recheck getting and reading after OOM
     // *****************
     // EP0
     readBack = powerSourceServer.GetEndpointList(0);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-    NL_TEST_ASSERT(apSuite, readBack->size() == 5);
+    ASSERT_NE(readBack, nullptr);
+    EXPECT_EQ(readBack->size(), 5u);
     for (size_t i = 0; i < readBack->size(); ++i)
     {
-        NL_TEST_ASSERT(apSuite, readBack->data()[i] == list0[i]);
+        EXPECT_EQ(readBack->data()[i], list0[i]);
     }
 
     // EP1
     readBack = powerSourceServer.GetEndpointList(1);
-    NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-    NL_TEST_ASSERT(apSuite, readBack->size() == 10);
+    ASSERT_NE(readBack, nullptr);
+    EXPECT_EQ(readBack->size(), 10u);
     for (size_t i = 0; i < readBack->size(); ++i)
     {
-        NL_TEST_ASSERT(apSuite, readBack->data()[i] == list1[i]);
+        EXPECT_EQ(readBack->data()[i], list1[i]);
     }
 
     // Remaining endpoints
-    for (EndpointId ep = 2; ep < numEndpoints; ++ep)
+    for (EndpointId ep = 2; ep < chip::Test::numEndpoints; ++ep)
     {
         readBack = powerSourceServer.GetEndpointList(ep);
-        NL_TEST_EXIT_ON_FAILED_ASSERT(apSuite, readBack != nullptr);
-        NL_TEST_ASSERT(apSuite, readBack->size() == 1);
+        ASSERT_NE(readBack, nullptr);
+        EXPECT_EQ(readBack->size(), 1u);
         if (readBack->size() == 1)
         {
-            NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]);
+            EXPECT_EQ(readBack->data()[0], listRest[0]);
         }
     }
 
@@ -243,36 +232,36 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo
     // *****************
     // Overwrite a list
     err = powerSourceServer.SetEndpointList(1, Span<EndpointId>(listRest));
-    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
     readBack = powerSourceServer.GetEndpointList(1);
-    NL_TEST_ASSERT(apSuite, readBack->size() == 1);
+    EXPECT_EQ(readBack->size(), 1u);
     if (readBack->size() == 1)
     {
-        NL_TEST_ASSERT(apSuite, readBack->data()[0] == listRest[0]);
+        EXPECT_EQ(readBack->data()[0], listRest[0]);
     }
 
     // Ensure only the overwritten list was changed, using read interface
-    for (EndpointId ep = 0; ep < numEndpoints + 1; ++ep)
+    for (EndpointId ep = 0; ep < chip::Test::numEndpoints + 1; ++ep)
     {
-        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(apSuite, ep);
+        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(ep);
         if (ep == 0)
         {
-            NL_TEST_ASSERT(apSuite, vec.size() == 5);
+            EXPECT_EQ(vec.size(), 5u);
             for (size_t j = 0; j < vec.size(); ++j)
             {
-                NL_TEST_ASSERT(apSuite, vec[j] == list0[j]);
+                EXPECT_EQ(vec[j], list0[j]);
             }
         }
-        else if (ep == numEndpoints)
+        else if (ep == chip::Test::numEndpoints)
         {
-            NL_TEST_ASSERT(apSuite, vec.size() == 0);
+            EXPECT_EQ(vec.size(), 0u);
         }
         else
         {
-            NL_TEST_ASSERT(apSuite, vec.size() == 1);
+            EXPECT_EQ(vec.size(), 1u);
             if (vec.size() == 1)
             {
-                NL_TEST_ASSERT(apSuite, vec[0] == listRest[0]);
+                EXPECT_EQ(vec[0], listRest[0]);
             }
         }
     }
@@ -280,76 +269,21 @@ void TestPowerSourceCluster::TestEndpointList(nlTestSuite * apSuite, void * apCo
     // *****************
     // Test removal
     // *****************
-    for (EndpointId ep = 0; ep < numEndpoints; ++ep)
+    for (EndpointId ep = 0; ep < chip::Test::numEndpoints; ++ep)
     {
         err = powerSourceServer.SetEndpointList(ep, Span<EndpointId>());
-        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+        EXPECT_EQ(err, CHIP_NO_ERROR);
         readBack = powerSourceServer.GetEndpointList(ep);
-        NL_TEST_ASSERT(apSuite, readBack == nullptr);
+        EXPECT_EQ(readBack, nullptr);
     }
 
     // Check through the read interface
-    for (EndpointId ep = 0; ep < numEndpoints + 1; ++ep)
+    for (EndpointId ep = 0; ep < chip::Test::numEndpoints + 1; ++ep)
     {
-        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(apSuite, ep);
-        NL_TEST_ASSERT(apSuite, vec.size() == 0);
+        std::vector<EndpointId> vec = ReadEndpointsThroughAttributeReader(ep);
+        EXPECT_EQ(vec.size(), 0u);
     }
 }
 
 } // namespace app
 } // namespace chip
-
-namespace {
-
-/**
- *   Test Suite. It lists all the test functions.
- */
-
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("TestEndpointList", chip::app::TestPowerSourceCluster::TestEndpointList),
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-/**
- *  Set up the test suite.
- */
-int TestPowerSourceClusterContext_Setup(void * inContext)
-{
-    CHIP_ERROR error = chip::Platform::MemoryInit();
-    if (error != CHIP_NO_ERROR)
-        return FAILURE;
-    return SUCCESS;
-}
-
-/**
- *  Tear down the test suite.
- */
-int TestPowerSourceClusterContext_Teardown(void * inContext)
-{
-    chip::app::Clusters::PowerSourceServer::Instance().Shutdown();
-    chip::Platform::MemoryShutdown();
-    return SUCCESS;
-}
-
-// clang-format off
-nlTestSuite sSuite =
-{
-    "TestPowerSourceCluster",
-    &sTests[0],
-    TestPowerSourceClusterContext_Setup,
-    TestPowerSourceClusterContext_Teardown
-};
-// clang-format on
-
-} // namespace
-
-int TestPowerSource()
-{
-    nlTestRunner(&sSuite, nullptr);
-    return nlTestRunnerStats(&sSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestPowerSource)
diff --git a/src/app/tests/TestTestEventTriggerDelegate.cpp b/src/app/tests/TestTestEventTriggerDelegate.cpp
index cd7f3ae9cd7be3..09e513a3d87afb 100644
--- a/src/app/tests/TestTestEventTriggerDelegate.cpp
+++ b/src/app/tests/TestTestEventTriggerDelegate.cpp
@@ -19,9 +19,9 @@
 #include <stdint.h>
 
 #include <app/TestEventTriggerDelegate.h>
+#include <lib/core/StringBuilderAdapters.h>
 #include <lib/support/Span.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 
@@ -66,20 +66,20 @@ class TestEventDelegate : public TestEventTriggerDelegate
     ByteSpan mEnableKey;
 };
 
-void TestKeyChecking(nlTestSuite * aSuite, void * aContext)
+TEST(TestTestEventTriggerDelegate, TestKeyChecking)
 {
     const uint8_t kTestKey[16]       = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
     const uint8_t kBadKey[16]        = { 255, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
     const uint8_t kDiffLenBadKey[17] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
     TestEventDelegate delegate{ ByteSpan{ kTestKey } };
 
-    NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kTestKey }) == true);
-    NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kBadKey }) == false);
-    NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{ kDiffLenBadKey }) == false);
-    NL_TEST_ASSERT(aSuite, delegate.DoesEnableKeyMatch(ByteSpan{}) == false);
+    EXPECT_TRUE(delegate.DoesEnableKeyMatch(ByteSpan{ kTestKey }));
+    EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{ kBadKey }));
+    EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{ kDiffLenBadKey }));
+    EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan{}));
 }
 
-void TestHandlerManagement(nlTestSuite * aSuite, void * aContext)
+TEST(TestTestEventTriggerDelegate, TestHandlerManagement)
 {
     const uint8_t kTestKey[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 
@@ -89,31 +89,31 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext)
     TestEventHandler event2Handler{ 2 };
 
     // Add 2, check 2 works 1 doesn't.
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR);
+    EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) != CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 0);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 2);
+    EXPECT_EQ(event1Handler.GetCount(), 0);
+    EXPECT_EQ(event2Handler.GetCount(), 2);
 
     event1Handler.ClearCount();
     event2Handler.ClearCount();
 
     // Add 1, check 1 and 2 work.
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event1Handler) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event1Handler) != CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.AddHandler(&event1Handler), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.AddHandler(&event1Handler), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 2);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 1);
+    EXPECT_EQ(event1Handler.GetCount(), 2);
+    EXPECT_EQ(event2Handler.GetCount(), 1);
 
     event1Handler.ClearCount();
     event2Handler.ClearCount();
@@ -121,29 +121,29 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext)
     // Remove 2, check 1 works.
     delegate.RemoveHandler(&event2Handler);
 
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 1);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0);
+    EXPECT_EQ(event1Handler.GetCount(), 1);
+    EXPECT_EQ(event2Handler.GetCount(), 0);
 
     // Remove again, should be NO-OP.
     delegate.RemoveHandler(&event2Handler);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0);
+    EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
+    EXPECT_EQ(event2Handler.GetCount(), 0);
 
     event1Handler.ClearCount();
     event2Handler.ClearCount();
 
     // Add 2 again, check 1 and 2 work.
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) != CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) == CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
+    EXPECT_EQ(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 1);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 1);
+    EXPECT_EQ(event1Handler.GetCount(), 1);
+    EXPECT_EQ(event2Handler.GetCount(), 1);
 
     event1Handler.ClearCount();
     event2Handler.ClearCount();
@@ -151,42 +151,14 @@ void TestHandlerManagement(nlTestSuite * aSuite, void * aContext)
     // Remove all handlers, check neither works.
     delegate.ClearAllHandlers();
 
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(1) != CHIP_NO_ERROR);
-    NL_TEST_ASSERT(aSuite, delegate.HandleEventTriggers(2) != CHIP_NO_ERROR);
+    EXPECT_NE(delegate.HandleEventTriggers(1), CHIP_NO_ERROR);
+    EXPECT_NE(delegate.HandleEventTriggers(2), CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(aSuite, event1Handler.GetCount() == 0);
-    NL_TEST_ASSERT(aSuite, event2Handler.GetCount() == 0);
+    EXPECT_EQ(event1Handler.GetCount(), 0);
+    EXPECT_EQ(event2Handler.GetCount(), 0);
 
     // Add a handler at the end: having it remaining should not cause crashes/leaks.
-    NL_TEST_ASSERT(aSuite, delegate.AddHandler(&event2Handler) == CHIP_NO_ERROR);
-}
-
-int TestSetup(void * inContext)
-{
-    return SUCCESS;
-}
-
-int TestTeardown(void * inContext)
-{
-    return SUCCESS;
+    EXPECT_EQ(delegate.AddHandler(&event2Handler), CHIP_NO_ERROR);
 }
 
 } // namespace
-
-int TestTestEventTriggerDelegate()
-{
-    static nlTest sTests[] = { NL_TEST_DEF("TestKeyChecking", TestKeyChecking),
-                               NL_TEST_DEF("TestHandlerManagement", TestHandlerManagement), NL_TEST_SENTINEL() };
-
-    nlTestSuite theSuite = {
-        "TestTestEventTriggerDelegate",
-        &sTests[0],
-        TestSetup,
-        TestTeardown,
-    };
-
-    nlTestRunner(&theSuite, nullptr);
-    return (nlTestRunnerStats(&theSuite));
-}
-
-CHIP_REGISTER_TEST_SUITE(TestTestEventTriggerDelegate)
diff --git a/src/app/tests/TestTimeSyncDataProvider.cpp b/src/app/tests/TestTimeSyncDataProvider.cpp
index 3ea30d5582a642..016075375d8538 100644
--- a/src/app/tests/TestTimeSyncDataProvider.cpp
+++ b/src/app/tests/TestTimeSyncDataProvider.cpp
@@ -17,11 +17,10 @@
 
 #include <app/clusters/time-synchronization-server/TimeSyncDataProvider.h>
 #include <lib/core/CHIPPersistentStorageDelegate.h>
+#include <lib/core/StringBuilderAdapters.h>
 #include <lib/support/CHIPMemString.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
-#include <lib/support/UnitTestRegistration.h>
-
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 
 using namespace chip;
 using namespace chip::DeviceLayer;
@@ -36,7 +35,14 @@ using DSTOffset         = app::Clusters::TimeSynchronization::Structs::DSTOffset
 
 namespace {
 
-void TestTrustedTimeSourceStoreLoad(nlTestSuite * inSuite, void * inContext)
+class TestTimeSyncDataProvider : public ::testing::Test
+{
+public:
+    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
+    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
+};
+
+TEST_F(TestTimeSyncDataProvider, TestTrustedTimeSourceStoreLoad)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -44,16 +50,16 @@ void TestTrustedTimeSourceStoreLoad(nlTestSuite * inSuite, void * inContext)
 
     TrustedTimeSource tts = { chip::FabricIndex(1), chip::NodeId(20), chip::EndpointId(0) };
 
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreTrustedTimeSource(tts));
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreTrustedTimeSource(tts));
 
     TrustedTimeSource retrievedTrustedTimeSource;
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadTrustedTimeSource(retrievedTrustedTimeSource));
-    NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.fabricIndex == chip::FabricIndex(1));
-    NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.nodeID == chip::NodeId(20));
-    NL_TEST_ASSERT(inSuite, retrievedTrustedTimeSource.endpoint == chip::EndpointId(0));
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadTrustedTimeSource(retrievedTrustedTimeSource));
+    EXPECT_EQ(retrievedTrustedTimeSource.fabricIndex, chip::FabricIndex(1));
+    EXPECT_EQ(retrievedTrustedTimeSource.nodeID, chip::NodeId(20));
+    EXPECT_EQ(retrievedTrustedTimeSource.endpoint, chip::EndpointId(0));
 }
 
-void TestTrustedTimeSourceEmpty(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestTrustedTimeSourceEmpty)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -61,10 +67,10 @@ void TestTrustedTimeSourceEmpty(nlTestSuite * inSuite, void * inContext)
 
     TrustedTimeSource tts;
 
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadTrustedTimeSource(tts));
+    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadTrustedTimeSource(tts));
 }
 
-void TestDefaultNTPStoreLoad(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestDefaultNTPStoreLoad)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -73,22 +79,22 @@ void TestDefaultNTPStoreLoad(nlTestSuite * inSuite, void * inContext)
     char ntp[10] = "localhost";
     chip::CharSpan defaultNTP(ntp);
 
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreDefaultNtp(defaultNTP));
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreDefaultNtp(defaultNTP));
 
     char buf[5];
     chip::MutableCharSpan getDefaultNtp(buf);
 
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_BUFFER_TOO_SMALL == timeSyncDataProv.LoadDefaultNtp(getDefaultNtp));
-    NL_TEST_ASSERT(inSuite, getDefaultNtp.size() == 5);
+    EXPECT_EQ(CHIP_ERROR_BUFFER_TOO_SMALL, timeSyncDataProv.LoadDefaultNtp(getDefaultNtp));
+    EXPECT_EQ(getDefaultNtp.size(), 5u);
 
     char buf1[20];
     chip::MutableCharSpan getDefaultNtp1(buf1);
 
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadDefaultNtp(getDefaultNtp1));
-    NL_TEST_ASSERT(inSuite, getDefaultNtp1.size() == 10);
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadDefaultNtp(getDefaultNtp1));
+    EXPECT_EQ(getDefaultNtp1.size(), 10u);
 }
 
-void TestDefaultNTPEmpty(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestDefaultNTPEmpty)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -96,10 +102,10 @@ void TestDefaultNTPEmpty(nlTestSuite * inSuite, void * inContext)
 
     chip::MutableCharSpan defaultNTP;
 
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadDefaultNtp(defaultNTP));
+    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadDefaultNtp(defaultNTP));
 }
 
-void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestTimeZoneStoreLoad)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -122,26 +128,26 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext)
     TimeSyncDataProvider::TimeZoneStore tzS[3] = { makeTimeZone(1, 1, tzShort), makeTimeZone(2, 2, tzLong),
                                                    makeTimeZone(3, 3, tzBerlin) };
     TimeZoneList tzL(tzS);
-    NL_TEST_ASSERT(inSuite, tzL.size() == 3);
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreTimeZone(tzL));
+    EXPECT_EQ(tzL.size(), 3u);
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreTimeZone(tzL));
 
     TimeSyncDataProvider::TimeZoneStore emptyTzS[3] = { makeTimeZone(), makeTimeZone(), makeTimeZone() };
 
     tzL = TimeZoneList(emptyTzS);
     TimeSyncDataProvider::TimeZoneObj tzObj{ tzL, 3 };
-    NL_TEST_ASSERT(inSuite, tzL.size() == 3);
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadTimeZone(tzObj));
-    NL_TEST_ASSERT(inSuite, tzObj.validSize == 3);
+    EXPECT_EQ(tzL.size(), 3u);
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadTimeZone(tzObj));
+    EXPECT_EQ(tzObj.validSize, 3u);
 
-    NL_TEST_ASSERT(inSuite, !tzL.empty());
+    EXPECT_FALSE(tzL.empty());
 
     if (!tzL.empty())
     {
         auto & tz = tzL[0].timeZone;
-        NL_TEST_ASSERT(inSuite, tz.offset == 1);
-        NL_TEST_ASSERT(inSuite, tz.validAt == 1);
-        NL_TEST_ASSERT(inSuite, tz.name.HasValue());
-        NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 2);
+        EXPECT_EQ(tz.offset, 1);
+        EXPECT_EQ(tz.validAt, 1u);
+        EXPECT_TRUE(tz.name.HasValue());
+        EXPECT_EQ(tz.name.Value().size(), 2u);
 
         tzL = tzL.SubSpan(1);
     }
@@ -149,10 +155,10 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext)
     if (!tzL.empty())
     {
         auto & tz = tzL[0].timeZone;
-        NL_TEST_ASSERT(inSuite, tz.offset == 2);
-        NL_TEST_ASSERT(inSuite, tz.validAt == 2);
-        NL_TEST_ASSERT(inSuite, tz.name.HasValue());
-        NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 63);
+        EXPECT_EQ(tz.offset, 2);
+        EXPECT_EQ(tz.validAt, 2u);
+        EXPECT_TRUE(tz.name.HasValue());
+        EXPECT_EQ(tz.name.Value().size(), 63u);
 
         tzL = tzL.SubSpan(1);
     }
@@ -160,18 +166,18 @@ void TestTimeZoneStoreLoad(nlTestSuite * inSuite, void * inContext)
     if (!tzL.empty())
     {
         auto & tz = tzL[0].timeZone;
-        NL_TEST_ASSERT(inSuite, tz.offset == 3);
-        NL_TEST_ASSERT(inSuite, tz.validAt == 3);
-        NL_TEST_ASSERT(inSuite, tz.name.HasValue());
-        NL_TEST_ASSERT(inSuite, tz.name.Value().size() == 6);
+        EXPECT_EQ(tz.offset, 3);
+        EXPECT_EQ(tz.validAt, 3u);
+        EXPECT_TRUE(tz.name.HasValue());
+        EXPECT_EQ(tz.name.Value().size(), 6u);
 
         tzL = tzL.SubSpan(1);
     }
 
-    NL_TEST_ASSERT(inSuite, tzL.empty());
+    EXPECT_TRUE(tzL.empty());
 }
 
-void TestTimeZoneEmpty(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestTimeZoneEmpty)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -179,12 +185,12 @@ void TestTimeZoneEmpty(nlTestSuite * inSuite, void * inContext)
 
     TimeSyncDataProvider::TimeZoneObj timeZoneObj;
 
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadTimeZone(timeZoneObj));
-    NL_TEST_ASSERT(inSuite, !timeZoneObj.timeZoneList.begin());
-    NL_TEST_ASSERT(inSuite, timeZoneObj.validSize == 0);
+    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadTimeZone(timeZoneObj));
+    EXPECT_FALSE(timeZoneObj.timeZoneList.begin());
+    EXPECT_EQ(timeZoneObj.validSize, 0u);
 }
 
-void TestDSTOffset(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestDSTOffset)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -201,26 +207,26 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext)
     DSTOffset dstS[3] = { makeDSTOffset(1, 1, 2), makeDSTOffset(2, 2, 3), makeDSTOffset(3, 3) };
     DSTOffsetList dstL(dstS);
     TimeSyncDataProvider::DSTOffsetObj dstObj{ dstL, 3 };
-    NL_TEST_ASSERT(inSuite, dstObj.validSize == 3);
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.StoreDSTOffset(dstL));
+    EXPECT_EQ(dstObj.validSize, 3u);
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.StoreDSTOffset(dstL));
 
     DSTOffset emtpyDstS[3] = { makeDSTOffset(), makeDSTOffset(), makeDSTOffset() };
 
     dstObj.dstOffsetList = DSTOffsetList(emtpyDstS);
     dstObj.validSize     = 0;
-    NL_TEST_ASSERT(inSuite, dstObj.dstOffsetList.size() == 3);
-    NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == timeSyncDataProv.LoadDSTOffset(dstObj));
-    NL_TEST_ASSERT(inSuite, dstObj.validSize == 3);
+    EXPECT_EQ(dstObj.dstOffsetList.size(), 3u);
+    EXPECT_EQ(CHIP_NO_ERROR, timeSyncDataProv.LoadDSTOffset(dstObj));
+    EXPECT_EQ(dstObj.validSize, 3u);
 
-    NL_TEST_ASSERT(inSuite, !dstObj.dstOffsetList.empty());
+    EXPECT_FALSE(dstObj.dstOffsetList.empty());
 
     if (!dstObj.dstOffsetList.empty())
     {
         auto & dst = dstObj.dstOffsetList.data()[0];
-        NL_TEST_ASSERT(inSuite, dst.offset == 1);
-        NL_TEST_ASSERT(inSuite, dst.validStarting == 1);
-        NL_TEST_ASSERT(inSuite, !dst.validUntil.IsNull());
-        NL_TEST_ASSERT(inSuite, dst.validUntil.Value() == 2);
+        EXPECT_EQ(dst.offset, 1);
+        EXPECT_EQ(dst.validStarting, 1u);
+        EXPECT_FALSE(dst.validUntil.IsNull());
+        EXPECT_EQ(dst.validUntil.Value(), 2u);
 
         dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1);
     }
@@ -228,10 +234,10 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext)
     if (!dstObj.dstOffsetList.empty())
     {
         auto & dst = dstObj.dstOffsetList.data()[0];
-        NL_TEST_ASSERT(inSuite, dst.offset == 2);
-        NL_TEST_ASSERT(inSuite, dst.validStarting == 2);
-        NL_TEST_ASSERT(inSuite, !dst.validUntil.IsNull());
-        NL_TEST_ASSERT(inSuite, dst.validUntil.Value() == 3);
+        EXPECT_EQ(dst.offset, 2);
+        EXPECT_EQ(dst.validStarting, 2u);
+        EXPECT_FALSE(dst.validUntil.IsNull());
+        EXPECT_EQ(dst.validUntil.Value(), 3u);
 
         dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1);
     }
@@ -239,17 +245,17 @@ void TestDSTOffset(nlTestSuite * inSuite, void * inContext)
     if (!dstObj.dstOffsetList.empty())
     {
         auto & dst = dstObj.dstOffsetList.data()[0];
-        NL_TEST_ASSERT(inSuite, dst.offset == 3);
-        NL_TEST_ASSERT(inSuite, dst.validStarting == 3);
-        NL_TEST_ASSERT(inSuite, dst.validUntil.IsNull());
+        EXPECT_EQ(dst.offset, 3);
+        EXPECT_EQ(dst.validStarting, 3u);
+        EXPECT_TRUE(dst.validUntil.IsNull());
 
         dstObj.dstOffsetList = dstObj.dstOffsetList.SubSpan(1);
     }
 
-    NL_TEST_ASSERT(inSuite, dstObj.dstOffsetList.empty());
+    EXPECT_TRUE(dstObj.dstOffsetList.empty());
 }
 
-void TestDSTOffsetEmpty(nlTestSuite * inSuite, void * inContext)
+TEST_F(TestTimeSyncDataProvider, TestDSTOffsetEmpty)
 {
     TestPersistentStorageDelegate persistentStorage;
     TimeSyncDataProvider timeSyncDataProv;
@@ -257,42 +263,9 @@ void TestDSTOffsetEmpty(nlTestSuite * inSuite, void * inContext)
 
     TimeSyncDataProvider::DSTOffsetObj dstObj;
 
-    NL_TEST_ASSERT(inSuite, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND == timeSyncDataProv.LoadDSTOffset(dstObj));
-    NL_TEST_ASSERT(inSuite, !dstObj.dstOffsetList.begin());
-    NL_TEST_ASSERT(inSuite, dstObj.validSize == 0);
-}
-
-const nlTest sTests[] = { NL_TEST_DEF("Test TrustedTimeSource store load", TestTrustedTimeSourceStoreLoad),
-                          NL_TEST_DEF("Test TrustedTimeSource empty", TestTrustedTimeSourceEmpty),
-                          NL_TEST_DEF("Test default NTP store load", TestDefaultNTPStoreLoad),
-                          NL_TEST_DEF("Test default NTP empty", TestDefaultNTPEmpty),
-                          NL_TEST_DEF("Test time zone store load", TestTimeZoneStoreLoad),
-                          NL_TEST_DEF("Test time zone (empty list)", TestTimeZoneEmpty),
-                          NL_TEST_DEF("Test DSTOffset", TestDSTOffset),
-                          NL_TEST_DEF("Test DSTOffset (empty list)", TestDSTOffsetEmpty),
-                          NL_TEST_SENTINEL() };
-
-int TestSetup(void * inContext)
-{
-    VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE);
-    return SUCCESS;
-}
-
-int TestTearDown(void * inContext)
-{
-    chip::Platform::MemoryShutdown();
-    return SUCCESS;
+    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, timeSyncDataProv.LoadDSTOffset(dstObj));
+    EXPECT_FALSE(dstObj.dstOffsetList.begin());
+    EXPECT_EQ(dstObj.validSize, 0u);
 }
 
 } // namespace
-
-int TestTimeSyncDataProvider()
-{
-    nlTestSuite theSuite = { "Time Sync data provider tests", &sTests[0], TestSetup, TestTearDown };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestTimeSyncDataProvider)
diff --git a/src/app/tests/ember-test-compatibility.cpp b/src/app/tests/ember-test-compatibility.cpp
index 471f4cfd43fa8c..7b82854c96250a 100644
--- a/src/app/tests/ember-test-compatibility.cpp
+++ b/src/app/tests/ember-test-compatibility.cpp
@@ -11,8 +11,10 @@
 #include <messaging/ReliableMessageContext.h>
 
 namespace chip {
-uint8_t chip::Test::attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE];
-size_t chip::Test::attributeDataTLVLen = 0;
+uint8_t Test::attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE];
+size_t Test::attributeDataTLVLen = 0;
+chip::EndpointId Test::numEndpoints;
+
 namespace app {
 
 // was previously in TestWriteInteraction.cpp
@@ -125,3 +127,16 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr
 } // namespace app
 
 } // namespace chip
+
+// was previously in TestPowerSourceCluster.cpp
+uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster,
+                                              uint16_t fixedClusterServerEndpointCount)
+{
+    // Very simple mapping here, we're just going to return the endpoint that matches the given endpoint index because the test
+    // uses the endpoints in order.
+    if (endpoint >= chip::Test::numEndpoints)
+    {
+        return kEmberInvalidEndpointIndex;
+    }
+    return endpoint;
+}
diff --git a/src/app/tests/ember-test-compatibility.h b/src/app/tests/ember-test-compatibility.h
index c214cba275396f..62860b332b96b0 100644
--- a/src/app/tests/ember-test-compatibility.h
+++ b/src/app/tests/ember-test-compatibility.h
@@ -3,6 +3,7 @@
 #include <app/CommandHandler.h>
 #include <app/ConcreteCommandPath.h>
 #include <app/WriteHandler.h>
+#include <app/util/attribute-storage.h>
 #include <app/util/mock/Constants.h>
 #include <app/util/mock/Functions.h>
 
@@ -22,6 +23,8 @@ constexpr chip::DataVersion kRejectedDataVersion = 1;
 extern uint8_t attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE];
 extern size_t attributeDataTLVLen;
 
+extern chip::EndpointId numEndpoints;
+
 } // namespace Test
 namespace app {
 
@@ -44,5 +47,9 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPat
                                   CommandHandler * apCommandObj);
 
 bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint);
+
 } // namespace app
 } // namespace chip
+
+uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster,
+                                              uint16_t fixedClusterServerEndpointCount);