如何解决如何在python单元测试中对pymodbus tcp服务器进行子处理,并在执行完所有测试后将其终止?
在介绍我面临的问题之前,我将尝试为您提供一些背景信息。 我有一个名为Actuator的组件,它依赖于pymodbus模块。在测试此组件时,我使用基于pymodbus的modbus TCP服务器以最简单的方式完成了该操作。基本上,我在新的外壳中将服务器作为python脚本(确切地说是https://pymodbus.readthedocs.io/en/latest/source/example/synchronous_server.html)运行,而我的应用程序(包括Actuator)在另一个外壳中运行。一切都像魅力一样。
我现在想做的是使用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进程没有终止(我必须手动将其杀死)。
你有什么主意吗?谢谢。
解决方法
我将分享我如何解决问题以及到目前为止所学到的知识:
关于尝试使Modbus TCP服务器在运行测试时作为子进程运行,您需要更改一些内容以使其正常运行。
第一件事是使用“ setUpClass”和“ tearDownClass”而不是setUp和tearDown(您也可以同时使用它们,但是在我的情况下,我需要前两个),以便您可以运行服务器的设置对于所有测试套件,仅一次,而不是在每个测试用例之前和之后。不幸的是,setUpClass和tearDownClass的语法不是那么简单。这个答案对我有很大帮助:Run setUp only once for a set of automated tests
第二件事是关于TCP套接字的。基本上,我想确保我的测试正常运行,并连续运行几次。因此,有时候一切正常,而其他时候却失败了。一段时间后,我发现如果我在不等待至少一分钟再重试的情况下运行测试,它们将失败。 这是由于在我的情况下,modbus服务器在本地地址和端口5020上绑定的TCP套接字的TIME_WAIT(默认设置为60秒)。如果要在以前使用的相同TCP地址和端口上重新绑定套接字,则必须等待60秒钟。该答案有助于理解为什么发生这种情况:Setting TIME_WAIT TCP
在弄清楚如何使所有这些东西协同工作之后,我决定使用模拟程序,因为我的解决方案似乎太笨拙了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。