Python2.7子进程Popen返回None

Python2.7子进程Popen返回None,python,python-2.7,subprocess,pytest,popen,Python,Python 2.7,Subprocess,Pytest,Popen,我目前正在使用python 2.7中的pytest进行一组集成测试,这些测试执行以下操作: 1) 在本地计算机的后台运行服务器二进制文件 2) 向服务器发送请求并验证结果 3) 终止后台服务器进程 一切似乎都很正常,只是我无法终止计算机上运行的服务器进程。尽管它继续在我的计算机上运行,Python似乎已经忘记了它;我的Popen对象是None AttributeError:“非类型”对象没有属性“终止” 你有没有想过是什么原因造成的?我错过了什么明显的东西吗 import time import

我目前正在使用python 2.7中的pytest进行一组集成测试,这些测试执行以下操作:

1) 在本地计算机的后台运行服务器二进制文件

2) 向服务器发送请求并验证结果

3) 终止后台服务器进程

一切似乎都很正常,只是我无法终止计算机上运行的服务器进程。尽管它继续在我的计算机上运行,Python似乎已经忘记了它;我的
Popen
对象是
None

AttributeError:“非类型”对象没有属性“终止”

你有没有想过是什么原因造成的?我错过了什么明显的东西吗

import time
import subprocess

server_background_process_pipe = None

def setup_module():
    # Start the test server in the background
    cmd = 'bin/my_server --key1='+value1+' --key2='+value2+' &' # The '&' tells my bin to run in the background
    server_background_process_pipe = subprocess.Popen(cmd, shell=True,stderr=subprocess.STDOUT)
    print(server_background_process_pipe) # prints '<subprocess.Popen object at 0x10aabd250>'
    time.sleep(1) # Wait for the server to be ready

def test_basic_get_request():
    print(server_background_process_pipe) # prints 'None'
    response = send_request_to_server() 
    fail_if_not_as_expected(response) # Response is exactly as expected

def teardown_module():
    # kill the server that was launched in setup_module to serve requests in the tests
    # AttributeError: 'NoneType' object has no attribute 'terminate'
    server_background_process_pipe.terminate()
导入时间
导入子流程
服务器\后台\进程\管道=无
def设置_模块():
#在后台启动测试服务器
cmd='bin/my_server--key1='+value1+'--key2='+value2+'&'#&'告诉我的bin在后台运行
server\u background\u process\u pipe=subprocess.Popen(cmd,shell=True,stderr=subprocess.STDOUT)
打印(服务器\后台\流程\管道)\打印“
时间。睡眠(1)#等待服务器准备就绪
def test_basic_get_request():
打印(服务器\后台\流程\管道)\打印“无”
响应=将请求发送到服务器()
如果不符合预期,则失败(响应)#响应与预期完全一致
def拆卸_模块():
#杀死在setup_模块中启动的服务器,以服务测试中的请求
#AttributeError:“非类型”对象没有属性“终止”
服务器\后台\进程\管道。终止()
额外信息:

即使服务器进程仍在运行,它仍然是
None
。测试运行时,它是
None
。它在测试套件完成后运行很长时间。如果我重新运行测试,我会在控制台中收到一条消息,说明我的服务器部署失败,因为它已经在运行。测试仍然通过,因为它们从上一次执行向服务器发送请求

由于服务器需要在后台运行,因此我直接使用subprocess.Popen构造函数,而不是中的一种方便方法,如
check\u output

def setup_module():
    …
    server_background_process_pipe = subprocess.Popen(…)
server\u background\u process\u pipe
是一个局部变量。它从未分配给全局
server\u background\u process\u pipe
,因此全局
server\u background\u process\u pipe
始终为
None
,并且代码

def teardown_module():
    server_background_process_pipe.terminate()
尝试从“无”获取属性
terminate

您需要对全局变量进行初始赋值:

def setup_module():
    …
    global server_background_process_pipe
    server_background_process_pipe = subprocess.Popen(…)

只能将
None
分配给模块全局变量
server\u background\u process\u pipe
。您可以在函数中使用分配给
server\u background\u process\u pipe
global
语句,但最好首先避免全局可变状态。将
global server\u background\u process\u pipe
添加到
def setup\u module()的顶部:
或者更好,添加
return server\u background\u process\u pipe
,让调用者执行
server\u background\u process\u pipe=setup\u module()
(理想情况下,将其传递给其他方法)。或者,如果这意味着像一个对象一样在调用之间保持某种状态,定义一个
并将其存储为
self.server\u background\u process\u pipe
。伙计,这太尴尬了!感谢所有的反馈!我最喜欢你的最后一个主意,abarnet,我想我会同意的