Updated the unit test documentation to reflect the transition to PW. (#33492)

* Revised unit testing documentation to refer to PW tests.

* Documentation update

* More doc updates

* More doc updates

* More doc updates

* More doc updates

* More doc updates

* More doc updates

* Updated documentation to reflect PW

* Fixed spelling error

* Replaced gtest.h include.

* Modified MessagingContext and its subclasses as well as AppContext to reflect PW migration.

* Undid last commit.

* Undid last commit.

* Undid last commit.

* Restyled by prettier-markdown

* Changed the includes to be consistent.

* Cleaned up example code comments

---------

Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/docs/guides/openiotsdk_unit_tests.md b/docs/guides/openiotsdk_unit_tests.md
index 7b9bba5..7560d4d 100644
--- a/docs/guides/openiotsdk_unit_tests.md
+++ b/docs/guides/openiotsdk_unit_tests.md
@@ -6,8 +6,8 @@
 sources are built as a static library that can be linked to the unit test
 application separately or as a monolithic test library. The common Matter test
 library collects all test cases and provides the engine based on
-[Nest Labs Unit Test](https://github.com/nestlabs/nlunit-test) to run them in
-the application.
+[Pigweed Unit Test](https://pigweed.dev/pw_unit_test) to run them in the
+application.
 
 The Open IoT SDK unit tests implementation are located in the
 `src/test_driver/openiotsdk/unit-tests` directory. This project builds a
@@ -27,6 +27,7 @@
 CoreTests
 CredentialsTest
 DataModelTests
+ICDServerTests
 InetLayerTests
 MdnsTests
 MessagingLayerTests
@@ -41,7 +42,6 @@
 SupportTests
 SystemLayerTests
 TestShell
-TransportLayerTests
 UserDirectedCommissioningTests
 ```
 
diff --git a/docs/testing/unit_testing.md b/docs/testing/unit_testing.md
index c539420..64046a4 100644
--- a/docs/testing/unit_testing.md
+++ b/docs/testing/unit_testing.md
@@ -11,85 +11,347 @@
     example applications.
     -   e.g. feature combinations not in example apps.
 
-## Unit testing in the SDK - nlUnitTest
+## Unit testing in the SDK using pw_unit_test
 
-The following example gives a small demonstration of how to use nlUnitTest to
-write a unit test
+This SDK uses Pigweed unit test (pw_unit_test), which is an implementation of
+GoogleTest. For more information see the
+[pw_unit_test documentation](https://pigweed.dev/pw_unit_test/) or the
+[GoogleTest documentation](https://google.github.io/googletest/).
+
+### Simple unit tests
+
+The following example demonstrates how to use pw_unit_test to write a simple
+unit test. Each test function is defined using `TEST(NameOfFunction)`. The set
+of test functions in a given source file is called a "suite".
 
 ```
-#include <lib/support/UnitTestContext.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
+#include <pw_unit_test/framework.h>
 
-class YourTestContext : public Test::AppContext {
-   ...
-};
+TEST(YourTestFunction1)
+{
+    // Do some test things here, then check the results using EXPECT_*
+    SomeTypeX foo;
+    foo.DoSomething();
+    EXPECT_EQ(foo.GetResultCount(), 7);
+    foo.DoSomethingElse();
+    EXPECT_EQ(foo.GetResultCount(), 5);
 
-
-static void TestName(nlTestSuite * apSuite, void * apContext) {
-    // If you register the test suite with a context, cast
-    // apContext as appropriate
-    YourTestContext * ctx = static_cast<YourTestContext *>(aContext);
-
-    // Do some test things here, then check the results using NL_TEST_ASSERT
-    NL_TEST_ASSERT(apSuite, <boolean condition>)
+    // If you want to abort the rest of the test upon failure, use ASSERT_*
+    SomeTypeY * ptr = foo.GetSomePointer();
+    ASSERT_NE(ptr, nullptr);
+    ptr->DoTheThing();  // Won't reach here if the ASSERT failed.
 }
 
-static const nlTest sTests[] =
+TEST(YourTestFunction2)
 {
-    NL_TEST_DEF("TestName", TestName), // Can have multiple of these
-    NL_TEST_SENTINEL() // If you forget this, you’re going to have a bad time
-};
-
-nlTestSuite sSuite =
-{
-    "TheNameOfYourTestSuite", // Test name
-    &sTests[0], // The list of tests to run
-    TestContext::Initialize, // Runs before all the tests (can be nullptr)
-    TestContext::Finalize // Runs after all the tests (can be nullptr)
-};
-
-int YourTestSuiteName()
-{
-    return chip::ExecuteTestsWithContext<YourTestContext>(&sSuite); // or “without”
+    // Do some test things here, then check the results using EXPECT_*
+    SomeTypeZ foo;
+    foo.DoSomething();
+    EXPECT_EQ(foo.GetResultCount(), 3);
 }
-
-CHIP_REGISTER_TEST_SUITE(YourTestSuiteName)
 ```
 
-Each test gets an nlTestSuite object (apSuite) that is passed into the test
-assertions, and a void\* context (apContext) that is yours to do with as you
-require.
-
-The apContext should be derived from
-[Test::AppContext](https://github.com/project-chip/connectedhomeip/blob/master/src/app/tests/AppTestContext.h)
-
 See
 [TestSpan.cpp](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/tests/TestSpan.cpp)
-for a great example of a good unit test.
+for an example of a simple unit test.
 
-## nlUnitTest - Compiling and running
+In the above example there are no fixtures or setup/teardown behavior.
 
--   Add to src/some_directory/tests/BUILD.gn
-    -   chip_test_suite_using_nltest("tests")
-        -   See for example
-            [src/lib/support/tests/BUILD.gn](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/tests/BUILD.gn)
--   [./gn_build.sh](https://github.com/project-chip/connectedhomeip/blob/master/gn_build.sh)
-    will build and run all tests
+### Test fixtures and setup/teardown behavior
+
+If your tests need fixtures or some kind of setup/teardown you will need to
+define a test context that derives from `::testing::Test`. Each of your test
+functions will be defined with `TEST_F(NameOfTestContext, NameOfFunction)`. The
+following example demonstrates how to use pw_unit_test to write a unit test that
+uses fixtures and setup/teardown behavior.
+
+```
+#include <pw_unit_test/framework.h>
+
+class YourTestContext : public ::testing::Test
+{
+public:
+    // Performs shared setup for all tests in the test suite.  Run once for the whole suite.
+    static void SetUpTestSuite()
+    {
+        // Your per-suite setup goes here:
+        sPerSuiteFixture.Init();
+        ASSERT_TRUE(sPerSuiteFixture.WorkingGreat());
+    }
+
+    // Performs shared teardown for all tests in the test suite.  Run once for the whole suite.
+    static void TearDownTestSuite()
+    {
+        // Your per-suite teardown goes here:
+        sPerSuiteFixture.Shutdown();
+    }
+
+protected:
+    // Performs setup for each test in the suite.  Run once for each test function.
+    void SetUp()
+    {
+        // Your per-test setup goes here:
+        mPerTestFixture.Init();
+        ASSERT_TRUE(mPerTestFixture.WorkingGreat());
+    }
+
+    // Performs teardown for each test in the suite.  Run once for each test function.
+    void TearDown()
+    {
+        // Your per-test teardown goes here:
+        mPerTestFixture.Shutdown();
+    }
+
+private:
+    // Your per-suite and per-test fixtures are declared here:
+    static SomeTypeA sPerSuiteFixture;
+    SomeTypeB mPerTestFixture;
+};
+// Your per-suite fixtures are defined here:
+SomeTypeA YourTestContext::sPerSuiteFixture;
+
+TEST_F(YourTestContext, YourTestFunction1)
+{
+    // Do some test things here, then check the results using EXPECT_*
+    mPerTestFixture.DoSomething();
+    EXPECT_EQ(mPerTestFixture.GetResultCount(), 7);
+    sPerSuiteFixture.DoSomething();
+    EXPECT_EQ(sPerSuiteFixture.GetResultCount(), 5);
+
+    // If you want to abort the rest of the test upon failure, use ASSERT_*
+    SomeTypeC * ptr = mPerTestFixture.GetSomePointer();
+    ASSERT_NE(ptr, nullptr);
+    ptr->DoTheThing();  // Won't reach here if the ASSERT failed.
+}
+
+TEST_F(YourTestContext, YourTestFunction2)
+{
+    // Do some test things here, then check the results using EXPECT_*
+    mPerTestFixture.DoSomethingElse();
+    EXPECT_EQ(mPerTestFixture.GetResultCount(), 9);
+}
+```
+
+### A loopback messaging context for convenience
+
+If you need messaging, there is a convenience class
+[Test::AppContext](https://github.com/project-chip/connectedhomeip/blob/master/src/app/tests/AppTestContext.h)
+that you can derive your test context from. It provides a network layer and a
+system layer and two secure sessions connected with each other. The following
+example demonstrates this.
+
+```
+#include <app/tests/AppTestContext.h>
+
+class YourTestContext : public Test::AppContext
+{
+public:
+    // Performs shared setup for all tests in the test suite.  Run once for the whole suite.
+    static void SetUpTestSuite()
+    {
+        AppContext::SetUpTestSuite();  // Call parent.
+        VerifyOrReturn(!HasFailure());  // Stop if parent had a failure.
+
+        // Your per-suite setup goes here:
+        sPerSuiteFixture.Init();
+        ASSERT_TRUE(sPerSuiteFixture.WorkingGreat());
+    }
+
+    // Performs shared teardown for all tests in the test suite.  Run once for the whole suite.
+    static void TearDownTestSuite()
+    {
+        // Your per-suite teardown goes here:
+        sPerSuiteFixture.Shutdown();
+
+        AppContext::TearDownTestSuite();  // Call parent.
+    }
+
+protected:
+    // Performs setup for each test in the suite.  Run once for each test function.
+    void SetUp()
+    {
+        AppContext::SetUp();  // Call parent.
+        VerifyOrReturn(!HasFailure());  // Stop if parent had a failure.
+
+        // Your per-test setup goes here:
+        mPerTestFixture.Init();
+        ASSERT_TRUE(mPerTestFixture.WorkingGreat());
+    }
+
+    // Performs teardown for each test in the suite.  Run once for each test function.
+    void TearDown()
+    {
+        // Your per-test teardown goes here:
+        mPerTestFixture.Shutdown();
+
+        chip::app::EventManagement::DestroyEventManagement();
+        AppContext::TearDown();  // Call parent.
+    }
+
+private:
+    // Your per-suite and per-test fixtures are declared here:
+    static SomeTypeA sPerSuiteFixture;
+    SomeTypeB mPerTestFixture;
+};
+// Your per-suite fixtures are defined here:
+SomeTypeA YourTestContext::sPerSuiteFixture;
+
+TEST_F(YourTestContext, YourTestFunction1)
+{
+    // Do some test things here, then check the results using EXPECT_*
+}
+
+TEST_F(YourTestContext, YourTestFunction2)
+{
+    // Do some test things here, then check the results using EXPECT_*
+}
+```
+
+You don't have to override all 4 functions `SetUpTestsuite`,
+`TearDownTestSuite`, `SetUp`, `TearDown`. If you don't need any custom behavior
+in one of those functions just omit it.
+
+If you override one of the setup/teardown functions make sure to invoke the
+parent's version of the function as well. `AppContext::SetUpTestSuite` and
+`AppContext::SetUp` may generate fatal failures, so after you call these from
+your overriding function make sure to check `HasFailure()` and return if the
+parent function failed.
+
+If you don't override any of the setup/teardown functions, you can simply make a
+type alias: `using YourTestContext = Test::AppContextPW;` instead of defining
+your own text context class.
+
+## Best practices
+
+-   Try to use as specific an assertion as possible. For example use these
+
+    ```
+    EXPECT_EQ(result, 3);
+    EXPECT_GT(result, 1);
+    EXPECT_STREQ(myString, "hello");
+    ```
+
+    instead of these
+
+    ```
+    EXPECT_TRUE(result == 3);
+    EXPECT_TRUE(result > 1);
+    EXPECT_EQ(strcmp(myString, "hello"), 0);
+    ```
+
+-   If you want a test to abort when an assertion fails, use `ASSERT_*` instead
+    of `EXPECT_*`. This will cause the current function to return.
+
+-   If a test calls a subroutine which exits due to an ASSERT failing, execution
+    of the test will continue after the subroutine call. This is because ASSERT
+    causes the subroutine to return (as opposed to throwing an exception). If
+    you want to prevent the test from continuing, check the value of
+    `HasFailure()` and stop execution if true. Example:
+
+    ```
+    void Subroutine()
+    {
+        ASSERT_EQ(1, 2);  // Fatal failure.
+    }
+
+    TEST(YourTestContext, YourTestFunction1)
+    {
+        Subroutine();  // A fatal failure happens in this subroutine...
+        // ... however execution still continues.
+        print("This gets executed");
+        VerifyOrReturn(!HasFailure());
+        print("This does not get executed");
+    }
+    ```
+
+-   If you want to force a fatal failure use `FAIL()`, which will record a fatal
+    failure and exit the current function. This is similar to using
+    `ASSERT_TRUE(false)`. If you want to force a non-fatal failure use
+    `ADD_FAILURE()`, which will record a non-fatal failure and continue
+    executing the current function. This is similar to using
+    `EXPECT_TRUE(false)`.
+
+-   `ASSERT_*` and `FAIL` will only work in functions with void return type,
+    since they generate a `return;` statement. If you must use these in a
+    non-void function, instead use `EXPECT_*` or `ADD_FAILURE` and then check
+    `HasFailure()` afterward and return if needed.
+
+-   If your test requires access to private/protected members of the underlying
+    class you're testing, you'll need to create an accessor class that performs
+    these operations and is friended to the underlying class. Please name the
+    class `chip::Test::SomethingTestAccess` where `Something` is the name of the
+    underlying class whose private/protected members you're trying to access.
+    Then add `friend class chip::Test::SomethingTestAccess;` to the underlying
+    class. Make sure your test's BUILD.gn file contains
+    `sources = [ "SomethingTestAccess.h" ]`. Before creating a new TestAccess
+    class, check if one already exists. If it does exist but doesn't expose the
+    member you need, you can add a function to that class to do so. Note that
+    you should make these functions as minimal as possible, with no logic
+    besides just exposing the private/protected member.
+    -   For an example see `ICDConfigurationDataTestAccess` which is defined in
+        [ICDConfigurationDataTestAccess.h](https://github.com/project-chip/connectedhomeip/blob/master/src/app/icd/server/tests/ICDConfigurationDataTestAccess.h),
+        friends the underlying class in
+        [ICDConfigurationData.h](https://github.com/project-chip/connectedhomeip/blob/master/src/app/icd/server/ICDConfigurationData.h),
+        is included as a source in
+        [BUILD.gn](https://github.com/project-chip/connectedhomeip/blob/master/src/app/icd/server/tests/BUILD.gn),
+        and is used by a test in
+        [TestICDManager.cpp](https://github.com/project-chip/connectedhomeip/blob/master/src/app/icd/server/tests/TestICDManager.cpp).
+    -   For another example see `TCPBaseTestAccess` which is defined in
+        [TCPBaseTestAccess.h](https://github.com/project-chip/connectedhomeip/blob/master/src/transport/raw/tests/TCPBaseTestAccess.h),
+        friends the underlying class in
+        [TCP.h](https://github.com/project-chip/connectedhomeip/blob/master/src/transport/raw/TCP.h),
+        is included as a source in
+        [BUILD.gn](https://github.com/project-chip/connectedhomeip/blob/master/src/transport/raw/tests/BUILD.gn),
+        and is used by a test in
+        [TestTCP.cpp](https://github.com/project-chip/connectedhomeip/blob/master/src/transport/raw/tests/TestTCP.cpp).
+
+## Compiling and running
+
+-   Add to `src/some_directory/tests/BUILD.gn`
+
+    -   Example
+
+        ```
+        chip_test_suite("tests") {
+            output_name = "libSomethingTests"
+
+            test_sources = [
+                "TestSuite1.cpp",
+                "TestSuite2.cpp",
+                // Other test source files go here.
+            ]
+
+            sources = [
+                // Non-test source files go here.
+            ]
+
+            cflags = [ "-Wconversion" ]
+
+            public_deps = [
+                // Dependencies go here.
+            ]
+        }
+        ```
+
+    -   Another example:
+        [src/lib/support/tests/BUILD.gn](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/tests/BUILD.gn)
+
+-   Build and run all tests with
+    [./gn_build.sh](https://github.com/project-chip/connectedhomeip/blob/master/gn_build.sh)
     -   CI runs this, so any unit tests that get added will automatically be
-        added to the CI
+        added to the CI.
 -   Test binaries are compiled into:
-    -   out/debug/<host_compiler>/tests
-    -   e.g. out/debug/linux_x64_clang/tests
--   Tests are run when ./gn_build.sh runs, but you can run them individually in
-    a debugger from their location.
+    -   `out/debug/<host_compiler>/tests`
+    -   e.g. `out/debug/linux_x64_clang/tests`
+-   Tests are run when `./gn_build.sh` runs, but you can run them individually
+    in a debugger from their location.
 
 ## Debugging unit tests
 
--   After running ./gn_build.sh, test binaries are compiled into
-    -   out/debug/<host_compiler>/tests
-    -   e.g. out/debug/linux_x64_clang/tests
--   Individual binaries, can be run through regular tools:
+-   After running `./gn_build.sh`, test binaries are compiled into
+    -   `out/debug/<host_compiler>/tests`
+    -   e.g. `out/debug/linux_x64_clang/tests`
+-   Individual binaries can be run through regular tools:
     -   gdb
     -   valgrind
     -   Your favorite tool that you tell everyone about.