我有以下文件(编写用于 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