我有以下文件(用于py.test编写):
# test_fuser.py
import subprocess
def fuser(filename):
return subprocess.check_output(['fuser', filename]).split()
def test_fuser_0(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
assert len(fuser(test_file.strpath)) == 0
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
assert len(fuser(test_file.strpath)) == 1
从命令行运行py.test
会产生:
$ py.test test_fuser.py
================================= test session starts ==================================
platform darwin -- Python 2.7.8 -- py-1.4.26 -- pytest-2.6.4
collected 2 items
test_fuser.py .F
======================================= FAILURES =======================================
_____________________________________ test_fuser_1 _____________________________________
tmpdir = local('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10')
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
> assert len(fuser(test_file.strpath)) == 1
E assert 2 == 1
E + where 2 = len(['71433', '71437'])
E + where ['71433', '71437'] = fuser('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt')
E + where '/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt' = local('/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt').strpath
test_fuser.py:18: AssertionError
--------------------------------- Captured stderr call ---------------------------------
/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-131/test_fuser_10/test.txt:
========================= 1 failed, 1 passed in 10.32 seconds =========================
这是不寻常的,因为人们会期望fuser()
返回一个PID,而不是两个,因为只有对open()
的调用才能打开文件。
为了进一步调查,我在调用test_fuser_1()
之前fuser()
设置了一个断点,在open()
的上下文中,然后重新进行测试。
def test_fuser_1(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('')
with open(test_file.strpath, 'w'):
pytest.set_trace()
assert len(fuser(test_file.strpath)) == 1
在断点处,我抓住了临时文件的名称:
>>>>>>>>>>>>>>>>>>>>>>> PDB set_trace (IO-capturing turned off) >>>>>>>>>>>>>>>>>>>>>>>>
> /Users/caesarbautista/Desktop/test_fuser.py(21)test_fuser_1()
-> assert len(fuser(test_file.strpath)) == 1
(Pdb) test_file.strpath
'/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt'
然后,从另一个终端呼叫fuser
我看到了一个PID。
$ fuser /private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt
/private/var/folders/mx/h4mybl9x1p52wbj2hnvk1lgh0000gn/T/pytest-132/test_fuser_10/test.txt: 71516
这似乎表明子流程负责第二个PID,但我不确定为什么会这样,并且已经没有关于如何进一步调查这个问题的想法。知道第二个PID的来源吗?
我虽然也许py.test可能与此相关,所以我重写了测试用于鼻子:
def test_fuser_0():
with open('test.txt', 'w') as fp:
fp.write('')
pids = fuser('test.txt')
assert len(pids) == 0, pids
def test_fuser_1():
with open('test.txt', 'w') as fp:
fp.write('')
pids = fuser('test.txt')
assert len(pids) == 1, pids
但是用鼻子跑它们会导致同样的失败:
$ nosetests --tests=test_fuser.py
test.txt:
.test.txt:
F
======================================================================
FAIL: test_fuser.test_fuser_1
----------------------------------------------------------------------
Traceback (most recent call last):
File "/opt/boxen/homebrew/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/caesarbautista/Desktop/test_fuser.py", line 34, in test_fuser_1
assert len(pids) == 1, pids
AssertionError: ['71865', '71869']
----------------------------------------------------------------------
Ran 2 tests in 11.026s
FAILED (failures=1