如何在Python中单元测试覆盆子pi的GPIO输出值

Yui*_*iga 5 python raspberry-pi python-unittest

我正在使用python制作Raspberry Pi程序.我想写unittest我的python代码.如何获得输出状态GPIO

测试目标类是下面的.我想在调用stop,brake,rotateClockwise和rotateCounterClockwise后检查输出.

import RPi.GPIO as GPIO
# moter management class, with like TA7291P
class MoterManager:
    def __init__(self, in1Pin, in2Pin):
        self.__in1Pin = in1Pin
        self.__in2Pin = in2Pin

    def stop(self):
        self.__offIn1()
        self.__offIn2()

    def brake(self):
        elf.__onIn1()
        self.__onIn2()

    def rotateClockwise(self):
        self.__onIn1()
        self.__offIn2()

    def rotateCounterClockwise(self):
        self.__offIn1()
        self.__onIn2()

    def __onIn1(self):
        GPIO.output( self.__in1Pin, True)
        print "In1 on"

    def __onIn2(self):
        GPIO.output( self.__in2Pin, True)
        print "In2 on"

    def __offIn1(self):
        GPIO.output( self.__in1Pin, False )
        print "In1 off"

    def __offIn2(self):
        GPIO.output( self.__in2Pin, False )
        print "In2 off"
Run Code Online (Sandbox Code Playgroud)

Mic*_*ico 5

如果你信任RPi.GPIO库,我认为这是一个很好的论点,你可以patch通过unittest.mock框架来实现。patch RPi.GPIO.output让您有可能打破对硬件的依赖并感知对该函数的调用。

那可能是你的测试课

import unittest
from unittest.mock import patch, call
from my_module import MoterManager

@patch("RPi.GPIO.output", autospec=True)
class TestMoterManager(unittest.TestClass):
    in1Pin=67
    in2Pin=68

    def test_init(self, mock_output):
        """If you would MoterManager() stop motor when you build it your test looks like follow code"""
        mm = MoterManager(self.in1Pin,self.in1Pin)
        mock_output.assert_has_calls([call(self.in1Pin, False),call(self.in2Pin, False)],any_order=True)

    def test_stop(self, mock_output):
        mm = MoterManager(self.in1Pin,self.in1Pin)
        mock_output.reset_mock
        mm.stop()
        mock_output.assert_has_calls([call(self.in1Pin, False),call(self.in2Pin, False)],any_order=True)

    def test_brake(self, mock_output):
        mm = MoterManager(self.in1Pin,self.in1Pin)
        mock_output.reset_mock
        mm.stop()
        mock_output.assert_has_calls([call(self.in1Pin, True),call(self.in2Pin, True)],any_order=True)

    def test_rotateClockwise(self, mock_output):
        mm = MoterManager(self.in1Pin,self.in1Pin)
        mock_output.reset_mock
        mm.stop()
        mock_output.assert_has_calls([call(self.in1Pin, True),call(self.in2Pin, False)],any_order=True)

    def test_rotateCounterClockwise(self, mock_output):
        mm = MoterManager(self.in1Pin,self.in1Pin)
        mock_output.reset_mock
        mm.stop()
        mock_output.assert_has_calls([call(self.in1Pin, False),call(self.in2Pin, True)],any_order=True)
Run Code Online (Sandbox Code Playgroud)

几点注意事项:

  • 在 python-2.7 中使用mockavailable bypip代替unittest.mock
  • autospec=True如果你想知道为什么看这个,我几乎在每个测试中都使用
  • 我的测试应该会在您的代码中引发几乎 1 个错误:brake方法中的拼写错误