From b0b04b2b58605f18c3c430b13559495ff76aa2a6 Mon Sep 17 00:00:00 2001 From: Javier Balloffet Date: Sun, 14 Jan 2024 21:12:25 +0100 Subject: [PATCH] Add Motor unit tests Signed-off-by: Javier Balloffet --- andino_firmware/platformio.ini | 4 +- .../test/desktop/test_motor/motor_test.cpp | 121 ++++++++++++++++++ .../test_pid}/pid_test.cpp | 0 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 andino_firmware/test/desktop/test_motor/motor_test.cpp rename andino_firmware/test/{test_desktop => desktop/test_pid}/pid_test.cpp (100%) diff --git a/andino_firmware/platformio.ini b/andino_firmware/platformio.ini index 5b596555..7bd5a0d9 100644 --- a/andino_firmware/platformio.ini +++ b/andino_firmware/platformio.ini @@ -21,12 +21,14 @@ build_flags = platform = atmelavr framework = arduino monitor_speed = 57600 -test_ignore = test_desktop +test_ignore = desktop/* ; Base configuration for desktop platforms (for unit testing). [base_desktop] platform = native test_framework = googletest +test_build_src = true +build_src_filter = + ; Environment for Arduino Uno. [env:uno] diff --git a/andino_firmware/test/desktop/test_motor/motor_test.cpp b/andino_firmware/test/desktop/test_motor/motor_test.cpp new file mode 100644 index 00000000..114e60b6 --- /dev/null +++ b/andino_firmware/test/desktop/test_motor/motor_test.cpp @@ -0,0 +1,121 @@ +// BSD 3-Clause License +// +// Copyright (c) 2024, Ekumen Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "motor.h" + +#include +#include + +#include "digital_out.h" +#include "pwm_out.h" + +namespace andino { +namespace test { +namespace { + +class MockDigitalOut : public andino::DigitalOut { + public: + MockDigitalOut(const int gpio_pin) : andino::DigitalOut(gpio_pin) {} + MOCK_METHOD(void, begin, (), (const, override)); + MOCK_METHOD(void, write, (int value), (const, override)); +}; + +class MockPwmOut : public andino::PwmOut { + public: + MockPwmOut(const int gpio_pin) : andino::PwmOut(gpio_pin) {} + MOCK_METHOD(void, begin, (), (const, override)); + MOCK_METHOD(void, write, (int value), (const, override)); +}; + +class MotorTest : public testing::Test { + protected: + MockDigitalOut enable_gpio_pin_{0}; + MockPwmOut forward_gpio_pin_{0}; + MockPwmOut backward_gpio_pin_{0}; +}; + +TEST_F(MotorTest, InitializeOk) { + EXPECT_CALL(enable_gpio_pin_, begin()).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.begin(); +} + +TEST_F(MotorTest, SetPositiveSpeed) { + EXPECT_CALL(forward_gpio_pin_, write(100)).Times(1); + EXPECT_CALL(backward_gpio_pin_, write(0)).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.set_speed(100); +} + +TEST_F(MotorTest, SetNegativeSpeed) { + EXPECT_CALL(forward_gpio_pin_, write(0)).Times(1); + EXPECT_CALL(backward_gpio_pin_, write(100)).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.set_speed(-100); +} + +TEST_F(MotorTest, SetZeroSpeed) { + EXPECT_CALL(forward_gpio_pin_, write(0)).Times(1); + EXPECT_CALL(backward_gpio_pin_, write(0)).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.set_speed(0); +} + +TEST_F(MotorTest, SetHigherThanMaximumPositiveSpeed) { + EXPECT_CALL(forward_gpio_pin_, write(255)).Times(1); + EXPECT_CALL(backward_gpio_pin_, write(0)).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.set_speed(500); +} + +TEST_F(MotorTest, SetLowerThanMinimumNegativeSpeed) { + EXPECT_CALL(forward_gpio_pin_, write(0)).Times(1); + EXPECT_CALL(backward_gpio_pin_, write(255)).Times(1); + + andino::Motor motor(&enable_gpio_pin_, &forward_gpio_pin_, &backward_gpio_pin_); + motor.set_speed(-500); +} + +} // namespace +} // namespace test +} // namespace andino + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if (RUN_ALL_TESTS()) { + } + + // Always return zero-code and allow PlatformIO to parse results. + return 0; +} diff --git a/andino_firmware/test/test_desktop/pid_test.cpp b/andino_firmware/test/desktop/test_pid/pid_test.cpp similarity index 100% rename from andino_firmware/test/test_desktop/pid_test.cpp rename to andino_firmware/test/desktop/test_pid/pid_test.cpp