Last active
February 18, 2016 15:28
-
-
Save ViktorovEugene/e279575438a282124d2e to your computer and use it in GitHub Desktop.
Test module with examples and pitfails of using temporary files from ``tempfile`` standart library module.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Study python3's ``tempfile`` library. | |
""" | |
from __future__ import print_function | |
import os | |
import tempfile | |
import unittest | |
import sys | |
import subprocess | |
tested_module_content = """\ | |
import os | |
import tempfile | |
def emergency_program_stop(): | |
this_file_path = os.path.abspath(__file__) | |
containing_dir = os.path.dirname(this_file_path) | |
temp_file = tempfile.NamedTemporaryFile(prefix='test_tmp_1_', | |
suffix='.txt', | |
mode="w+", | |
dir=containing_dir) | |
if os.path.exists(temp_file.name): | |
print(temp_file.name, end='') | |
raise SystemError | |
else: | |
# Temporary file should be created for fair test, so we will | |
# print out really existed file name to make the test fail. | |
print(this_file_path, end='') | |
if __name__ == '__main__': | |
emergency_program_stop() | |
""" | |
class TestTempFile(unittest.TestCase): | |
""" | |
Test of some futures of the ``tempfile`` standard library module. | |
""" | |
def test_auto_deleting_when_emergency_close_program(self): | |
""" | |
Test to check that temp file is deleted even if an error was | |
occurred. | |
It creates temporary python module, that will create temporary file, | |
print it name and emergency stop by raising a SystemError. | |
If this file fail to create his own temporary file, it will print | |
his own name and the test will treat it like a fail. | |
""" | |
containing_dir = os.path.dirname(os.path.abspath(__file__)) | |
python_interpreter = sys.executable | |
temp_file = tempfile.NamedTemporaryFile(prefix='tested_module_', | |
suffix='.py', | |
mode="w+", | |
dir=containing_dir) | |
temp_file.write(tested_module_content) | |
temp_file.flush() | |
with subprocess.Popen( | |
(python_interpreter, temp_file.name), | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
) as proc: | |
tested_temp_file_name = proc.stdout.read() | |
self.assertNotEqual( | |
temp_file.name, | |
tested_temp_file_name, | |
"Fail because of just created temporary python module fail to " | |
"create his own temporary file and returned one's name." | |
) | |
self.assertFalse( | |
os.path.exists(tested_temp_file_name), | |
'File should be deleted!' | |
) | |
def test_make_and_access_the_temp_file(self): | |
""" | |
Test of behaviour NamedTemporaryFile() instance. | |
* Immediate creation on the file system. | |
* Predictable updating of the content. | |
""" | |
containing_dir = os.path.dirname(os.path.abspath(__file__)) | |
# Test of immediate creation of the temporary file. | |
temp_file = tempfile.NamedTemporaryFile(prefix='test_tmp_1_', | |
suffix='.txt', | |
mode="w+", | |
dir=containing_dir) | |
self.assertTrue( | |
os.path.exists(temp_file.name), | |
"Temp file does'nt exist after creating!" | |
) | |
# Test that file is not updating right after calling write() method. | |
with open(temp_file.name) as f_: | |
self.assertEqual( | |
f_.read(), | |
'', | |
'Nothing was written to the file, it should be empty now!' | |
) | |
written_string_1 = 'initial string' | |
temp_file.write(written_string_1) | |
with open(temp_file.name) as f_: | |
self.assertEqual( | |
f_.read(), | |
'', | |
'String was written, but not flushed, it should be still ' | |
'empty!' | |
) | |
# Test that file was updated after calling flush() method. | |
temp_file.flush() | |
with open(temp_file.name) as f_: | |
self.assertEqual( | |
f_.read(), | |
written_string_1, | |
'flush() method was called, so the file should be updated now' | |
) | |
# Updating after the calling seek() method. | |
written_string_2 = 'second string' | |
temp_file.write(written_string_2) | |
temp_file.seek(0) | |
with open(temp_file.name) as f_: | |
content = f_.read() | |
self.assertEqual( | |
content, | |
written_string_1 + written_string_2, | |
'seek() method was called, so the file should be updated now' | |
) | |
# Deleting the file after calling the close() method. | |
self.assertTrue( | |
os.path.exists(temp_file.name), | |
'File should be present on the file system now!' | |
) | |
temp_file.close() | |
self.assertFalse( | |
os.path.exists(temp_file.name), | |
'File object was closed, so the temp file is expected ' | |
'to be deleted now.' | |
) | |
def test_buggy_future_with_wrong_mode_value(self): | |
""" | |
When you give some wrong value to the ``mode`` argument | |
(i.e. ``mode='wr'``) the next error is occurred: | |
ValueError: must have exactly one of create/read/write/append mode | |
Which is a blunder of the particular developer, you need be more | |
careful, but "temporary" file are created on the disk anyway, and now | |
it becomes not so temporary as expected. | |
Because of error, program is interrupted, empty file remains on the | |
disk. | |
Temp file will not be deleted automatically, how it happens whilst | |
normaly finishing the program without running the ``close()`` method, | |
or when it will be stopped because of an expection. | |
""" | |
containing_dir = os.path.dirname(os.path.abspath(__file__)) | |
dir_content_before_fail = os.listdir(containing_dir) | |
with self.assertRaises(ValueError): | |
tempfile.NamedTemporaryFile(prefix='test_tmp_2_', | |
mode='wr', | |
dir=containing_dir) | |
dir_content_after_fail = os.listdir(containing_dir) | |
dir_content_diff = list( | |
set(dir_content_after_fail) - set(dir_content_before_fail) | |
) | |
self.addCleanup(os.remove, dir_content_diff.pop()) | |
self.assertNotEqual(dir_content_before_fail, dir_content_after_fail) | |
if __name__ == '__main__': | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment