pw_unit_test migration: lib support batch 2 (#33144)

* pw_unit_test migration: lib support batch 2

* restyle
diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn
index 2a9c1ac..585233b 100644
--- a/src/lib/support/tests/BUILD.gn
+++ b/src/lib/support/tests/BUILD.gn
@@ -25,11 +25,18 @@
   test_sources = [
     "TestBitMask.cpp",
     "TestBufferReader.cpp",
+    "TestBytesToHex.cpp",
     "TestDefer.cpp",
     "TestFixedBufferAllocator.cpp",
     "TestFold.cpp",
     "TestIniEscaping.cpp",
     "TestSafeInt.cpp",
+    "TestSafeString.cpp",
+    "TestScoped.cpp",
+    "TestSpan.cpp",
+    "TestStaticSupportSmartPtr.cpp",
+    "TestTestPersistentStorageDelegate.cpp",
+    "TestUtf8.cpp",
   ]
   sources = []
 
@@ -59,7 +66,6 @@
   test_sources = [
     "TestBufferWriter.cpp",
     "TestBytesCircularBuffer.cpp",
-    "TestBytesToHex.cpp",
     "TestCHIPCounter.cpp",
     "TestCHIPMem.cpp",
     "TestCHIPMemString.cpp",
@@ -70,21 +76,15 @@
     "TestPersistedCounter.cpp",
     "TestPool.cpp",
     "TestPrivateHeap.cpp",
-    "TestSafeString.cpp",
-    "TestScoped.cpp",
     "TestScopedBuffer.cpp",
     "TestSorting.cpp",
-    "TestSpan.cpp",
     "TestStateMachine.cpp",
-    "TestStaticSupportSmartPtr.cpp",
     "TestStringBuilder.cpp",
     "TestStringSplitter.cpp",
-    "TestTestPersistentStorageDelegate.cpp",
     "TestThreadOperationalDataset.cpp",
     "TestTimeUtils.cpp",
     "TestTlvJson.cpp",
     "TestTlvToJson.cpp",
-    "TestUtf8.cpp",
     "TestVariant.cpp",
     "TestZclString.cpp",
   ]
diff --git a/src/lib/support/tests/TestBytesToHex.cpp b/src/lib/support/tests/TestBytesToHex.cpp
index f5ac6ef..1e30481 100644
--- a/src/lib/support/tests/TestBytesToHex.cpp
+++ b/src/lib/support/tests/TestBytesToHex.cpp
@@ -20,15 +20,13 @@
 #include <string>
 #include <vector>
 
+#include <gtest/gtest.h>
+
 #include <lib/support/BytesToHex.h>
 #include <lib/support/CodeUtils.h>
 #include <lib/support/EnforceFormat.h>
 #include <lib/support/Span.h>
-#include <lib/support/UnitTestRegistration.h>
 #include <lib/support/logging/CHIPLogging.h>
-
-#include <nlunit-test.h>
-
 namespace {
 
 using namespace chip;
@@ -37,7 +35,7 @@
 // To accumulate redirected logs for some tests
 std::vector<std::string> gRedirectedLogLines;
 
-void TestBytesToHexNotNullTerminated(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestBytesToHexNotNullTerminated)
 {
     // Uppercase
     {
@@ -45,12 +43,11 @@
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char dest2[18]    = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { 'F', 'E', 'D', 'C', 'B', 'A', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '!', '@' };
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kUppercase) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kUppercase), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite, BytesToUppercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest2[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToUppercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Lowercase
@@ -59,12 +56,12 @@
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char dest2[18]    = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '!', '@' };
-        NL_TEST_ASSERT(inSuite, BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kNone) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(src) * 2u, HexFlags::kNone), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
         // Test Alias
-        NL_TEST_ASSERT(inSuite, BytesToLowercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest2[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToLowercaseHexBuffer(&src[0], sizeof(src), &dest2[0], sizeof(src) * 2u), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Trivial: Zero size input
@@ -72,28 +69,28 @@
         uint8_t src[]    = { 0x00 };
         char dest[2]     = { '!', '@' };
         char expected[2] = { '!', '@' };
-        NL_TEST_ASSERT(inSuite, BytesToHex(&src[0], 0, &dest[0], sizeof(src) * 2u, HexFlags::kNone) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(&src[0], 0, &dest[0], sizeof(src) * 2u, HexFlags::kNone), CHIP_NO_ERROR);
         // Nothing should have been touched.
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Trivial: Zero size input with null buffer
     {
         char dest[2]     = { '!', '@' };
         char expected[2] = { '!', '@' };
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNone) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNone), CHIP_NO_ERROR);
         // Nothing should have been touched.
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNone) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNone), CHIP_NO_ERROR);
         // Nothing should have been touched.
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNone) == CHIP_ERROR_INVALID_ARGUMENT);
+        EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNone), CHIP_ERROR_INVALID_ARGUMENT);
     }
 }
 
-void TestBytesToHexNullTerminated(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestBytesToHexNullTerminated)
 {
     // Uppercase
     {
@@ -101,17 +98,16 @@
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char dest2[18]    = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0', '@' };
-        NL_TEST_ASSERT(inSuite, ((sizeof(src) * 2u) + 1u) <= sizeof(dest));
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kUppercaseAndNullTerminate) ==
-                           CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest));
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kUppercaseAndNullTerminate),
+                  CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
         // Test Alias
         CHIP_ERROR retval = BytesToUppercaseHexString(&src[0], sizeof(src), &dest2[0], sizeof(dest2));
         printf("retval=%" CHIP_ERROR_FORMAT "\n", retval.Format());
-        NL_TEST_ASSERT(inSuite, retval == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest2[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(retval, CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Lowercase
@@ -120,15 +116,14 @@
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char dest2[18]    = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0', '@' };
-        NL_TEST_ASSERT(inSuite, ((sizeof(src) * 2u) + 1u) <= sizeof(dest));
-        NL_TEST_ASSERT(
-            inSuite, BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kNullTerminate) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest));
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) + 1, HexFlags::kNullTerminate), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
         // Test Alias
-        NL_TEST_ASSERT(inSuite, BytesToLowercaseHexString(&src[0], sizeof(src), &dest2[0], sizeof(dest2)) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToLowercaseHexString(&src[0], sizeof(src), &dest2[0], sizeof(dest2)), CHIP_NO_ERROR);
         printf("->%s\n", dest2);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest2[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest2[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Trivial: Zero size input
@@ -136,36 +131,36 @@
         uint8_t src[]    = { 0x00 };
         char dest[2]     = { '!', '@' };
         char expected[2] = { '\0', '@' };
-        NL_TEST_ASSERT(inSuite, BytesToHex(&src[0], 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(&src[0], 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR);
         // Expect nul termination
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Trivial: Zero size input with null buffer
     {
         char dest[2]     = { '!', '@' };
         char expected[2] = { '\0', '@' };
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR);
         // Nothing should have been touched.
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNullTerminate) == CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 0, HexFlags::kNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL);
 
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, &dest[0], 1, HexFlags::kNullTerminate) == CHIP_NO_ERROR);
+        EXPECT_EQ(BytesToHex(nullptr, 0, &dest[0], 1, HexFlags::kNullTerminate), CHIP_NO_ERROR);
         // Nothing should have been touched.
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite, BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNullTerminate) == CHIP_ERROR_INVALID_ARGUMENT);
+        EXPECT_EQ(BytesToHex(nullptr, 0, nullptr, 1, HexFlags::kNullTerminate), CHIP_ERROR_INVALID_ARGUMENT);
     }
 }
 
-void TestBytesToHexErrors(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestBytesToHexErrors)
 {
     // NULL destination
     {
         uint8_t src[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
         char * dest   = nullptr;
-        NL_TEST_ASSERT(inSuite, BytesToHex(&src[0], 0, dest, sizeof(src) * 2u, HexFlags::kNone) == CHIP_ERROR_INVALID_ARGUMENT);
+        EXPECT_EQ(BytesToHex(&src[0], 0, dest, sizeof(src) * 2u, HexFlags::kNone), CHIP_ERROR_INVALID_ARGUMENT);
     }
 
     // Destination buffer too small for non-null-terminated
@@ -173,12 +168,10 @@
         uint8_t src[]     = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
-        NL_TEST_ASSERT(inSuite, ((sizeof(src) * 2u) + 1u) <= sizeof(dest));
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) - 1, HexFlags::kNone) ==
-                           CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest));
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u) - 1, HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL);
         // Ensure output not touched
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Destination buffer too small for null-terminated
@@ -186,12 +179,11 @@
         uint8_t src[]     = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
-        NL_TEST_ASSERT(inSuite, ((sizeof(src) * 2u) + 1u) <= sizeof(dest));
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u), HexFlags::kNullTerminate) ==
-                           CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_LE(((sizeof(src) * 2u) + 1u), sizeof(dest));
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], (sizeof(src) * 2u), HexFlags::kNullTerminate),
+                  CHIP_ERROR_BUFFER_TOO_SMALL);
         // Ensure output not touched
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Writing in a larger buffer is fine, bytes past the nul terminator (when requested) are untouched.
@@ -199,10 +191,9 @@
         uint8_t src[]     = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0', '@' };
-        NL_TEST_ASSERT(inSuite, ((sizeof(src) * 2u) + 1u) < sizeof(dest));
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(dest), HexFlags::kNullTerminate) == CHIP_NO_ERROR);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_LT(((sizeof(src) * 2u) + 1u), sizeof(dest));
+        EXPECT_EQ(BytesToHex(&src[0], sizeof(src), &dest[0], sizeof(dest), HexFlags::kNullTerminate), CHIP_NO_ERROR);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 
     // Source size that would not fit in any output using size_t
@@ -210,18 +201,16 @@
         uint8_t src[]     = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
         char dest[18]     = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
         char expected[18] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '!', '@' };
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNullTerminate) ==
-                           CHIP_ERROR_BUFFER_TOO_SMALL);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNullTerminate),
+                  CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
 
-        NL_TEST_ASSERT(inSuite,
-                       BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNone) == CHIP_ERROR_BUFFER_TOO_SMALL);
-        NL_TEST_ASSERT(inSuite, memcmp(&dest[0], &expected[0], sizeof(expected)) == 0);
+        EXPECT_EQ(BytesToHex(&src[0], SIZE_MAX / 2u, &dest[0], sizeof(dest), HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL);
+        EXPECT_EQ(memcmp(&dest[0], &expected[0], sizeof(expected)), 0);
     }
 }
 
-void TestBytesToHexUint64(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestBytesToHexUint64)
 {
     // Different values in each byte and each nibble should let us know if the conversion is correct.
     uint64_t test     = 0x0123456789ABCDEF;
@@ -237,62 +226,54 @@
 
     // Lower case - uint64_t.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNone) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, lowerExpected, strlen(lowerExpected)) == 0);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNone), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, lowerExpected, strlen(lowerExpected)), 0);
     // No null termination.
-    NL_TEST_ASSERT(inSuite, buf[16] == 1);
+    EXPECT_EQ(buf[16], 1);
 
     // Lower case - uint32_t.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint32ToHex(test32_0, buf, sizeof(uint32_t) * 2, HexFlags::kNone) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite,
-                   Uint32ToHex(test32_1, &buf[sizeof(uint32_t) * 2], sizeof(uint32_t) * 2, HexFlags::kNone) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, lowerExpected, strlen(lowerExpected)) == 0);
+    EXPECT_EQ(Uint32ToHex(test32_0, buf, sizeof(uint32_t) * 2, HexFlags::kNone), CHIP_NO_ERROR);
+    EXPECT_EQ(Uint32ToHex(test32_1, &buf[sizeof(uint32_t) * 2], sizeof(uint32_t) * 2, HexFlags::kNone), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, lowerExpected, strlen(lowerExpected)), 0);
     // No null termination.
-    NL_TEST_ASSERT(inSuite, buf[16] == 1);
+    EXPECT_EQ(buf[16], 1);
 
     // Upper case - uint64_t.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercase) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, upperExpected, strlen(upperExpected)) == 0);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercase), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, upperExpected, strlen(upperExpected)), 0);
     // No null termination.
-    NL_TEST_ASSERT(inSuite, buf[16] == 1);
+    EXPECT_EQ(buf[16], 1);
 
     // Upper case - uint16_t.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint16ToHex(test16_0, buf, sizeof(uint16_t) * 2, HexFlags::kUppercase) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite,
-                   Uint16ToHex(test16_1, &buf[sizeof(uint16_t) * 2 * 1], sizeof(uint16_t) * 2, HexFlags::kUppercase) ==
-                       CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite,
-                   Uint16ToHex(test16_2, &buf[sizeof(uint16_t) * 2 * 2], sizeof(uint16_t) * 2, HexFlags::kUppercase) ==
-                       CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite,
-                   Uint16ToHex(test16_3, &buf[sizeof(uint16_t) * 2 * 3], sizeof(uint16_t) * 2, HexFlags::kUppercase) ==
-                       CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, upperExpected, strlen(upperExpected)) == 0);
+    EXPECT_EQ(Uint16ToHex(test16_0, buf, sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR);
+    EXPECT_EQ(Uint16ToHex(test16_1, &buf[sizeof(uint16_t) * 2 * 1], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR);
+    EXPECT_EQ(Uint16ToHex(test16_2, &buf[sizeof(uint16_t) * 2 * 2], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR);
+    EXPECT_EQ(Uint16ToHex(test16_3, &buf[sizeof(uint16_t) * 2 * 3], sizeof(uint16_t) * 2, HexFlags::kUppercase), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, upperExpected, strlen(upperExpected)), 0);
     // No null termination.
-    NL_TEST_ASSERT(inSuite, buf[16] == 1);
+    EXPECT_EQ(buf[16], 1);
 
     // Lower case with null termination.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNullTerminate) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, lowerExpected, sizeof(lowerExpected)) == 0);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kNullTerminate), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, lowerExpected, sizeof(lowerExpected)), 0);
 
     // Upper case with null termination.
     memset(buf, 1, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercaseAndNullTerminate) == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, memcmp(buf, upperExpected, sizeof(upperExpected)) == 0);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf), HexFlags::kUppercaseAndNullTerminate), CHIP_NO_ERROR);
+    EXPECT_EQ(memcmp(buf, upperExpected, sizeof(upperExpected)), 0);
 
     // Too small buffer
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kNone) == CHIP_ERROR_BUFFER_TOO_SMALL);
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kUppercase) == CHIP_ERROR_BUFFER_TOO_SMALL);
-    NL_TEST_ASSERT(inSuite, Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kNullTerminate) == CHIP_ERROR_BUFFER_TOO_SMALL);
-    NL_TEST_ASSERT(inSuite,
-                   Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kUppercaseAndNullTerminate) == CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kNone), CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 2, HexFlags::kUppercase), CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(Uint64ToHex(test, buf, sizeof(buf) - 1, HexFlags::kUppercaseAndNullTerminate), CHIP_ERROR_BUFFER_TOO_SMALL);
 }
 
-void TestHexToBytesAndUint(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestHexToBytesAndUint)
 {
     // Different values in each byte and each nibble should let us know if the conversion is correct.
     char hexInLowercase[]      = "0123456789abcdef";
@@ -310,32 +291,32 @@
 
     // Lower case - bytes.
     memset(buf, 0, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, HexToBytes(hexInLowercase, strlen(hexInLowercase), buf, sizeof(buf)) == sizeof(buf));
-    NL_TEST_ASSERT(inSuite, memcmp(buf, bytesOutExpected, sizeof(buf)) == 0);
+    EXPECT_EQ(HexToBytes(hexInLowercase, strlen(hexInLowercase), buf, sizeof(buf)), sizeof(buf));
+    EXPECT_EQ(memcmp(buf, bytesOutExpected, sizeof(buf)), 0);
 
     // Upper case - bytes.
     memset(buf, 0, sizeof(buf));
-    NL_TEST_ASSERT(inSuite, HexToBytes(hexInUppercase, strlen(hexInUppercase), buf, sizeof(buf)) == sizeof(buf));
-    NL_TEST_ASSERT(inSuite, memcmp(buf, bytesOutExpected, sizeof(buf)) == 0);
+    EXPECT_EQ(HexToBytes(hexInUppercase, strlen(hexInUppercase), buf, sizeof(buf)), sizeof(buf));
+    EXPECT_EQ(memcmp(buf, bytesOutExpected, sizeof(buf)), 0);
 
     // Lower case - uint64_t.
     test64Out = 0;
-    NL_TEST_ASSERT(inSuite, UppercaseHexToUint64(hexInLowercase, strlen(hexInLowercase), test64Out) == 0);
+    EXPECT_EQ(UppercaseHexToUint64(hexInLowercase, strlen(hexInLowercase), test64Out), 0u);
 
     // Upper case - uint64_t.
     test64Out = 0;
-    NL_TEST_ASSERT(inSuite, UppercaseHexToUint64(hexInUppercase, strlen(hexInUppercase), test64Out) == sizeof(uint64_t));
-    NL_TEST_ASSERT(inSuite, test64Out == test64OutExpected);
+    EXPECT_EQ(UppercaseHexToUint64(hexInUppercase, strlen(hexInUppercase), test64Out), sizeof(uint64_t));
+    EXPECT_EQ(test64Out, test64OutExpected);
 
     // Upper case - uint32_t.
     test32Out = 0;
-    NL_TEST_ASSERT(inSuite, UppercaseHexToUint32(hexInUppercase32, strlen(hexInUppercase32), test32Out) == sizeof(uint32_t));
-    NL_TEST_ASSERT(inSuite, test32Out == test32OutExpected);
+    EXPECT_EQ(UppercaseHexToUint32(hexInUppercase32, strlen(hexInUppercase32), test32Out), sizeof(uint32_t));
+    EXPECT_EQ(test32Out, test32OutExpected);
 
     // Upper case - uint16_t.
     test16Out = 0;
-    NL_TEST_ASSERT(inSuite, UppercaseHexToUint16(hexInUppercase16, strlen(hexInUppercase16), test16Out) == sizeof(uint16_t));
-    NL_TEST_ASSERT(inSuite, test16Out == test16OutExpected);
+    EXPECT_EQ(UppercaseHexToUint16(hexInUppercase16, strlen(hexInUppercase16), test16Out), sizeof(uint16_t));
+    EXPECT_EQ(test16Out, test16OutExpected);
 }
 
 #if CHIP_PROGRESS_LOGGING
@@ -351,9 +332,9 @@
     gRedirectedLogLines.push_back(std::string(line));
 }
 
-void ValidateTextMatches(nlTestSuite * inSuite, const char ** expected, size_t numLines, const std::vector<std::string> & candidate)
+void ValidateTextMatches(const char ** expected, size_t numLines, const std::vector<std::string> & candidate)
 {
-    NL_TEST_ASSERT(inSuite, candidate.size() == numLines);
+    EXPECT_EQ(candidate.size(), numLines);
     if (candidate.size() != numLines)
     {
         return;
@@ -361,7 +342,7 @@
     for (size_t idx = 0; idx < numLines; idx++)
     {
         printf("Checking '%s' against '%s'\n", candidate.at(idx).c_str(), expected[idx]);
-        NL_TEST_ASSERT(inSuite, candidate.at(idx) == expected[idx]);
+        EXPECT_EQ(candidate.at(idx), expected[idx]);
         if (candidate.at(idx) != expected[idx])
         {
             return;
@@ -369,7 +350,7 @@
     }
 }
 
-void TestLogBufferAsHex(nlTestSuite * inSuite, void * inContext)
+TEST(TestBytesToHex, TestLogBufferAsHex)
 {
     const char * kExpectedText1[] = {
         ">>>A54A39294B28886E8BFC15B44105A3FD22745225983A753E6BB82DA7C62493BF",
@@ -425,31 +406,9 @@
             LogBufferAsHex(testCase.label, testCase.buffer);
         }
         chip::Logging::SetLogRedirectCallback(nullptr);
-        ValidateTextMatches(inSuite, testCase.expectedText, testCase.numLines, gRedirectedLogLines);
+        ValidateTextMatches(testCase.expectedText, testCase.numLines, gRedirectedLogLines);
     }
 }
 
 #endif
-
-const nlTest sTests[] = {
-    NL_TEST_DEF("TestBytesToHexNotNullTerminated", TestBytesToHexNotNullTerminated), //
-    NL_TEST_DEF("TestBytesToHexNullTerminated", TestBytesToHexNullTerminated),       //
-    NL_TEST_DEF("TestBytesToHexErrors", TestBytesToHexErrors),                       //
-    NL_TEST_DEF("TestBytesToHexUint64", TestBytesToHexUint64),                       //
-    NL_TEST_DEF("TestHexToBytesAndUint", TestHexToBytesAndUint),                     //
-#if CHIP_PROGRESS_LOGGING
-    NL_TEST_DEF("TestLogBufferAsHex", TestLogBufferAsHex), //
-#endif
-    NL_TEST_SENTINEL() //
-};
-
 } // namespace
-
-int TestBytesToHex()
-{
-    nlTestSuite theSuite = { "BytesToHex", sTests, nullptr, nullptr };
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestBytesToHex)
diff --git a/src/lib/support/tests/TestSafeString.cpp b/src/lib/support/tests/TestSafeString.cpp
index 2dc52d3..09e7d89 100644
--- a/src/lib/support/tests/TestSafeString.cpp
+++ b/src/lib/support/tests/TestSafeString.cpp
@@ -22,45 +22,27 @@
  *
  */
 
-#include <lib/support/SafeString.h>
-#include <lib/support/UnitTestRegistration.h>
+#include <gtest/gtest.h>
 
-#include <nlunit-test.h>
+#include <lib/support/SafeString.h>
 
 using namespace chip;
 
-static void TestMaxStringLength(nlTestSuite * inSuite, void * inContext)
+TEST(TestSafeString, TestMaxStringLength)
 {
     constexpr size_t len = MaxStringLength("a", "bc", "def");
-    NL_TEST_ASSERT(inSuite, len == 3);
+    EXPECT_EQ(len, 3u);
 
-    NL_TEST_ASSERT(inSuite, MaxStringLength("bc") == 2);
+    EXPECT_EQ(MaxStringLength("bc"), 2u);
 
-    NL_TEST_ASSERT(inSuite, MaxStringLength("def", "bc", "a") == 3);
+    EXPECT_EQ(MaxStringLength("def", "bc", "a"), 3u);
 
-    NL_TEST_ASSERT(inSuite, MaxStringLength("") == 0);
+    EXPECT_EQ(MaxStringLength(""), 0u);
 }
 
-static void TestTotalStringLength(nlTestSuite * inSuite, void * inContext)
+TEST(TestSafeString, TestTotalStringLength)
 {
-    NL_TEST_ASSERT(inSuite, TotalStringLength("") == 0);
-    NL_TEST_ASSERT(inSuite, TotalStringLength("a") == 1);
-    NL_TEST_ASSERT(inSuite, TotalStringLength("def", "bc", "a") == 6);
+    EXPECT_EQ(TotalStringLength(""), 0u);
+    EXPECT_EQ(TotalStringLength("a"), 1u);
+    EXPECT_EQ(TotalStringLength("def", "bc", "a"), 6u);
 }
-
-#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(TestMaxStringLength), NL_TEST_DEF_FN(TestTotalStringLength), NL_TEST_SENTINEL() };
-
-int TestSafeString()
-{
-    nlTestSuite theSuite = { "CHIP SafeString tests", &sTests[0], nullptr, nullptr };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestSafeString)
diff --git a/src/lib/support/tests/TestScoped.cpp b/src/lib/support/tests/TestScoped.cpp
index 90cdd62..fef70a4 100644
--- a/src/lib/support/tests/TestScoped.cpp
+++ b/src/lib/support/tests/TestScoped.cpp
@@ -16,87 +16,66 @@
  *    limitations under the License.
  */
 
-#include <lib/support/Scoped.h>
-#include <lib/support/UnitTestRegistration.h>
-
-#include <nlunit-test.h>
 #include <string.h>
 
+#include <gtest/gtest.h>
+
+#include <lib/support/Scoped.h>
+
 namespace {
 
 using namespace chip;
 
-void TestScopedVariableChange(nlTestSuite * inSuite, void * inContext)
+TEST(TestScoped, TestScopedVariableChange)
 {
     int x = 123;
 
     {
         ScopedChange change1(x, 10);
-        NL_TEST_ASSERT(inSuite, x == 10);
+        EXPECT_EQ(x, 10);
 
         x = 15;
         {
             ScopedChange change2(x, 20);
-            NL_TEST_ASSERT(inSuite, x == 20);
+            EXPECT_EQ(x, 20);
         }
-        NL_TEST_ASSERT(inSuite, x == 15);
+        EXPECT_EQ(x, 15);
     }
-    NL_TEST_ASSERT(inSuite, x == 123);
+    EXPECT_EQ(x, 123);
 }
 
-void TestScopedChangeOnly(nlTestSuite * inSuite, void * inContext)
+TEST(TestScoped, TestScopedChangeOnly)
 {
     ScopedChangeOnly intValue(123);
     ScopedChangeOnly strValue("abc");
 
-    NL_TEST_ASSERT(inSuite, intValue == 123);
-    NL_TEST_ASSERT(inSuite, strcmp(strValue, "abc") == 0);
+    EXPECT_EQ(intValue, 123);
+    EXPECT_STREQ(strValue, "abc");
 
     {
         ScopedChange change1(intValue, 234);
 
-        NL_TEST_ASSERT(inSuite, intValue == 234);
-        NL_TEST_ASSERT(inSuite, strcmp(strValue, "abc") == 0);
+        EXPECT_EQ(intValue, 234);
+        EXPECT_STREQ(strValue, "abc");
 
         ScopedChange change2(strValue, "xyz");
-        NL_TEST_ASSERT(inSuite, intValue == 234);
-        NL_TEST_ASSERT(inSuite, strcmp(strValue, "xyz") == 0);
+        EXPECT_EQ(intValue, 234);
+        EXPECT_STREQ(strValue, "xyz");
 
         {
             ScopedChange change3(intValue, 10);
             ScopedChange change4(strValue, "test");
 
-            NL_TEST_ASSERT(inSuite, intValue == 10);
-            NL_TEST_ASSERT(inSuite, strcmp(strValue, "test") == 0);
+            EXPECT_EQ(intValue, 10);
+            EXPECT_STREQ(strValue, "test");
         }
 
-        NL_TEST_ASSERT(inSuite, intValue == 234);
-        NL_TEST_ASSERT(inSuite, strcmp(strValue, "xyz") == 0);
+        EXPECT_EQ(intValue, 234);
+        EXPECT_STREQ(strValue, "xyz");
     }
 
-    NL_TEST_ASSERT(inSuite, intValue == 123);
-    NL_TEST_ASSERT(inSuite, strcmp(strValue, "abc") == 0);
+    EXPECT_EQ(intValue, 123);
+    EXPECT_STREQ(strValue, "abc");
 }
 
 } // 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(TestScopedVariableChange), //
-    NL_TEST_DEF_FN(TestScopedChangeOnly),     //
-    NL_TEST_SENTINEL()                        //
-};
-
-int TestScoped()
-{
-    nlTestSuite theSuite = { "CHIP Scoped tests", &sTests[0], nullptr, nullptr };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestScoped)
diff --git a/src/lib/support/tests/TestSpan.cpp b/src/lib/support/tests/TestSpan.cpp
index 87f52ae..6849138 100644
--- a/src/lib/support/tests/TestSpan.cpp
+++ b/src/lib/support/tests/TestSpan.cpp
@@ -22,256 +22,255 @@
  *
  */
 
-#include <lib/support/Span.h>
-#include <lib/support/UnitTestRegistration.h>
-
-#include <nlunit-test.h>
-
 #include <array>
 
+#include <gtest/gtest.h>
+
+#include <lib/support/Span.h>
+
 using namespace chip;
 
-static void TestByteSpan(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestByteSpan)
 {
     uint8_t arr[] = { 1, 2, 3 };
 
     ByteSpan s0 = ByteSpan();
-    NL_TEST_ASSERT(inSuite, s0.size() == 0);
-    NL_TEST_ASSERT(inSuite, s0.empty());
-    NL_TEST_ASSERT(inSuite, s0.data_equal(s0));
+    EXPECT_EQ(s0.size(), 0u);
+    EXPECT_TRUE(s0.empty());
+    EXPECT_TRUE(s0.data_equal(s0));
 
     ByteSpan s1(arr, 2);
-    NL_TEST_ASSERT(inSuite, s1.data() == arr);
-    NL_TEST_ASSERT(inSuite, s1.size() == 2);
-    NL_TEST_ASSERT(inSuite, !s1.empty());
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s1));
-    NL_TEST_ASSERT(inSuite, !s1.data_equal(s0));
+    EXPECT_EQ(s1.data(), arr);
+    EXPECT_EQ(s1.size(), 2u);
+    EXPECT_FALSE(s1.empty());
+    EXPECT_TRUE(s1.data_equal(s1));
+    EXPECT_FALSE(s1.data_equal(s0));
 
     ByteSpan s2(arr);
-    NL_TEST_ASSERT(inSuite, s2.data() == arr);
-    NL_TEST_ASSERT(inSuite, s2.size() == 3);
-    NL_TEST_ASSERT(inSuite, s2.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, !s2.empty());
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s2));
-    NL_TEST_ASSERT(inSuite, !s2.data_equal(s1));
-    NL_TEST_ASSERT(inSuite, s2.front() == 1);
-    NL_TEST_ASSERT(inSuite, s2.back() == 3);
-    NL_TEST_ASSERT(inSuite, s2[0] == 1);
-    NL_TEST_ASSERT(inSuite, s2[1] == 2);
-    NL_TEST_ASSERT(inSuite, s2[2] == 3);
+    EXPECT_EQ(s2.data(), arr);
+    EXPECT_EQ(s2.size(), 3u);
+    EXPECT_EQ(s2.data()[2], 3u);
+    EXPECT_FALSE(s2.empty());
+    EXPECT_TRUE(s2.data_equal(s2));
+    EXPECT_FALSE(s2.data_equal(s1));
+    EXPECT_EQ(s2.front(), 1u);
+    EXPECT_EQ(s2.back(), 3u);
+    EXPECT_EQ(s2[0], 1u);
+    EXPECT_EQ(s2[1], 2u);
+    EXPECT_EQ(s2[2], 3u);
 
     ByteSpan s3 = s2;
-    NL_TEST_ASSERT(inSuite, s3.data() == arr);
-    NL_TEST_ASSERT(inSuite, s3.size() == 3);
-    NL_TEST_ASSERT(inSuite, s3.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, !s3.empty());
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s2));
+    EXPECT_EQ(s3.data(), arr);
+    EXPECT_EQ(s3.size(), 3u);
+    EXPECT_EQ(s3.data()[2], 3u);
+    EXPECT_FALSE(s3.empty());
+    EXPECT_TRUE(s3.data_equal(s2));
 
     uint8_t arr2[] = { 3, 2, 1 };
     ByteSpan s4(arr2);
-    NL_TEST_ASSERT(inSuite, !s4.data_equal(s2));
+    EXPECT_FALSE(s4.data_equal(s2));
 
     ByteSpan s5(arr2, 0);
-    NL_TEST_ASSERT(inSuite, s5.data() != nullptr);
-    NL_TEST_ASSERT(inSuite, !s5.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s5.data_equal(s0));
-    NL_TEST_ASSERT(inSuite, s0.data_equal(s5));
+    EXPECT_NE(s5.data(), nullptr);
+    EXPECT_FALSE(s5.data_equal(s4));
+    EXPECT_TRUE(s5.data_equal(s0));
+    EXPECT_TRUE(s0.data_equal(s5));
 
     ByteSpan s6(arr2);
     s6.reduce_size(2);
-    NL_TEST_ASSERT(inSuite, s6.size() == 2);
+    EXPECT_EQ(s6.size(), 2u);
     ByteSpan s7(arr2, 2);
-    NL_TEST_ASSERT(inSuite, s6.data_equal(s7));
-    NL_TEST_ASSERT(inSuite, s7.data_equal(s6));
+    EXPECT_TRUE(s6.data_equal(s7));
+    EXPECT_TRUE(s7.data_equal(s6));
 }
 
-static void TestMutableByteSpan(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestMutableByteSpan)
 {
     uint8_t arr[] = { 1, 2, 3 };
 
     MutableByteSpan s0 = MutableByteSpan();
-    NL_TEST_ASSERT(inSuite, s0.size() == 0);
-    NL_TEST_ASSERT(inSuite, s0.empty());
-    NL_TEST_ASSERT(inSuite, s0.data_equal(s0));
+    EXPECT_EQ(s0.size(), 0u);
+    EXPECT_TRUE(s0.empty());
+    EXPECT_TRUE(s0.data_equal(s0));
 
     MutableByteSpan s1(arr, 2);
-    NL_TEST_ASSERT(inSuite, s1.data() == arr);
-    NL_TEST_ASSERT(inSuite, s1.size() == 2);
-    NL_TEST_ASSERT(inSuite, !s1.empty());
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s1));
-    NL_TEST_ASSERT(inSuite, !s1.data_equal(s0));
+    EXPECT_EQ(s1.data(), arr);
+    EXPECT_EQ(s1.size(), 2u);
+    EXPECT_FALSE(s1.empty());
+    EXPECT_TRUE(s1.data_equal(s1));
+    EXPECT_FALSE(s1.data_equal(s0));
 
     MutableByteSpan s2(arr);
-    NL_TEST_ASSERT(inSuite, s2.data() == arr);
-    NL_TEST_ASSERT(inSuite, s2.size() == 3);
-    NL_TEST_ASSERT(inSuite, s2.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, !s2.empty());
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s2));
-    NL_TEST_ASSERT(inSuite, !s2.data_equal(s1));
+    EXPECT_EQ(s2.data(), arr);
+    EXPECT_EQ(s2.size(), 3u);
+    EXPECT_EQ(s2.data()[2], 3u);
+    EXPECT_FALSE(s2.empty());
+    EXPECT_TRUE(s2.data_equal(s2));
+    EXPECT_FALSE(s2.data_equal(s1));
 
     MutableByteSpan s3 = s2;
-    NL_TEST_ASSERT(inSuite, s3.data() == arr);
-    NL_TEST_ASSERT(inSuite, s3.size() == 3);
-    NL_TEST_ASSERT(inSuite, s3.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, !s3.empty());
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s2));
+    EXPECT_EQ(s3.data(), arr);
+    EXPECT_EQ(s3.size(), 3u);
+    EXPECT_EQ(s3.data()[2], 3u);
+    EXPECT_FALSE(s3.empty());
+    EXPECT_TRUE(s3.data_equal(s2));
 
     uint8_t arr2[] = { 3, 2, 1 };
     MutableByteSpan s4(arr2);
-    NL_TEST_ASSERT(inSuite, !s4.data_equal(s2));
+    EXPECT_FALSE(s4.data_equal(s2));
 
     MutableByteSpan s5(arr2, 0);
-    NL_TEST_ASSERT(inSuite, s5.data() != nullptr);
-    NL_TEST_ASSERT(inSuite, !s5.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s5.data_equal(s0));
-    NL_TEST_ASSERT(inSuite, s0.data_equal(s5));
+    EXPECT_NE(s5.data(), nullptr);
+    EXPECT_FALSE(s5.data_equal(s4));
+    EXPECT_TRUE(s5.data_equal(s0));
+    EXPECT_TRUE(s0.data_equal(s5));
 
     MutableByteSpan s6(arr2);
     s6.reduce_size(2);
-    NL_TEST_ASSERT(inSuite, s6.size() == 2);
+    EXPECT_EQ(s6.size(), 2u);
     MutableByteSpan s7(arr2, 2);
-    NL_TEST_ASSERT(inSuite, s6.data_equal(s7));
-    NL_TEST_ASSERT(inSuite, s7.data_equal(s6));
+    EXPECT_TRUE(s6.data_equal(s7));
+    EXPECT_TRUE(s7.data_equal(s6));
 
     uint8_t arr3[] = { 1, 2, 3 };
     MutableByteSpan s8(arr3);
-    NL_TEST_ASSERT(inSuite, arr3[1] == 2);
+    EXPECT_EQ(arr3[1], 2u);
     s8.data()[1] = 3;
-    NL_TEST_ASSERT(inSuite, arr3[1] == 3);
+    EXPECT_EQ(arr3[1], 3u);
 
     // Not mutable span on purpose, to test conversion.
     ByteSpan s9 = s8;
-    NL_TEST_ASSERT(inSuite, s9.data_equal(s8));
-    NL_TEST_ASSERT(inSuite, s8.data_equal(s9));
+    EXPECT_TRUE(s9.data_equal(s8));
+    EXPECT_TRUE(s8.data_equal(s9));
 
     // Not mutable span on purpose.
     ByteSpan s10(s8);
-    NL_TEST_ASSERT(inSuite, s10.data_equal(s8));
-    NL_TEST_ASSERT(inSuite, s8.data_equal(s10));
+    EXPECT_TRUE(s10.data_equal(s8));
+    EXPECT_TRUE(s8.data_equal(s10));
 }
 
-static void TestFixedByteSpan(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestFixedByteSpan)
 {
     uint8_t arr[] = { 1, 2, 3 };
 
     FixedByteSpan<3> s0 = FixedByteSpan<3>();
-    NL_TEST_ASSERT(inSuite, s0.data() != nullptr);
-    NL_TEST_ASSERT(inSuite, s0.size() == 3);
-    NL_TEST_ASSERT(inSuite, s0.data_equal(s0));
-    NL_TEST_ASSERT(inSuite, s0[0] == 0);
-    NL_TEST_ASSERT(inSuite, s0[1] == 0);
-    NL_TEST_ASSERT(inSuite, s0[2] == 0);
+    EXPECT_NE(s0.data(), nullptr);
+    EXPECT_EQ(s0.size(), 3u);
+    EXPECT_TRUE(s0.data_equal(s0));
+    EXPECT_EQ(s0[0], 0u);
+    EXPECT_EQ(s0[1], 0u);
+    EXPECT_EQ(s0[2], 0u);
 
     FixedByteSpan<2> s1(arr);
-    NL_TEST_ASSERT(inSuite, s1.data() == arr);
-    NL_TEST_ASSERT(inSuite, s1.size() == 2);
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s1));
+    EXPECT_EQ(s1.data(), arr);
+    EXPECT_EQ(s1.size(), 2u);
+    EXPECT_TRUE(s1.data_equal(s1));
 
     FixedByteSpan<3> s2(arr);
-    NL_TEST_ASSERT(inSuite, s2.data() == arr);
-    NL_TEST_ASSERT(inSuite, s2.size() == 3);
-    NL_TEST_ASSERT(inSuite, s2.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s2));
-    NL_TEST_ASSERT(inSuite, s2.front() == 1);
-    NL_TEST_ASSERT(inSuite, s2.back() == 3);
-    NL_TEST_ASSERT(inSuite, s2[0] == 1);
-    NL_TEST_ASSERT(inSuite, s2[1] == 2);
-    NL_TEST_ASSERT(inSuite, s2[2] == 3);
+    EXPECT_EQ(s2.data(), arr);
+    EXPECT_EQ(s2.size(), 3u);
+    EXPECT_EQ(s2.data()[2], 3u);
+    EXPECT_TRUE(s2.data_equal(s2));
+    EXPECT_EQ(s2.front(), 1u);
+    EXPECT_EQ(s2.back(), 3u);
+    EXPECT_EQ(s2[0], 1u);
+    EXPECT_EQ(s2[1], 2u);
+    EXPECT_EQ(s2[2], 3u);
 
     FixedByteSpan<3> s3 = s2;
-    NL_TEST_ASSERT(inSuite, s3.data() == arr);
-    NL_TEST_ASSERT(inSuite, s3.size() == 3);
-    NL_TEST_ASSERT(inSuite, s3.data()[2] == 3);
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s2));
+    EXPECT_EQ(s3.data(), arr);
+    EXPECT_EQ(s3.size(), 3u);
+    EXPECT_EQ(s3.data()[2], 3u);
+    EXPECT_TRUE(s3.data_equal(s2));
 
     uint8_t arr2[] = { 3, 2, 1 };
     FixedSpan<uint8_t, 3> s4(arr2);
-    NL_TEST_ASSERT(inSuite, !s4.data_equal(s2));
+    EXPECT_FALSE(s4.data_equal(s2));
 
     size_t idx = 0;
     for (auto & entry : s4)
     {
-        NL_TEST_ASSERT(inSuite, entry == arr2[idx++]);
+        EXPECT_EQ(entry, arr2[idx++]);
     }
-    NL_TEST_ASSERT(inSuite, idx == 3);
+    EXPECT_EQ(idx, 3u);
 
     FixedByteSpan<3> s5(arr2);
-    NL_TEST_ASSERT(inSuite, s5.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s5));
+    EXPECT_TRUE(s5.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s5));
 
     FixedByteSpan<2> s6(s4);
     idx = 0;
     for (auto & entry : s6)
     {
-        NL_TEST_ASSERT(inSuite, entry == arr2[idx++]);
+        EXPECT_EQ(entry, arr2[idx++]);
     }
-    NL_TEST_ASSERT(inSuite, idx == 2);
+    EXPECT_EQ(idx, 2u);
 
     // Not fixed, to test conversion.
     ByteSpan s7(s4);
-    NL_TEST_ASSERT(inSuite, s7.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s7));
+    EXPECT_TRUE(s7.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s7));
 
     MutableByteSpan s8(s4);
-    NL_TEST_ASSERT(inSuite, s8.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s8));
+    EXPECT_TRUE(s8.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s8));
 }
 
-static void TestSpanOfPointers(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestSpanOfPointers)
 {
     uint8_t x        = 5;
     uint8_t * ptrs[] = { &x, &x };
     Span<uint8_t *> s1(ptrs);
     Span<uint8_t * const> s2(s1);
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s2));
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s1));
+    EXPECT_TRUE(s1.data_equal(s2));
+    EXPECT_TRUE(s2.data_equal(s1));
 
     FixedSpan<uint8_t *, 2> s3(ptrs);
     FixedSpan<uint8_t * const, 2> s4(s3);
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s3));
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s1));
+    EXPECT_TRUE(s1.data_equal(s3));
+    EXPECT_TRUE(s3.data_equal(s1));
 
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s3));
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s2));
+    EXPECT_TRUE(s2.data_equal(s3));
+    EXPECT_TRUE(s3.data_equal(s2));
 
-    NL_TEST_ASSERT(inSuite, s1.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s1));
+    EXPECT_TRUE(s1.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s1));
 
-    NL_TEST_ASSERT(inSuite, s2.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s2));
+    EXPECT_TRUE(s2.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s2));
 
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s4));
-    NL_TEST_ASSERT(inSuite, s4.data_equal(s3));
+    EXPECT_TRUE(s3.data_equal(s4));
+    EXPECT_TRUE(s4.data_equal(s3));
 
     Span<uint8_t *> s5(s3);
-    NL_TEST_ASSERT(inSuite, s5.data_equal(s3));
-    NL_TEST_ASSERT(inSuite, s3.data_equal(s5));
+    EXPECT_TRUE(s5.data_equal(s3));
+    EXPECT_TRUE(s3.data_equal(s5));
 }
 
-static void TestSubSpan(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestSubSpan)
 {
     uint8_t array[16];
     ByteSpan span(array);
 
-    NL_TEST_ASSERT(inSuite, span.data() == &array[0]);
-    NL_TEST_ASSERT(inSuite, span.size() == 16);
+    EXPECT_EQ(span.data(), &array[0]);
+    EXPECT_EQ(span.size(), 16u);
 
     ByteSpan subspan = span.SubSpan(1, 14);
-    NL_TEST_ASSERT(inSuite, subspan.data() == &array[1]);
-    NL_TEST_ASSERT(inSuite, subspan.size() == 14);
+    EXPECT_EQ(subspan.data(), &array[1]);
+    EXPECT_EQ(subspan.size(), 14u);
 
     subspan = span.SubSpan(1, 0);
-    NL_TEST_ASSERT(inSuite, subspan.size() == 0);
+    EXPECT_EQ(subspan.size(), 0u);
 
     subspan = span.SubSpan(10);
-    NL_TEST_ASSERT(inSuite, subspan.data() == &array[10]);
-    NL_TEST_ASSERT(inSuite, subspan.size() == 6);
+    EXPECT_EQ(subspan.data(), &array[10]);
+    EXPECT_EQ(subspan.size(), 6u);
 
     subspan = span.SubSpan(16);
-    NL_TEST_ASSERT(inSuite, subspan.size() == 0);
+    EXPECT_EQ(subspan.size(), 0u);
 }
 
-static void TestFromZclString(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestFromZclString)
 {
     // Purposefully larger size than data.
     constexpr uint8_t array[16] = { 3, 0x41, 0x63, 0x45 };
@@ -279,26 +278,26 @@
     static constexpr char str[] = "AcE";
 
     ByteSpan s1 = ByteSpan::fromZclString(array);
-    NL_TEST_ASSERT(inSuite, s1.data_equal(ByteSpan(&array[1], 3)));
+    EXPECT_TRUE(s1.data_equal(ByteSpan(&array[1], 3u)));
 
     CharSpan s2 = CharSpan::fromZclString(array);
-    NL_TEST_ASSERT(inSuite, s2.data_equal(CharSpan(str, 3)));
+    EXPECT_TRUE(s2.data_equal(CharSpan(str, 3)));
 }
 
-static void TestFromCharString(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestFromCharString)
 {
     static constexpr char str[] = "AcE";
 
     CharSpan s1 = CharSpan::fromCharString(str);
-    NL_TEST_ASSERT(inSuite, s1.data_equal(CharSpan(str, 3)));
+    EXPECT_TRUE(s1.data_equal(CharSpan(str, 3)));
 }
 
-static void TestLiteral(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestLiteral)
 {
     constexpr CharSpan literal = "HI!"_span;
-    NL_TEST_ASSERT(inSuite, literal.size() == 3);
-    NL_TEST_ASSERT(inSuite, literal.data_equal(CharSpan::fromCharString("HI!")));
-    NL_TEST_ASSERT(inSuite, ""_span.size() == 0);
+    EXPECT_EQ(literal.size(), 3u);
+    EXPECT_TRUE(literal.data_equal(CharSpan::fromCharString("HI!")));
+    EXPECT_EQ(""_span.size(), 0u);
 
     // These should be compile errors -- if they were allowed they would produce
     // a CharSpan that includes the trailing '\0' byte in the value.
@@ -306,7 +305,7 @@
     // constexpr CharSpan disallowed2{ "abcd" };
 }
 
-static void TestConversionConstructors(nlTestSuite * inSuite, void * inContext)
+TEST(TestSpan, TestConversionConstructors)
 {
     struct Foo
     {
@@ -345,43 +344,15 @@
     ([](FixedSpan<const Foo, 3> f) {})(constArray);
     ([](Span<const Foo> f) {})(constArray);
 
-    NL_TEST_ASSERT(inSuite, span10.data_equal(span10));
-    NL_TEST_ASSERT(inSuite, span10.data_equal(span9));
-    NL_TEST_ASSERT(inSuite, span10.data_equal(array));
-    NL_TEST_ASSERT(inSuite, span10.data_equal(constArray));
-    NL_TEST_ASSERT(inSuite, span9.data_equal(span9));
-    NL_TEST_ASSERT(inSuite, span9.data_equal(span10));
-    NL_TEST_ASSERT(inSuite, span9.data_equal(array));
-    NL_TEST_ASSERT(inSuite, span9.data_equal(constArray));
+    EXPECT_TRUE(span10.data_equal(span10));
+    EXPECT_TRUE(span10.data_equal(span9));
+    EXPECT_TRUE(span10.data_equal(array));
+    EXPECT_TRUE(span10.data_equal(constArray));
+    EXPECT_TRUE(span9.data_equal(span9));
+    EXPECT_TRUE(span9.data_equal(span10));
+    EXPECT_TRUE(span9.data_equal(array));
+    EXPECT_TRUE(span9.data_equal(constArray));
 
     // The following should not compile
     // Span<const Foo> error1 = std::array<Foo, 3>(); // Span would point into a temporary value
 }
-
-#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(TestByteSpan),
-    NL_TEST_DEF_FN(TestMutableByteSpan),
-    NL_TEST_DEF_FN(TestFixedByteSpan),
-    NL_TEST_DEF_FN(TestSpanOfPointers),
-    NL_TEST_DEF_FN(TestSubSpan),
-    NL_TEST_DEF_FN(TestFromZclString),
-    NL_TEST_DEF_FN(TestFromCharString),
-    NL_TEST_DEF_FN(TestLiteral),
-    NL_TEST_DEF_FN(TestConversionConstructors),
-    NL_TEST_SENTINEL(),
-};
-
-int TestSpan()
-{
-    nlTestSuite theSuite = { "CHIP Span tests", &sTests[0], nullptr, nullptr };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestSpan)
diff --git a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp
index 809c2e4..b51afc1 100644
--- a/src/lib/support/tests/TestStaticSupportSmartPtr.cpp
+++ b/src/lib/support/tests/TestStaticSupportSmartPtr.cpp
@@ -15,14 +15,13 @@
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
-#include <lib/support/static_support_smart_ptr.h>
-
-#include <lib/support/Scoped.h>
-#include <lib/support/UnitTestRegistration.h>
 
 #include <cstring>
 
-#include <nlunit-test.h>
+#include <gtest/gtest.h>
+
+#include <lib/support/Scoped.h>
+#include <lib/support/static_support_smart_ptr.h>
 
 using namespace chip;
 namespace {
@@ -50,42 +49,42 @@
 
 namespace {
 
-void TestCheckedGlobalInstanceReference(nlTestSuite * inSuite, void * inContext)
+TEST(TestStaticSupportSmartPtr, TestCheckedGlobalInstanceReference)
 {
     CheckedGlobalInstanceReference<TestClass> ref(&gTestClass);
 
     // We expect that sizes of global references is minimal
-    NL_TEST_ASSERT(inSuite, sizeof(ref) == 1);
+    EXPECT_EQ(sizeof(ref), 1u);
 
-    NL_TEST_ASSERT(inSuite, ref->num == 123);
-    NL_TEST_ASSERT(inSuite, strcmp(ref->str, "abc") == 0);
+    EXPECT_EQ(ref->num, 123);
+    EXPECT_STREQ(ref->str, "abc");
 
     {
         ScopedChange<int> change1(gTestClass.num, 100);
         ScopedChange<const char *> change2(ref->str, "xyz");
 
-        NL_TEST_ASSERT(inSuite, ref->num == 100);
-        NL_TEST_ASSERT(inSuite, strcmp(gTestClass.str, "xyz") == 0);
+        EXPECT_EQ(ref->num, 100);
+        EXPECT_STREQ(gTestClass.str, "xyz");
     }
 
     CheckedGlobalInstanceReference<TestClass> ref2(&gTestClass);
 
-    NL_TEST_ASSERT(inSuite, ref->num == ref2->num);
-    NL_TEST_ASSERT(inSuite, strcmp(ref->str, ref2->str) == 0);
+    EXPECT_EQ(ref->num, ref2->num);
+    EXPECT_STREQ(ref->str, ref2->str);
 
     {
         ScopedChange<int> change1(gTestClass.num, 321);
         ScopedChange<const char *> change2(ref->str, "test");
 
-        NL_TEST_ASSERT(inSuite, ref->num == ref2->num);
-        NL_TEST_ASSERT(inSuite, strcmp(ref->str, ref2->str) == 0);
+        EXPECT_EQ(ref->num, ref2->num);
+        EXPECT_STREQ(ref->str, ref2->str);
 
-        NL_TEST_ASSERT(inSuite, ref2->num == 321);
-        NL_TEST_ASSERT(inSuite, strcmp(ref2->str, "test") == 0);
+        EXPECT_EQ(ref2->num, 321);
+        EXPECT_STREQ(ref2->str, "test");
     }
 }
 
-void TestSimpleInstanceReference(nlTestSuite * inSuite, void * inContext)
+TEST(TestStaticSupportSmartPtr, TestSimpleInstanceReference)
 {
     TestClass a("abc", 123);
     TestClass b("xyz", 100);
@@ -94,34 +93,16 @@
     SimpleInstanceReference ref_b(&b);
 
     // overhead of simple references should be a simple pointer
-    NL_TEST_ASSERT(inSuite, sizeof(ref_a) <= sizeof(void *));
+    EXPECT_LE(sizeof(ref_a), sizeof(void *));
 
-    NL_TEST_ASSERT(inSuite, ref_a->num == 123);
-    NL_TEST_ASSERT(inSuite, ref_b->num == 100);
+    EXPECT_EQ(ref_a->num, 123);
+    EXPECT_EQ(ref_b->num, 100);
 
     ref_a->num = 99;
     b.num      = 30;
 
-    NL_TEST_ASSERT(inSuite, a.num == 99);
-    NL_TEST_ASSERT(inSuite, ref_b->num == 30);
+    EXPECT_EQ(a.num, 99);
+    EXPECT_EQ(ref_b->num, 30);
 }
 
-#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn)
-const nlTest sTests[] = {
-    NL_TEST_DEF_FN(TestCheckedGlobalInstanceReference),
-    NL_TEST_DEF_FN(TestSimpleInstanceReference),
-    NL_TEST_SENTINEL(),
-};
-
 } // namespace
-
-int TestStaticSupportSmartPtr()
-{
-    nlTestSuite theSuite = { "CHIP Static support smart pointers", &sTests[0], nullptr, nullptr };
-
-    // Run test suite against one context.
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestStaticSupportSmartPtr)
diff --git a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp
index 05ef383..a53f43c 100644
--- a/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp
+++ b/src/lib/support/tests/TestTestPersistentStorageDelegate.cpp
@@ -18,14 +18,13 @@
 
 #include <lib/core/CHIPError.h>
 #include <lib/support/TestPersistentStorageDelegate.h>
-#include <lib/support/UnitTestRegistration.h>
 
 #include <array>
 #include <cstring>
 #include <set>
 #include <string>
 
-#include <nlunit-test.h>
+#include <gtest/gtest.h>
 
 using namespace chip;
 
@@ -50,7 +49,7 @@
     return true;
 }
 
-void TestBasicApi(nlTestSuite * inSuite, void * inContext)
+TEST(TestTestPersistentStorageDelegate, TestBasicApi)
 {
     TestPersistentStorageDelegate storage;
 
@@ -63,49 +62,49 @@
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(size, actualSizeOfBuf);
 
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 0);
+    EXPECT_EQ(storage.GetNumKeys(), 0u);
 
     err = storage.SyncDeleteKeyValue("roboto");
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
 
     // Add basic key, read it back, erase it
     static const char kStringValue1[] = "abcd";
     err = storage.SyncSetKeyValue("roboto", kStringValue1, static_cast<uint16_t>(strlen(kStringValue1)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue1));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kStringValue1));
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));
 
     err = storage.SyncDeleteKeyValue("roboto");
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(size, actualSizeOfBuf);
 
     // Validate adding 2 different keys
     static const char kStringValue2[] = "0123abcd";
     static const char kStringValue3[] = "cdef89";
     err = storage.SyncSetKeyValue("key2", kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     err = storage.SyncSetKeyValue("key3", kStringValue3, static_cast<uint16_t>(strlen(kStringValue3)));
-    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key3"));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_TRUE(storage.SyncDoesKeyExist("key3"));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 2);
+    EXPECT_EQ(storage.GetNumKeys(), 2u);
     auto keys = storage.GetKeys();
     std::array<std::string, 2> kExpectedKeys{ "key2", "key3" };
-    NL_TEST_ASSERT(inSuite, SetMatches(keys, kExpectedKeys) == true);
+    EXPECT_EQ(SetMatches(keys, kExpectedKeys), true);
 
     // Read them back
 
@@ -115,164 +114,164 @@
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kStringValue2));
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
     // Make sure that there was no buffer overflow during SyncGetKeyValue
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
+    EXPECT_EQ(0, memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
 
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("key3", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue3));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue3, strlen(kStringValue3)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kStringValue3));
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue3, strlen(kStringValue3)));
     // Make sure that there was no buffer overflow during SyncGetKeyValue
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
+    EXPECT_EQ(0, memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
 
     // Read providing too small a buffer. Data read up to `size` and nothing more.
     memset(&buf[0], 0, sizeof(buf));
     size                               = static_cast<uint16_t>(strlen(kStringValue2) - 1);
     uint16_t sizeBeforeGetKeyValueCall = size;
     err                                = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
-    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, size));
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_EQ(size, sizeBeforeGetKeyValueCall);
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue2, size));
     // Make sure that there was no buffer overflow during SyncGetKeyValue
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
+    EXPECT_EQ(0, memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
 
     // Read in too small a buffer, which is nullptr and size == 0: check CHIP_ERROR_BUFFER_TOO_SMALL is given.
     memset(&buf[0], 0, sizeof(buf));
     size                      = 0;
     sizeBeforeGetKeyValueCall = size;
     err                       = storage.SyncGetKeyValue("key2", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
-    NL_TEST_ASSERT(inSuite, size != strlen(kStringValue2));
-    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
+    EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);
+    EXPECT_NE(size, strlen(kStringValue2));
+    EXPECT_EQ(size, sizeBeforeGetKeyValueCall);
     // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
     // nullptr is provided.
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
 
     // Read in too small a buffer, which is nullptr and size != 0: error
     size                      = static_cast<uint16_t>(strlen(kStringValue2) - 1);
     sizeBeforeGetKeyValueCall = size;
     err                       = storage.SyncGetKeyValue("key2", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
-    NL_TEST_ASSERT(inSuite, size == sizeBeforeGetKeyValueCall);
+    EXPECT_EQ(err, CHIP_ERROR_INVALID_ARGUMENT);
+    EXPECT_EQ(size, sizeBeforeGetKeyValueCall);
     // Just making sure that implementation doesn't hold onto reference of previous destination buffer when
     // nullptr is provided.
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
 
     // When key not found, size is not touched.
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(actualSizeOfBuf, size);
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
 
     size = 0;
     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, 0 == size);
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(0, size);
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], sizeof(buf)));
 
     // Even when key not found, cannot pass nullptr with size != 0.
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("keyDOES_NOT_EXIST", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
-    NL_TEST_ASSERT(inSuite, actualSizeOfBuf == size);
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));
+    EXPECT_EQ(err, CHIP_ERROR_INVALID_ARGUMENT);
+    EXPECT_EQ(actualSizeOfBuf, size);
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], size));
 
     // Attempt an empty key write with either nullptr or zero size works
     err = storage.SyncSetKeyValue("key2", kStringValue2, 0);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_TRUE(storage.SyncDoesKeyExist("key2"));
 
     size = 0;
     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == 0);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, 0u);
 
     size = 0;
     err  = storage.SyncGetKeyValue("key2", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == 0);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, 0u);
 
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == 0);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, 0u);
 
     err = storage.SyncSetKeyValue("key2", nullptr, 0);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist("key2"));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_TRUE(storage.SyncDoesKeyExist("key2"));
 
     size = 0;
     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == 0);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, 0u);
 
     // Failure to set key if buffer is nullptr and size != 0
     size = 10;
     err  = storage.SyncSetKeyValue("key4", nullptr, size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
-    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key4"));
+    EXPECT_EQ(err, CHIP_ERROR_INVALID_ARGUMENT);
+    EXPECT_FALSE(storage.SyncDoesKeyExist("key4"));
 
     // Can delete empty key
     err = storage.SyncDeleteKeyValue("key2");
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
-    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist("key2"));
+    EXPECT_FALSE(storage.SyncDoesKeyExist("key2"));
 
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue("key2", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, size == actualSizeOfBuf);
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], &all_zeroes[0], size));
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(size, actualSizeOfBuf);
+    EXPECT_EQ(0, memcmp(&buf[0], &all_zeroes[0], size));
 
     // Using key and value with base64 symbols
     static const char kBase64SymbolsKey[]   = "key+/=";
     static const char kBase64SymbolValues[] = "value+/=";
     err = storage.SyncSetKeyValue(kBase64SymbolsKey, kBase64SymbolValues, static_cast<uint16_t>(strlen(kBase64SymbolValues)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue(kBase64SymbolsKey, &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kBase64SymbolValues));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kBase64SymbolValues, strlen(kBase64SymbolValues)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kBase64SymbolValues));
+    EXPECT_EQ(0, memcmp(&buf[0], kBase64SymbolValues, strlen(kBase64SymbolValues)));
     // Make sure that there was no buffer overflow during SyncGetKeyValue
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
+    EXPECT_EQ(0, memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
 
     err = storage.SyncDeleteKeyValue(kBase64SymbolsKey);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(kBase64SymbolsKey));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_FALSE(storage.SyncDoesKeyExist(kBase64SymbolsKey));
 
     // Try using key that is a size that equals PersistentStorageDelegate::kKeyLengthMax
     char longKeyString[PersistentStorageDelegate::kKeyLengthMax + 1];
     memset(&longKeyString, 'X', PersistentStorageDelegate::kKeyLengthMax);
     longKeyString[sizeof(longKeyString) - 1] = '\0';
     // strlen() is not compile time so we just have this runtime assert that should aways pass as a sanity check.
-    NL_TEST_ASSERT(inSuite, strlen(longKeyString) == PersistentStorageDelegate::kKeyLengthMax);
+    EXPECT_EQ(strlen(longKeyString), PersistentStorageDelegate::kKeyLengthMax);
 
     err = storage.SyncSetKeyValue(longKeyString, kStringValue2, static_cast<uint16_t>(strlen(kStringValue2)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     memset(&buf[0], 0, sizeof(buf));
     size = actualSizeOfBuf;
     err  = storage.SyncGetKeyValue(longKeyString, &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue2));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kStringValue2));
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue2, strlen(kStringValue2)));
     // Make sure that there was no buffer overflow during SyncGetKeyValue
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
+    EXPECT_EQ(0, memcmp(&buf[size], &all_zeroes[0], sizeof(buf) - size));
 
-    NL_TEST_ASSERT(inSuite, storage.SyncDoesKeyExist(longKeyString));
+    EXPECT_TRUE(storage.SyncDoesKeyExist(longKeyString));
 
     err = storage.SyncDeleteKeyValue(longKeyString);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, !storage.SyncDoesKeyExist(longKeyString));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_FALSE(storage.SyncDoesKeyExist(longKeyString));
 
     constexpr size_t kMaxCHIPCertLength = 400; // From credentials/CHIPCert.h and spec
     uint8_t largeBuffer[kMaxCHIPCertLength];
@@ -281,26 +280,26 @@
     memcpy(largeBufferForCheck, largeBuffer, sizeof(largeBuffer));
 
     err = storage.SyncSetKeyValue(longKeyString, largeBuffer, static_cast<uint16_t>(sizeof(largeBuffer)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     memset(&largeBuffer, 0, sizeof(largeBuffer));
     size = static_cast<uint16_t>(sizeof(largeBuffer));
     err  = storage.SyncGetKeyValue(longKeyString, &largeBuffer[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == static_cast<uint16_t>(sizeof(largeBuffer)));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&largeBuffer, largeBufferForCheck, sizeof(largeBuffer)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, static_cast<uint16_t>(sizeof(largeBuffer)));
+    EXPECT_EQ(0, memcmp(&largeBuffer, largeBufferForCheck, sizeof(largeBuffer)));
 
     err = storage.SyncDeleteKeyValue(longKeyString);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
 
     // Cleaning up
     err = storage.SyncDeleteKeyValue("key3");
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 0);
+    EXPECT_EQ(storage.GetNumKeys(), 0u);
 }
 
 // ClearStorage is not a PersistentStorageDelegate base class method, it only
 // appears in the TestPersistentStorageDelegate.
-void TestClearStorage(nlTestSuite * inSuite, void * inContext)
+TEST(TestTestPersistentStorageDelegate, TestClearStorage)
 {
     TestPersistentStorageDelegate storage;
 
@@ -308,51 +307,37 @@
     uint16_t size = sizeof(buf);
 
     // Key not there
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 0);
+    EXPECT_EQ(storage.GetNumKeys(), 0u);
 
     CHIP_ERROR err;
     memset(&buf[0], 0, sizeof(buf));
     size = sizeof(buf);
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, size == sizeof(buf));
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(size, sizeof(buf));
 
     // Add basic key, read it back
     static const char kStringValue1[] = "abcd";
     err = storage.SyncSetKeyValue("roboto", kStringValue1, static_cast<uint16_t>(strlen(kStringValue1)));
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 1);
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(storage.GetNumKeys(), 1u);
 
     memset(&buf[0], 0, sizeof(buf));
     size = sizeof(buf);
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
-    NL_TEST_ASSERT(inSuite, size == strlen(kStringValue1));
-    NL_TEST_ASSERT(inSuite, 0 == memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));
+    EXPECT_EQ(err, CHIP_NO_ERROR);
+    EXPECT_EQ(size, strlen(kStringValue1));
+    EXPECT_EQ(0, memcmp(&buf[0], kStringValue1, strlen(kStringValue1)));
 
     // Clear storage, make sure it's gone
     storage.ClearStorage();
 
-    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == 0);
+    EXPECT_EQ(storage.GetNumKeys(), 0u);
     memset(&buf[0], 0, sizeof(buf));
     size = sizeof(buf);
     err  = storage.SyncGetKeyValue("roboto", &buf[0], size);
-    NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
-    NL_TEST_ASSERT(inSuite, size == sizeof(buf));
+    EXPECT_EQ(err, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
+    EXPECT_EQ(size, sizeof(buf));
 }
 
-const nlTest sTests[] = { NL_TEST_DEF("Test basic API", TestBasicApi),
-                          NL_TEST_DEF("Test ClearStorage method of TestPersistentStorageDelegate", TestClearStorage),
-                          NL_TEST_SENTINEL() };
-
 } // namespace
-
-int TestTestPersistentStorageDelegate()
-{
-    nlTestSuite theSuite = { "TestPersistentStorageDelegate tests", &sTests[0], nullptr, nullptr };
-
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestTestPersistentStorageDelegate);
diff --git a/src/lib/support/tests/TestUtf8.cpp b/src/lib/support/tests/TestUtf8.cpp
index a18ed74..dd07880 100644
--- a/src/lib/support/tests/TestUtf8.cpp
+++ b/src/lib/support/tests/TestUtf8.cpp
@@ -17,12 +17,10 @@
  *    limitations under the License.
  */
 
-#include <functional>
-
-#include <lib/support/UnitTestRegistration.h>
 #include <lib/support/utf8.h>
 
-#include <nlunit-test.h>
+#include <functional>
+#include <gtest/gtest.h>
 
 namespace {
 
@@ -33,7 +31,7 @@
     {                                                                                                                              \
         uint8_t _buff[] = { __VA_ARGS__ };                                                                                         \
         CharSpan _span(reinterpret_cast<const char *>(_buff), sizeof(_buff));                                                      \
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(_span));                                                                             \
+        EXPECT_TRUE(Utf8::IsValid(_span));                                                                                         \
     } while (0)
 
 #define TEST_INVALID_BYTES(...)                                                                                                    \
@@ -41,42 +39,42 @@
     {                                                                                                                              \
         uint8_t _buff[] = { __VA_ARGS__ };                                                                                         \
         CharSpan _span(reinterpret_cast<const char *>(_buff), sizeof(_buff));                                                      \
-        NL_TEST_ASSERT(inSuite, !Utf8::IsValid(_span));                                                                            \
+        EXPECT_FALSE(Utf8::IsValid(_span));                                                                                        \
     } while (0)
 
-void TestValidStrings(nlTestSuite * inSuite, void * inContext)
+TEST(TestUtf8, TestValidStrings)
 {
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan())); // empty span ok
+    EXPECT_TRUE(Utf8::IsValid(CharSpan())); // empty span ok
 
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("abc")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("abc")));
 
     // Various tests from https://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html
 
     // Generic UTF8
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("κόσμε")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("κόσμε")));
 
     // First possible sequence of a certain length
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("€")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("ࠀ")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("𐀀")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("�����")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("������")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("€")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("ࠀ")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("𐀀")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("�����")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("������")));
 
     // Last possible sequence of a certain length
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("߿")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("￿")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("����")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("�����")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("������")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("߿")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("￿")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("����")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("�����")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("������")));
 
     // Other boundary conditions
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("퟿")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("�")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("􏿿")));
-    NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan::fromCharString("����")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("퟿")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("�")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("􏿿")));
+    EXPECT_TRUE(Utf8::IsValid(CharSpan::fromCharString("����")));
 
     // NOTE: UTF8 allows embeded NULLs
     //       even though strings like that are probably not ideal for handling
@@ -84,17 +82,17 @@
     //       completely if the spec is updated as such
     {
         char zero[16] = { 0 };
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 0)));
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 1)));
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 2)));
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 3)));
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 4)));
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(zero, 16)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 0)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 1)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 2)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 3)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 4)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(zero, 16)));
     }
 
     {
         char insideZero[] = "test\0zero";
-        NL_TEST_ASSERT(inSuite, Utf8::IsValid(CharSpan(insideZero)));
+        EXPECT_TRUE(Utf8::IsValid(CharSpan(insideZero)));
     }
 
     // Test around forbidden 0xD800..0xDFFF UTF-16 surrogate pairs.
@@ -102,7 +100,7 @@
     TEST_VALID_BYTES(0b1110'1110, 0b10'000000, 0b10'000000);
 }
 
-void TestInvalidStrings(nlTestSuite * inSuite, void * inContext)
+TEST(TestUtf8, TestInvalidStrings)
 {
     // Overly long sequences
     TEST_INVALID_BYTES(0xc0, 0b10'111111);
@@ -169,22 +167,3 @@
 }
 
 } // namespace
-
-// clang-format off
-const nlTest sTests[] =
-{
-    NL_TEST_DEF("TestValidStrings", TestValidStrings),
-    NL_TEST_DEF("TestInvalidStrings", TestInvalidStrings),
-    NL_TEST_SENTINEL()
-};
-// clang-format on
-
-int TestUtf8()
-{
-    nlTestSuite theSuite = { "UTF8 validator tests", &sTests[0], nullptr, nullptr };
-
-    nlTestRunner(&theSuite, nullptr);
-    return nlTestRunnerStats(&theSuite);
-}
-
-CHIP_REGISTER_TEST_SUITE(TestUtf8);