diff --git a/phosphor-regulators/test/meson.build b/phosphor-regulators/test/meson.build
index f036dbb..3dc46f4 100644
--- a/phosphor-regulators/test/meson.build
+++ b/phosphor-regulators/test/meson.build
@@ -14,6 +14,7 @@
     'exception_utils_tests.cpp',
     'ffdc_file_tests.cpp',
     'id_map_tests.cpp',
+    'phase_fault_detection_tests.cpp',
     'phase_fault_tests.cpp',
     'pmbus_error_tests.cpp',
     'pmbus_utils_tests.cpp',
diff --git a/phosphor-regulators/test/phase_fault_detection_tests.cpp b/phosphor-regulators/test/phase_fault_detection_tests.cpp
new file mode 100644
index 0000000..c85970c
--- /dev/null
+++ b/phosphor-regulators/test/phase_fault_detection_tests.cpp
@@ -0,0 +1,765 @@
+/**
+ * Copyright © 2021 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "action.hpp"
+#include "chassis.hpp"
+#include "device.hpp"
+#include "i2c_capture_bytes_action.hpp"
+#include "i2c_compare_bit_action.hpp"
+#include "i2c_interface.hpp"
+#include "if_action.hpp"
+#include "log_phase_fault_action.hpp"
+#include "mock_action.hpp"
+#include "mock_error_logging.hpp"
+#include "mock_journal.hpp"
+#include "mock_services.hpp"
+#include "mocked_i2c_interface.hpp"
+#include "phase_fault.hpp"
+#include "phase_fault_detection.hpp"
+#include "rule.hpp"
+#include "system.hpp"
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace phosphor::power::regulators;
+
+using ::testing::_;
+using ::testing::A;
+using ::testing::NotNull;
+using ::testing::Ref;
+using ::testing::Return;
+using ::testing::SetArrayArgument;
+using ::testing::Throw;
+using ::testing::TypedEq;
+
+class PhaseFaultDetectionTests : public ::testing::Test
+{
+  public:
+    /**
+     * Constructor.
+     *
+     * Creates the following objects needed for calling the
+     * PhaseFaultDetection::execute() method:
+     * - Regulator Device
+     * - I/O expander Device
+     * - Chassis that contains the Devices
+     * - System that contains the Chassis
+     *
+     * Saves pointers to these objects in data members so they can be easily
+     * accessed in tests.  Also saves pointers to the MockI2CInterface objects
+     * so they can be used in mock expectations.
+     */
+    PhaseFaultDetectionTests() : ::testing::Test{}
+    {
+        // Create mock I2CInterface for regulator Device and save pointer
+        auto regI2CInterface = std::make_unique<i2c::MockedI2CInterface>();
+        this->regI2CInterface = regI2CInterface.get();
+
+        // Create regulator Device and save pointer
+        auto regulator = std::make_unique<Device>(
+            "vdd1", true,
+            "/xyz/openbmc_project/inventory/system/chassis/motherboard/vdd1",
+            std::move(regI2CInterface));
+        this->regulator = regulator.get();
+
+        // Create mock I2CInterface for I/O expander Device and save pointer
+        auto ioExpI2CInterface = std::make_unique<i2c::MockedI2CInterface>();
+        this->ioExpI2CInterface = ioExpI2CInterface.get();
+
+        // Create I/O expander Device and save pointer
+        auto ioExpander = std::make_unique<Device>(
+            "ioexp1", false,
+            "/xyz/openbmc_project/inventory/system/chassis/motherboard/ioexp1",
+            std::move(ioExpI2CInterface));
+        this->ioExpander = ioExpander.get();
+
+        // Create Chassis that contains Devices and save pointer
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(regulator));
+        devices.emplace_back(std::move(ioExpander));
+        auto chassis = std::make_unique<Chassis>(
+            1, "/xyz/openbmc_project/inventory/system/chassis",
+            std::move(devices));
+        this->chassis = chassis.get();
+
+        // Create System that contains Chassis and save pointer
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        this->system =
+            std::make_unique<System>(std::move(rules), std::move(chassisVec));
+    }
+
+  protected:
+    /**
+     * Note: The following pointers do NOT need to be explicitly deleted.  They
+     * point to objects that are owned by the System object.  All the objects
+     * will be automatically deleted.
+     */
+    i2c::MockedI2CInterface* regI2CInterface{nullptr};
+    Device* regulator{nullptr};
+    i2c::MockedI2CInterface* ioExpI2CInterface{nullptr};
+    Device* ioExpander{nullptr};
+    Chassis* chassis{nullptr};
+
+    /**
+     * System object.  Owns all the other objects and will automatically delete
+     * them.
+     */
+    std::unique_ptr<System> system{};
+};
+
+TEST_F(PhaseFaultDetectionTests, Constructor)
+{
+    // Test where device ID not specified
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::make_unique<MockAction>());
+
+        PhaseFaultDetection detection{std::move(actions)};
+        EXPECT_EQ(detection.getActions().size(), 1);
+        EXPECT_EQ(detection.getDeviceID(), "");
+    }
+
+    // Test where device ID not specified
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::make_unique<MockAction>());
+        actions.push_back(std::make_unique<MockAction>());
+
+        PhaseFaultDetection detection{std::move(actions), "ioexp1"};
+        EXPECT_EQ(detection.getActions().size(), 2);
+        EXPECT_EQ(detection.getDeviceID(), "ioexp1");
+    }
+}
+
+TEST_F(PhaseFaultDetectionTests, ClearErrorHistory)
+{
+    std::vector<std::unique_ptr<Action>> actions{};
+
+    // Create MockAction that will switch every 5 times between working and
+    // throwing an exception.  Expect it to be executed 20 times.
+    std::logic_error error{"Logic error"};
+    auto action = std::make_unique<MockAction>();
+    EXPECT_CALL(*action, execute)
+        .Times(20)
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Return(true))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error))
+        .WillOnce(Throw(error));
+    actions.push_back(std::move(action));
+
+    // Create a LogPhaseFaultAction that will log N faults
+    actions.push_back(std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n));
+
+    // Create a LogPhaseFaultAction that will log N+1 faults
+    actions.push_back(
+        std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n_plus_1));
+
+    // Create PhaseFaultDetection
+    PhaseFaultDetection detection{std::move(actions)};
+
+    // Create lambda that sets Journal and ErrorLogging expectations when
+    // performing phase fault detection 10 times.  The lambda allows us to
+    // set the same expectations twice without duplicate code.
+    auto setExpectations = [](MockServices& services) {
+        // Set Journal service expectations:
+        // - 3 error messages for the MockAction exceptions
+        // - 3 error messages for inability to detect phase faults
+        // - 2 error messages for the N phase fault
+        // - 2 error messages for the N+1 phase fault
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(journal, logError(std::vector<std::string>{"Logic error"}))
+            .Times(3);
+        EXPECT_CALL(journal,
+                    logError("Unable to detect phase faults in regulator vdd1"))
+            .Times(3);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+
+        // Set ErrorLogging service expectations:
+        // - Internal error should be logged once for the MockAction exceptions
+        // - N phase fault error should be logged once
+        // - N+1 phase fault error should be logged once
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logInternalError).Times(1);
+        EXPECT_CALL(errorLogging, logPhaseFault(_, _, PhaseFaultType::n, _, _))
+            .Times(1);
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(_, _, PhaseFaultType::n_plus_1, _, _))
+            .Times(1);
+    };
+
+    // Perform phase fault detection 10 times to set error history data members
+    {
+        // Create mock services.  Set expectations via lambda.
+        MockServices services{};
+        setExpectations(services);
+
+        // Execute PhaseFaultDetection 10 times
+        for (int i = 1; i <= 10; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Clear error history
+    detection.clearErrorHistory();
+
+    // Perform phase fault detection 10 more times.  Verify errors logged again.
+    {
+        // Create mock services.  Set expectations via lambda.
+        MockServices services{};
+        setExpectations(services);
+
+        // Execute PhaseFaultDetection 10 times
+        for (int i = 1; i <= 10; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+}
+
+TEST_F(PhaseFaultDetectionTests, Execute)
+{
+    // Test where Device ID was specified
+    {
+        // Create I2CCompareBitAction that will use an I2CInterface
+        auto action = std::make_unique<I2CCompareBitAction>(0x1C, 2, 0);
+
+        // Create PhaseFaultDetection.  Specify device ID of I/O expander.
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions), "ioexp1"};
+
+        // Set expectations for regulator I2C interface.  Should not be used.
+        EXPECT_CALL(*regI2CInterface, isOpen).Times(0);
+        EXPECT_CALL(*regI2CInterface, read(0x1C, A<uint8_t&>())).Times(0);
+
+        // Set expectations for I/O expander I2C interface.  Should be used.
+        EXPECT_CALL(*ioExpI2CInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*ioExpI2CInterface, read(0x1C, A<uint8_t&>())).Times(1);
+
+        // Create mock services.  Expect no errors to be logged.
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logPhaseFault).Times(0);
+
+        // Execute PhaseFaultDetection
+        detection.execute(services, *system, *chassis, *regulator);
+    }
+
+    // Test where Device ID was not specified
+    {
+        // Create I2CCompareBitAction that will use an I2CInterface
+        auto action = std::make_unique<I2CCompareBitAction>(0x1C, 2, 0);
+
+        // Create PhaseFaultDetection.  Specify no device ID, which means the
+        // regulator should be used.
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Set expectations for regulator I2C interface.  Should be used.
+        EXPECT_CALL(*regI2CInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*regI2CInterface, read(0x1C, A<uint8_t&>())).Times(1);
+
+        // Set expectations for I/O expander I2C interface.  Should not be used.
+        EXPECT_CALL(*ioExpI2CInterface, isOpen).Times(0);
+        EXPECT_CALL(*ioExpI2CInterface, read(0x1C, A<uint8_t&>())).Times(0);
+
+        // Create mock services.  Expect no errors to be logged.
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logPhaseFault).Times(0);
+
+        // Execute PhaseFaultDetection
+        detection.execute(services, *system, *chassis, *regulator);
+    }
+
+    // Test where no phase faults detected
+    {
+        // Create MockAction.  Expect it to be executed 3 times.
+        auto action = std::make_unique<MockAction>();
+        EXPECT_CALL(*action, execute).Times(3).WillRepeatedly(Return(true));
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services.  Expect no errors to be logged.
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logPhaseFault).Times(0);
+
+        // Execute PhaseFaultDetection 3 times
+        for (int i = 1; i <= 3; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where N fault occurs, but not twice in a row
+    {
+        // Create MockAction that will alternate between returning true and
+        // false.  Expect it to be executed 6 times.  Use it for the "condition"
+        // of an IfAction.
+        auto conditionAction = std::make_unique<MockAction>();
+        EXPECT_CALL(*conditionAction, execute)
+            .Times(6)
+            .WillOnce(Return(true))
+            .WillOnce(Return(false))
+            .WillOnce(Return(true))
+            .WillOnce(Return(false))
+            .WillOnce(Return(true))
+            .WillOnce(Return(false));
+
+        // Create a LogPhaseFaultAction that will log an N phase fault in the
+        // ActionEnvironment.  Use it for the "then" clause of an IfAction.
+        auto logPhaseFaultAction =
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
+
+        // Create an IfAction that will log an N phase fault in the
+        // ActionEnvironment if the mock condition is true.
+        std::vector<std::unique_ptr<Action>> thenActions{};
+        thenActions.push_back(std::move(logPhaseFaultAction));
+        auto ifAction = std::make_unique<IfAction>(std::move(conditionAction),
+                                                   std::move(thenActions));
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(ifAction));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services.  Expect 3 error messages in the journal for
+        // an N phase fault detected with the consecutive count = 1.  Expect no
+        // phase fault error to be logged.
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=1"))
+            .Times(3);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=2"))
+            .Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logPhaseFault).Times(0);
+
+        // Execute PhaseFaultDetection 6 times
+        for (int i = 1; i <= 6; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where N+1 fault occurs, but not twice in a row
+    {
+        // Create MockAction that will alternate between returning true and
+        // false.  Expect it to be executed 6 times.  Use it for the "condition"
+        // of an IfAction.
+        auto conditionAction = std::make_unique<MockAction>();
+        EXPECT_CALL(*conditionAction, execute)
+            .Times(6)
+            .WillOnce(Return(true))
+            .WillOnce(Return(false))
+            .WillOnce(Return(true))
+            .WillOnce(Return(false))
+            .WillOnce(Return(true))
+            .WillOnce(Return(false));
+
+        // Create a LogPhaseFaultAction that will log an N+1 phase fault in the
+        // ActionEnvironment.  Use it for the "then" clause of an IfAction.
+        auto logPhaseFaultAction =
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n_plus_1);
+
+        // Create an IfAction that will log an N+1 phase fault in the
+        // ActionEnvironment if the mock condition is true.
+        std::vector<std::unique_ptr<Action>> thenActions{};
+        thenActions.push_back(std::move(logPhaseFaultAction));
+        auto ifAction = std::make_unique<IfAction>(std::move(conditionAction),
+                                                   std::move(thenActions));
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(ifAction));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services.  Expect 3 error messages in the journal for
+        // an N+1 phase fault detected with the consecutive count = 1.  Expect
+        // no phase fault error to be logged.
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=1"))
+            .Times(3);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=2"))
+            .Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging, logPhaseFault).Times(0);
+
+        // Execute PhaseFaultDetection 6 times
+        for (int i = 1; i <= 6; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where N fault detected twice in a row
+    {
+        // Create action that will log an N phase fault in ActionEnvironment
+        auto action = std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services with the following expectations:
+        // - 2 error messages in journal for N phase fault detected
+        // - 0 error messages in journal for N+1 phase fault detected
+        // - 1 N phase fault error logged
+        // - 0 N+1 phase fault errors logged
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=1"))
+            .Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        std::map<std::string, std::string> additionalData{};
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(Entry::Level::Warning, Ref(journal),
+                                  PhaseFaultType::n, regulator->getFRU(),
+                                  additionalData))
+            .Times(1);
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(_, _, PhaseFaultType::n_plus_1, _, _))
+            .Times(0);
+
+        // Execute PhaseFaultDetection 5 times
+        for (int i = 1; i <= 5; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where N+1 fault detected twice in a row
+    {
+        // Create action that will log an N+1 phase fault in ActionEnvironment
+        auto action =
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n_plus_1);
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services with the following expectations:
+        // - 2 error messages in journal for N+1 phase fault detected
+        // - 0 error messages in journal for N phase fault detected
+        // - 1 N+1 phase fault error logged
+        // - 0 N phase fault errors logged
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=1"))
+            .Times(0);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        std::map<std::string, std::string> additionalData{};
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(Entry::Level::Informational, Ref(journal),
+                                  PhaseFaultType::n_plus_1, regulator->getFRU(),
+                                  additionalData))
+            .Times(1);
+        EXPECT_CALL(errorLogging, logPhaseFault(_, _, PhaseFaultType::n, _, _))
+            .Times(0);
+
+        // Execute PhaseFaultDetection 5 times
+        for (int i = 1; i <= 5; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where both faults detected twice in a row
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+
+        // Create action that will log an N+1 phase fault in ActionEnvironment
+        actions.push_back(
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n_plus_1));
+
+        // Create action that will log an N phase fault in ActionEnvironment
+        actions.push_back(
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n));
+
+        // Create PhaseFaultDetection
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Create mock services with the following expectations:
+        // - 2 error messages in journal for N+1 phase fault detected
+        // - 2 error messages in journal for N phase fault detected
+        // - 1 N+1 phase fault error logged
+        // - 1 N phase fault error logged
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n+1 phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=1"))
+            .Times(1);
+        EXPECT_CALL(
+            journal,
+            logError("n phase fault detected in regulator vdd1: count=2"))
+            .Times(1);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        std::map<std::string, std::string> additionalData{};
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(Entry::Level::Informational, Ref(journal),
+                                  PhaseFaultType::n_plus_1, regulator->getFRU(),
+                                  additionalData))
+            .Times(1);
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(Entry::Level::Warning, Ref(journal),
+                                  PhaseFaultType::n, regulator->getFRU(),
+                                  additionalData))
+            .Times(1);
+
+        // Execute PhaseFaultDetection 5 times
+        for (int i = 1; i <= 5; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where additional error data is captured
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+
+        // Create action that will capture 1 byte from register 0x0F
+        actions.push_back(std::make_unique<I2CCaptureBytesAction>(0x0F, 1));
+
+        // Create action that will capture 2 bytes from register 0x21
+        actions.push_back(std::make_unique<I2CCaptureBytesAction>(0x21, 2));
+
+        // Create action that will log an N phase fault in ActionEnvironment
+        actions.push_back(
+            std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n));
+
+        // Create PhaseFaultDetection
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Set expectations for regulator I2C interface:
+        // - isOpen() will return true
+        // - reading 1 byte from register 0x0F will return 0xDA
+        // - reading 2 bytes from register 0x21 will return [ 0x56, 0x14 ]
+        EXPECT_CALL(*regI2CInterface, isOpen).WillRepeatedly(Return(true));
+        uint8_t register0FValues[] = {0xDA};
+        EXPECT_CALL(*regI2CInterface,
+                    read(0x0F, TypedEq<uint8_t&>(1), NotNull(),
+                         i2c::I2CInterface::Mode::I2C))
+            .Times(5)
+            .WillRepeatedly(
+                SetArrayArgument<2>(register0FValues, register0FValues + 1));
+        uint8_t register21Values[] = {0x56, 0x14};
+        EXPECT_CALL(*regI2CInterface,
+                    read(0x21, TypedEq<uint8_t&>(2), NotNull(),
+                         i2c::I2CInterface::Mode::I2C))
+            .Times(5)
+            .WillRepeatedly(
+                SetArrayArgument<2>(register21Values, register21Values + 2));
+
+        // Create mock services with the following expectations:
+        // - 2 error messages in journal for N phase fault detected
+        // - 1 N phase fault error logged with additional data
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        EXPECT_CALL(journal, logError(A<const std::string&>())).Times(2);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        std::map<std::string, std::string> additionalData{
+            {"vdd1_register_0xF", "[ 0xDA ]"},
+            {"vdd1_register_0x21", "[ 0x56, 0x14 ]"}};
+        EXPECT_CALL(errorLogging,
+                    logPhaseFault(Entry::Level::Warning, Ref(journal),
+                                  PhaseFaultType::n, regulator->getFRU(),
+                                  additionalData))
+            .Times(1);
+
+        // Execute PhaseFaultDetection 5 times
+        for (int i = 1; i <= 5; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+
+    // Test where fails: Exception thrown by actions
+    {
+        // Create I2CCompareBitAction that will use the I2CInterface
+        auto action = std::make_unique<I2CCompareBitAction>(0x7C, 2, 0);
+
+        // Create PhaseFaultDetection
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::move(action));
+        PhaseFaultDetection detection{std::move(actions)};
+
+        // Set expectations for regulator I2C interface:
+        // - isOpen() will return true
+        // - reading 1 byte from register 0x7C will throw an I2CException
+        EXPECT_CALL(*regI2CInterface, isOpen).WillRepeatedly(Return(true));
+        EXPECT_CALL(*regI2CInterface, read(0x7C, A<uint8_t&>()))
+            .Times(5)
+            .WillRepeatedly(Throw(
+                i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
+
+        // Create mock services with the following expectations:
+        // - 3 error messages in journal for exception
+        // - 3 error messages in journal for inability to detect phase faults
+        // - 1 I2C error logged
+        MockServices services{};
+        MockJournal& journal = services.getMockJournal();
+        std::vector<std::string> exceptionMessages{
+            "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70",
+            "ActionError: i2c_compare_bit: { register: 0x7C, position: 2, "
+            "value: 0 }"};
+        EXPECT_CALL(journal, logError(exceptionMessages)).Times(3);
+        EXPECT_CALL(journal,
+                    logError("Unable to detect phase faults in regulator vdd1"))
+            .Times(3);
+        MockErrorLogging& errorLogging = services.getMockErrorLogging();
+        EXPECT_CALL(errorLogging,
+                    logI2CError(Entry::Level::Warning, Ref(journal),
+                                "/dev/i2c-1", 0x70, 0))
+            .Times(1);
+
+        // Execute PhaseFaultDetection 5 times
+        for (int i = 1; i <= 5; ++i)
+        {
+            detection.execute(services, *system, *chassis, *regulator);
+        }
+    }
+}
+
+TEST_F(PhaseFaultDetectionTests, GetActions)
+{
+    std::vector<std::unique_ptr<Action>> actions{};
+
+    MockAction* action1 = new MockAction{};
+    actions.push_back(std::unique_ptr<MockAction>{action1});
+
+    MockAction* action2 = new MockAction{};
+    actions.push_back(std::unique_ptr<MockAction>{action2});
+
+    PhaseFaultDetection detection{std::move(actions)};
+    EXPECT_EQ(detection.getActions().size(), 2);
+    EXPECT_EQ(detection.getActions()[0].get(), action1);
+    EXPECT_EQ(detection.getActions()[1].get(), action2);
+}
+
+TEST_F(PhaseFaultDetectionTests, GetDeviceID)
+{
+    // Test where device ID not specified
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::make_unique<MockAction>());
+
+        PhaseFaultDetection detection{std::move(actions)};
+        EXPECT_EQ(detection.getDeviceID(), "");
+    }
+
+    // Test where device ID not specified
+    {
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.push_back(std::make_unique<MockAction>());
+
+        PhaseFaultDetection detection{std::move(actions), "ioexp1"};
+        EXPECT_EQ(detection.getDeviceID(), "ioexp1");
+    }
+}
