简体   繁体   English

Python:如何在我的测试套件中制作临时文件?

[英]Python: How do I make temporary files in my test suite?

(I'm using Python 2.6 and nose .) (我使用的是 Python 2.6 和nose 。)

I'm writing tests for my Python app.我正在为我的 Python 应用程序编写测试。 I want one test to open a new file, close it, and then delete it.我想要一个测试来打开一个新文件,关闭它,然后删除它。 Naturally, I prefer that this will happen inside a temporary directory, because I don't want to trash the user's filesystem.自然,我更喜欢这将发生在临时目录中,因为我不想破坏用户的文件系统。 And, it needs to be cross-OS.而且,它需要是跨操作系统的。

How do I do it?我该怎么做?

FWIW using py.test you can write: FWIW 使用 py.test 你可以写:

def test_function(tmpdir):
    # tmpdir is a unique-per-test-function invocation temporary directory

Each test function using the "tmpdir" function argument will get a clean empty directory, created as a sub directory of "/tmp/pytest-NUM" (linux, win32 has different path) where NUM is increased for each test run.每个使用“tmpdir”函数参数的测试函数都会得到一个干净的空目录,创建为“/tmp/pytest-NUM”的子目录(linux,win32有不同的路径),每次测试运行时NUM增加。 The last three directories are kept to ease inspection and older ones are automatically deleted.保留最后三个目录以方便检查,旧目录将被自动删除。 You can also set the base temp directory with py.test --basetemp=mytmpdir .您还可以使用py.test --basetemp=mytmpdir设置基本临时目录。

The tmpdir object is a py.path.local object which can also use like this: tmpdir 对象是一个 py.path.local 对象,它也可以像这样使用:

sub = tmpdir.mkdir("sub")
sub.join("testfile.txt").write("content")

But it's also fine to just convert it to a "string" path:但也可以将其转换为“字符串”路径:

tmpdir = str(tmpdir)

查看标准库中的tempfile模块 - 应该是您所需要的。

Instead of using tempfile directly I suggest using a context manager wrapper for it - the context manager takes care of removing the directory in all cases (success/failure/exception) with basically no boilerplate.我建议使用上下文管理器包装器代替直接使用临时文件- 上下文管理器负责在所有情况下(成功/失败/异常)删除目录,基本上没有样板。

Here is how it can be used:以下是它的使用方法:

from tempfile import TempDir    # "tempfile" is a module in the standard library
...

# in some test:
with TempDir() as d:
    temp_file_name = os.path.join(d.name, 'your_temp_file.name')
    # create file...
    # ...
    # asserts...

I have been using a home grown version (the implementation is rather short - under 20 lines) up to the point, when I needed to use it somewhere else as well, so I looked around if there is a package ready to install, and indeed there is: tempfile到目前为止,当我还需要在其他地方使用它时,我一直在使用自己开发的版本(实现相当短 - 不到 20 行),所以我环顾四周是否有准备安装的软件包,确实有:临时文件


Note: the code snippet above is a little out-dated.注意:上面的代码片段有点过时了。

To create a temporary file with custom content for your tests you can use this class:要为您的测试创建带有自定义内容的临时文件,您可以使用此类:

import os, tempfile

class TestFileContent:                                                                                                  
    def __init__(self, content):                                                                                        

        self.file = tempfile.NamedTemporaryFile(mode='w', delete=False)                                                 

        with self.file as f:                                                                                            
            f.write(content)                                                                                            

    @property                                                                                                           
    def filename(self):                                                                                                 
        return self.file.name                                                                                           

    def __enter__(self):                                                                                                
        return self                                                                                                     

    def __exit__(self, type, value, traceback):                                                                         
        os.unlink(self.filename)                                                                                        

This class will create a temporary file, write your content inside it and then close the file.此类将创建一个临时文件,在其中写入您的内容,然后关闭该文件。 You use it inside a with statement to ensure that the file is deleted after usage like this:您在with语句中使用它以确保文件在使用后被删除,如下所示:

    with TestFileContent(
'''Hello, world
'''
    ) as test_file:

        # Here, a temporary file has been created in the file named test_file.filename with the specified content
        # This file will be deleted once you leave the with block

For people who come across this in the future, but also refuse to use pytest for some reason:对于以后遇到这种情况,但又因某种原因拒绝使用 pytest 的人:

I wrote tempcase , a small library which provides a unittest.TestCase subclass with convenience methods for handling temporary directories.我编写了tempcase ,这是一个小型库,它提供了一个unittest.TestCase子类,其中包含处理临时目录的便捷方法。 No directories are created until you request the path to them, and they are namespaced to the project, TestCase class, timestamp, and test method.在您请求目录的路径之前,不会创建任何目录,并且它们被命名为项目、TestCase 类、时间戳和测试方法。 They are automatically cleaned up afterwards.之后它们会自动清理。 You can disable cleanup to inspect the output by setting a property.您可以通过设置属性来禁用清理以检查输出。

There is also a decorator which can be applied to individual test cases, if you're porting code gradually.如果您正在逐步移植代码,还有一个装饰器可以应用于单个测试用例。

Python 3.2+蟒蛇 3.2+

tempfile library TemporaryDirectory() hand in hand with context manager with is the way to go. tempfileTemporaryDirectory()与上下文管理器with是要走的路。 However DO note, that this PHYSICALLY creates the temporary directory (in some OS dir for temp. files (on linux probably /tmp )) - files there would actually use the storage device/disk - it may not be a problem for you, but it is something to consider when that usage would be heavy on eg a paid service (for alternatives see the the end of this answer post) .但是请注意,这在物理上创建了临时目录(在某些操作系统目录中用于临时文件(在 linux 上可能是/tmp ))-那里的文件实际上会使用存储设备/磁盘-对您来说可能不是问题,但是当这种使用量在例如付费服务上很重时需要考虑(有关替代方案,请参阅本回答帖子的结尾)

I also suggest using os library os.path.join() to put stuff there and to use it in general to avoid cross-platform bugs regarding \\ or / paths.我还建议使用osos.path.join()将东西放在那里,并在一般情况使用它来避免关于\\/路径的跨平台错误。

Note: When used without context manager with you get object of TemporaryDirectory class and retrieve the name with .name , when used in context manager you get the name string assigned to your as variable.注意:当在没有上下文管理器的情况下with您将获得TemporaryDirectory类的对象并使用.name检索名称,当在上下文管理器中使用时,您将获得分配给as变量的名称字符串

TL;DR : The code TL;DR:代码

import tempfile
import os
with tempfile.TemporaryDirectory() as tempdir:
  # you can e.g. create a file here:
  tmpfilepath = os.path.join(tempdir, 'someFileInTmpDir.txt')
  with open(tmpfilepath, 'w') as tmpfile:
    tmpfile.write("something")

Change the temporary directory location更改临时目录位置

Here you must a dig a bit deeper, since documentation is kind of fuzzy here: it does not document its arguments at all, but, it sends you to mkdtemp() which should use same rules and there it sends you to mkstemp() where you can finally sort of ensure yourself, that the dir argument is used to override the default directory placement.在这里,你必须一挖一个深一点,因为文件是一种模糊的位置:它不会在所有记录它的参数,但是,它向您发送mkdtemp()应使用相同的规则,有其发送你mkstemp() ,其中您最终可以确保自己使用dir参数来覆盖默认目录位置。

Do you want to completely fake the I/O (input/output) operations on your filesystem?您想完全伪造文件系统上的 I/O(输入/输出)操作吗?

You can try using pyfakefs as suggested in this answer: https://stackoverflow.com/a/46817032/1835470您可以尝试按照此答案中的建议使用pyfakefshttps : //stackoverflow.com/a/46817032/1835470

Which one is better?哪一个更好? faking filesystem or a physical temporary dir?伪造文件系统还是物理临时目录?

Depends on the usage - usually a combination can be a good compromise - test each filesystem operation on its own with real directories and files so you know it really works, but for your custom heavy-usage stuff use faking/mocking filesystem operations :) Also for testing permissions coming from within the OS for example - it would probably be better to use the physical way.取决于使用情况 - 通常组合可以是一个很好的折衷方案 - 使用真实的目录和文件单独测试每个文件系统操作,以便您知道它确实有效,但是对于您自定义的大量使用的东西,请使用伪造/模拟文件系统操作 :) 另外例如,用于测试来自操作系统内部的权限 - 使用物理方式可能会更好。
You must always evaluate beforehand how much performance and durability is available to you and if it makes sense to make an extra testing or not.您必须始终事先评估您可以获得多少性能和耐用性,以及进行额外测试是否有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在python unittest中创建测试套件 - How do i create a test Suite in python unittest 如何在套件中的测试类中共享一个webdriver实例?我使用Selenium2和Python - How can I share one webdriver instance in my test classes in the suite? I use Selenium2 and Python 如何制作较小的临时文件? - How can I make smaller temporary files? 如何使用测试文件和预期的 output 文件测试 Python - How do I test Python with test files and expected output files 使用Python unittest,如何创建和使用“可返回测试套件的可调用对象”? - With Python unittest, how do I create and use a “callable object that returns a test suite”? 如何使用单元测试在 Python 的单个测试套件中运行多个类? - How do I run multiple Classes in a single test suite in Python using unit testing? 如何运行python测试套件? - How to run python test suite? 如何在测试套件中找到未使用的步骤定义? - How can I find unused step definitions in my test suite? 如何使 Python 临时文件和文件夹在定义的天数内持久化? - How to make Python temporary files and folders persistent for a defined period of days? 使用 Python-playwright,如何在不将其保存到磁盘或使用临时文件的情况下制作屏幕截图? - Using Python-playwright, how do I make a screenshot without saving it to disk or using a temporary file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM