2022-03-13に更新

Pythonのunittest実行時に、「ResourceWarning: unclosed file」が発生する場合の対処方法

Pythonでunittestを実行していた際に、「ResourceWarning: unclosed file」が出力されたので、その対処方法について、記載。

global logins
def log_setting(log_level):
    global logins
    home = '<ログファイルパス>'
    pid = os.getpid()

    # create logger
    logins = logging.getLogger(__name__)
    logins.setLevel(logging.DEBUG)

    # create File Handler
    fh = logging.FileHandler('{0}/log/log{1}.log'.format(home, pid))
    fh.setLevel(logging.INFO)

    # create Formatter
    fh_formatter = \
        logging.Formatter(
            '%(asctime)s - %(levelname)s - \
            %(filename)s - %(name)s - %(funcName)s - %(message)s')

    # set Formatter
    fh.setFormatter(fh_formatter)

    # add Handler
    logins.addHandler(fh)

    # test logging
    logins.info('logtest:addHandler') 

↑みたいな関数があり、unittest側からは下記でテストメソッド単位で呼び出したとする。

def setUp(self):
   logtest.log_setting(logging.DEBUG)`


def tearDown(self):
   logtest.logins.handlers = []

この場合、unittestを実行すると、ログファイル内に「ResourceWarning: unclosed file」が出力される。
理由はログファイルがクローズされていない状態で、ハンドラをクリアしているから。
ハンドラをクリアしている理由は、そうしないとテストメソッドの実行の都度、「log_setting」が呼び出されてハンドラが追加され、ログが重複して出力されてしまうから。

ログファイルをクローズする処理を入れればいいので、下記のようにする。

def tearDown(self):
   logtest.logins.handlers[0].close()
   logtest.logins.handlers = []

こうすると、ログファイルをクローズした後にハンドラをクリアするので、警告は出力されない。
ログも重複しない。

本当にいいのは、テスト対象側のプログラムを修正することだと思う。
ファイル出力しかしない想定であれば、addHandlerを使う必要はなく、下記で対応ができる。↓のほうがコード短いし、↑よりもいいかな。

```
def log_setting(log_level):
global logins
home = '/home/aoiro/work/logtest'
pid = os.getpid()

# create logger
logins = logging.getLogger(__name__)

log_format = \
    '%(asctime)s - {} - %(levelname)s - %(message)s'.format("tester")
logging.basicConfig(
    filename='{0}/log/log{1}.log'.format(home, pid),
    level=log_level, format=log_format)

```

ツイッターでシェア
みんなに共有、忘れないようにメモ

ao-iro

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント