web-dev-qa-db-ja.com

Python:テストスイートで一時ファイルを作成するにはどうすればよいですか?

(私はPython 2.6およびnoseを使用しています。)

Pythonアプリのテストを作成しています。1つのテストで新しいファイルを開き、閉じてから削除する必要があります。当然、これは一時ディレクトリ内で行われることをお勧めします。ユーザーのファイルシステムをゴミ箱に捨てたくないからです。そして、クロスOSである必要があります。

どうすればいいのですか?

26
Ram Rachum

標準ライブラリの tempfile モジュールを参照してください-必要なのはこれだけです。

17
bgporter

Py.testを使用したFWIWは、次のように記述できます。

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

「tmpdir」関数の引数を使用する各テスト関数は、「/ tmp/pytest-NUM」(Linux、win32のパスは異なります)のサブディレクトリとして作成されたクリーンな空のディレクトリを取得します。NUMはテストの実行ごとに増加します。最後の3つのディレクトリは検査を容易にするために保持され、古いディレクトリは自動的に削除されます。 py.test --basetemp=mytmpdirを使用してベース一時ディレクトリを設定することもできます。

Tmpdirオブジェクトはpy.path.localオブジェクトであり、次のように使用することもできます。

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

ただし、「文字列」パスに変換するだけでも問題ありません。

tmpdir = str(tmpdir)
27
hpk42

tempfile を直接使用する代わりに、コンテキストマネージャーラッパーを使用することをお勧めします-コンテキストマネージャーは、基本的に定型文なしで、すべての場合(成功/失敗/例外)にディレクトリを削除します。

使用方法は次のとおりです。

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...

私は、他の場所でも使用する必要がある時点まで、自家製バージョン(実装はかなり短い-20行未満)を使用していたので、インストールする準備ができているパッケージがあるかどうかを調べました。あります: tempfile


注:上記のコードスニペットは少し古くなっています。

4

テスト用のカスタムコンテンツを含む一時ファイルを作成するには、次のクラスを使用できます。

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)                                                                                        

このクラスは一時ファイルを作成し、その中にコンテンツを書き込んでからファイルを閉じます。 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
2
leszek.hanusz

将来これに遭遇するが、何らかの理由でpytestの使用を拒否する人のために:

tempcase を作成しました。これは、一時ディレクトリを処理するための便利なメソッドを備えたunittest.TestCaseサブクラスを提供する小さなライブラリです。ディレクトリへのパスを要求するまでディレクトリは作成されず、プロジェクト、TestCaseクラス、タイムスタンプ、およびテストメソッドに名前空間が付けられます。その後、自動的にクリーンアップされます。プロパティを設定することにより、クリーンアップを無効にして出力を検査できます。

コードを段階的に移植する場合は、個々のテストケースに適用できるデコレータもあります。

1
Chris L. Barnes