在介绍我面临的问题之前,我将尝试为您提供一些背景信息。我有一个名为 Actuator 的组件,它依赖于模块 pymodbus。当我测试这个组件时,我使用基于 pymodbus 的 modbus TCP 服务器以最简单的方式进行了测试。基本上,我在一个新的 shell 和我的应用程序中将服务器作为 python 脚本(正是这个:https ://pymodbus.readthedocs.io/en/latest/source/example/synchronous_server.html )运行,其中包括执行器,在另一个外壳中。一切都像魅力一样。
我现在想做的是为执行器编写一个单元测试,使用 python unittest 和 pymodbus 并尝试自动化我之前所做的事情。我的想法是在 setUp 方法中将 modbus 服务器作为子进程运行(考虑到我不需要服务器的输出),在我的测试套件中使用它,然后在 tearDown 方法中终止它,如下所示:
class TestActuator(unittest.TestCase):
"""Class to test the actuator module"""
def setUp(self):
"""
Setup a real Actuator object with a modbus server running
in background for tests
"""
modbus_server_path = "path/to/modbus_server.py"
cmd = "python3 {}".format(modbus_server_path)
self.modbus_server = Popen(cmd.split(), shell=False, stdout=DEVNULL, stderr=DEVNULL)
# other stuff
def test1(self):
def test2(self):
def tearDown(self):
"""Cleanup everything before exiting"""
self.modbus_server.terminate()
if __name__ == '__main__':
unittest.main()
不幸的是,这似乎比我预期的更具挑战性。我从 stackoverflow 上的其他主题尝试的一切都失败了:
- 使用 Popen.kill() 而不是终止。我还尝试在杀死或终止后“删除”或使用 os.kill(self.modbus_server.pid, SIGTERM) 代替。
- 在 Popen 命令中添加或更改 args,例如 shell=True 而不是 shell=False 和 close_fds=True。
- 使用子进程 Popen 的其他变体,例如 check_output、run、call 等...
- 使用 os.spawnl 而不是子进程 Popen。
这些都不起作用。大多数时候发生的情况是服务器无法正常启动,因此所有其他测试都失败并且 modbus_server 进程没有终止(我必须手动终止它)。
你有什么主意吗?谢谢你。