[{"data":1,"prerenderedAt":130},["ShallowReactive",2],{"$f3b4kt8h8rzrno":3},{"title":4,"date":5,"tags":6,"categories":11,"draft":14,"_id":15,"slug":16,"path":17,"document":18,"excerpt":128,"readingTimeMinutes":129},"Unit Testing in MicroPython with Mocks","2020-02-07T00:00:00.000Z",[7,8,9,10],"micropython","testing","mocks","tutorial",[12,13],"python","embedded",false,"content:blog:unit-testing-micropython-with-mocks","unit-testing-micropython-with-mocks","\u002Fblog\u002Funit-testing-micropython-with-mocks",{"frontmatter":19,"meta":20,"nodes":21},{},{},[22,26,30,35,38,42,54,62,74,79,90,95,109,114],[23,24,25],"p",{},"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.",[27,28,29],null,{},"more",[31,32,34],"h1",{"id":33},"mocking","Mocking",[23,36,37],{},"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed.",[31,39,41],{"id":40},"a-micropython-mocking-example","A MicroPython Mocking Example",[23,43,44,45,49,50,53],{},"In this example, we will be unit testing a module named ",[46,47,48],"code",{},"time_logger",", that\ndepends on the MicroPython library ",[46,51,52],{},"utime"," to log the most recent Epoch time to\na file.",[55,56,58],"pre",{"language":12,"class":57},"shiki dark:tokyo-night",[46,59,61],{"class":60},"language-python","# time_logger.py\n\nclass TimeLogger(object):\n\n    def save_time(self):\n        \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n        \"\"\"\n        with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n            f.write(str(utime.time()))",[23,63,64,65,67,68,70,71,73],{},"First, because the ",[46,66,52],{}," module is not installed on the machine that the unit\ntests on, we must mock ",[46,69,52],{}," module before importing ",[46,72,48],{}," in our\nunit test file.",[55,75,76],{"language":12,"class":57},[46,77,78],{"class":60},"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger",[23,80,81,82,85,86,89],{},"Then, we can write a test that patches the ",[46,83,84],{},"utime.time"," functionality so that\nit returns a value of our choosing -- in this case, ",[46,87,88],{},"1234",".",[55,91,92],{"language":12,"class":57},[46,93,94],{"class":60},"class TestTimeLogger(unittest.TestCase):\n\n    def test_save_time(self):\n        \"\"\" Verify that the Epoch time is written to file\n        \"\"\"\n        with unittest.mock.patch(\"utime.time\", return_value=1234):\n            t = TimeLogger()\n            t.save_time()\n            with open(\"LAST_KNOWN_TIME\") as f:\n                self.assertEqual(\"1234\", f.read())",[23,96,97,98,101,102,105,106,108],{},"Now, when the ",[46,99,100],{},"save_time"," method gets the latest time from ",[46,103,104],{},"utime.time()",", the\nvalue will be patched to return ",[46,107,88],{},". That value will be written to a file,\nand our unit test will pass!",[110,111,113],"h2",{"id":112},"references","References",[115,116,117],"ol",{},[118,119,120],"li",{},[121,122,124,127],"a",{"href":123},"https:\u002F\u002Fdocs.python.org\u002F3\u002Flibrary\u002Funittest.html",[46,125,126],{},"unittest"," — Unit testing framework","Unit testing code for embedded systems can be challenging. While it's possible to leverage emulators, write sideeffect free code, or run tests on the hardware itself, it's often easiest to unit test the code on your personal computer with mocked hardware functionality.",2,1790648870600]