diff --git a/phosphor-regulators/test/configuration_tests.cpp b/phosphor-regulators/test/configuration_tests.cpp
index a4086e1..0865be7 100644
--- a/phosphor-regulators/test/configuration_tests.cpp
+++ b/phosphor-regulators/test/configuration_tests.cpp
@@ -14,17 +14,34 @@
  * limitations under the License.
  */
 #include "action.hpp"
+#include "chassis.hpp"
 #include "configuration.hpp"
+#include "device.hpp"
+#include "i2c_interface.hpp"
+#include "i2c_write_byte_action.hpp"
+#include "journal.hpp"
 #include "mock_action.hpp"
+#include "mock_journal.hpp"
+#include "mocked_i2c_interface.hpp"
+#include "pmbus_utils.hpp"
+#include "pmbus_write_vout_command_action.hpp"
+#include "rail.hpp"
+#include "system.hpp"
 
 #include <memory>
 #include <optional>
 #include <utility>
 #include <vector>
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using namespace phosphor::power::regulators;
+using namespace phosphor::power::regulators::pmbus_utils;
+
+using ::testing::Return;
+using ::testing::Throw;
+using ::testing::TypedEq;
 
 TEST(ConfigurationTests, Constructor)
 {
@@ -55,9 +72,368 @@
     }
 }
 
-TEST(ConfigurationTests, Execute)
+// Test for execute(System&, Chassis&, Device&)
+TEST(ConfigurationTests, ExecuteForDevice)
 {
-    // TODO: Implement test when execute() function is done
+    // Test where works: Volts value not specified
+    {
+        // Create I2CWriteByteAction with register 0x7C and value 0x0A
+        std::unique_ptr<I2CWriteByteAction> action =
+            std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
+
+        // Create mock I2CInterface.  Expect action to write 0x0A to 0x7C.
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
+            .Times(1);
+
+        // Create Configuration with no volts value specified
+        std::optional<double> volts{};
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(volts, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Device that contains Configuration
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "vdd_reg", true, "/system/chassis/motherboard/reg2",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(configuration));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr);
+        std::vector<std::string> expectedDebugMessages{"Configuring vdd_reg"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+    }
+
+    // Test where works: Volts value specified
+    {
+        // Create PMBusWriteVoutCommandAction.  Do not specify a volts value
+        // because it will get a value of 1.3V from the
+        // ActionEnvironment/Configuration.  Specify a -8 exponent.
+        // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D.
+        std::optional<double> volts{};
+        std::unique_ptr<PMBusWriteVoutCommandAction> action =
+            std::make_unique<PMBusWriteVoutCommandAction>(
+                volts, pmbus_utils::VoutDataFormat::linear, -8, false);
+
+        // Create mock I2CInterface.  Expect action to write 0x014D to
+        // VOUT_COMMAND (command/register 0x21).
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
+            .Times(1);
+
+        // Create Configuration with volts value 1.3V
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(1.3, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Device that contains Configuration
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "vdd_reg", true, "/system/chassis/motherboard/reg2",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(configuration));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr);
+        std::vector<std::string> expectedDebugMessages{
+            "Configuring vdd_reg: volts=1.300000"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+    }
+
+    // Test where fails
+    {
+        // Create I2CWriteByteAction with register 0x7C and value 0x0A
+        std::unique_ptr<I2CWriteByteAction> action =
+            std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
+
+        // Create mock I2CInterface.  write() throws an I2CException.
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
+            .Times(1)
+            .WillOnce(Throw(
+                i2c::I2CException{"Failed to write byte", "/dev/i2c-1", 0x70}));
+
+        // Create Configuration with no volts value specified
+        std::optional<double> volts{};
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(volts, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Device that contains Configuration
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "vdd_reg", true, "/system/chassis/motherboard/reg2",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(configuration));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr);
+        std::vector<std::string> expectedDebugMessages{"Configuring vdd_reg"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        std::vector<std::string> expectedErrMessages{
+            "I2CException: Failed to write byte: bus /dev/i2c-1, addr 0x70",
+            "ActionError: i2c_write_byte: { register: 0x7C, value: 0xA, mask: "
+            "0xFF }",
+            "Unable to configure vdd_reg"};
+        EXPECT_EQ(journal::getErrMessages(), expectedErrMessages);
+    }
+}
+
+// Test for execute(System&, Chassis&, Device&, Rail&)
+TEST(ConfigurationTests, ExecuteForRail)
+{
+    // Test where works: Volts value not specified
+    {
+        // Create I2CWriteByteAction with register 0x7C and value 0x0A
+        std::unique_ptr<I2CWriteByteAction> action =
+            std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
+
+        // Create mock I2CInterface.  Expect action to write 0x0A to 0x7C.
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
+            .Times(1);
+
+        // Create Configuration with no volts value specified
+        std::optional<double> volts{};
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(volts, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Rail that contains Configuration
+        std::unique_ptr<Rail> rail =
+            std::make_unique<Rail>("vio2", std::move(configuration));
+        Rail* railPtr = rail.get();
+
+        // Create Device that contains Rail
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Configuration> deviceConfiguration{};
+        std::vector<std::unique_ptr<Rail>> rails{};
+        rails.emplace_back(std::move(rail));
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "reg1", true, "/system/chassis/motherboard/reg1",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(deviceConfiguration), std::move(rails));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr, *railPtr);
+        std::vector<std::string> expectedDebugMessages{"Configuring vio2"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+    }
+
+    // Test where works: Volts value specified
+    {
+        // Create PMBusWriteVoutCommandAction.  Do not specify a volts value
+        // because it will get a value of 1.3V from the
+        // ActionEnvironment/Configuration.  Specify a -8 exponent.
+        // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D.
+        std::optional<double> volts{};
+        std::unique_ptr<PMBusWriteVoutCommandAction> action =
+            std::make_unique<PMBusWriteVoutCommandAction>(
+                volts, pmbus_utils::VoutDataFormat::linear, -8, false);
+
+        // Create mock I2CInterface.  Expect action to write 0x014D to
+        // VOUT_COMMAND (command/register 0x21).
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
+            .Times(1);
+
+        // Create Configuration with volts value 1.3V
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(1.3, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Rail that contains Configuration
+        std::unique_ptr<Rail> rail =
+            std::make_unique<Rail>("vio2", std::move(configuration));
+        Rail* railPtr = rail.get();
+
+        // Create Device that contains Rail
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Configuration> deviceConfiguration{};
+        std::vector<std::unique_ptr<Rail>> rails{};
+        rails.emplace_back(std::move(rail));
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "reg1", true, "/system/chassis/motherboard/reg1",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(deviceConfiguration), std::move(rails));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr, *railPtr);
+        std::vector<std::string> expectedDebugMessages{
+            "Configuring vio2: volts=1.300000"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        EXPECT_EQ(journal::getErrMessages().size(), 0);
+    }
+
+    // Test where fails
+    {
+        // Create I2CWriteByteAction with register 0x7C and value 0x0A
+        std::unique_ptr<I2CWriteByteAction> action =
+            std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
+
+        // Create mock I2CInterface.  write() throws an I2CException.
+        std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
+            std::make_unique<i2c::MockedI2CInterface>();
+        EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
+        EXPECT_CALL(*i2cInterface,
+                    write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
+            .Times(1)
+            .WillOnce(Throw(
+                i2c::I2CException{"Failed to write byte", "/dev/i2c-1", 0x70}));
+
+        // Create Configuration with no volts value specified
+        std::optional<double> volts{};
+        std::vector<std::unique_ptr<Action>> actions{};
+        actions.emplace_back(std::move(action));
+        std::unique_ptr<Configuration> configuration =
+            std::make_unique<Configuration>(volts, std::move(actions));
+        Configuration* configurationPtr = configuration.get();
+
+        // Create Rail that contains Configuration
+        std::unique_ptr<Rail> rail =
+            std::make_unique<Rail>("vio2", std::move(configuration));
+        Rail* railPtr = rail.get();
+
+        // Create Device that contains Rail
+        std::unique_ptr<PresenceDetection> presenceDetection{};
+        std::unique_ptr<Configuration> deviceConfiguration{};
+        std::vector<std::unique_ptr<Rail>> rails{};
+        rails.emplace_back(std::move(rail));
+        std::unique_ptr<Device> device = std::make_unique<Device>(
+            "reg1", true, "/system/chassis/motherboard/reg1",
+            std::move(i2cInterface), std::move(presenceDetection),
+            std::move(deviceConfiguration), std::move(rails));
+        Device* devicePtr = device.get();
+
+        // Create Chassis that contains Device
+        std::vector<std::unique_ptr<Device>> devices{};
+        devices.emplace_back(std::move(device));
+        std::unique_ptr<Chassis> chassis =
+            std::make_unique<Chassis>(1, std::move(devices));
+        Chassis* chassisPtr = chassis.get();
+
+        // Create System that contains Chassis
+        std::vector<std::unique_ptr<Rule>> rules{};
+        std::vector<std::unique_ptr<Chassis>> chassisVec{};
+        chassisVec.emplace_back(std::move(chassis));
+        System system{std::move(rules), std::move(chassisVec)};
+
+        // Execute Configuration
+        journal::clear();
+        configurationPtr->execute(system, *chassisPtr, *devicePtr, *railPtr);
+        std::vector<std::string> expectedDebugMessages{"Configuring vio2"};
+        EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
+        std::vector<std::string> expectedErrMessages{
+            "I2CException: Failed to write byte: bus /dev/i2c-1, addr 0x70",
+            "ActionError: i2c_write_byte: { register: 0x7C, value: 0xA, mask: "
+            "0xFF }",
+            "Unable to configure vio2"};
+        EXPECT_EQ(journal::getErrMessages(), expectedErrMessages);
+    }
 }
 
 TEST(ConfigurationTests, GetActions)
