Как использовать Python для создания набора файлов на диске для тестирования? - PullRequest
2 голосов
/ 16 марта 2010

Я ищу способ создания дерева тестовых файлов для модульного тестирования инструмента упаковки. По сути, я хочу создать некоторые общие структуры файловой системы - каталоги, вложенные каталоги, символические ссылки в выбранном дереве, символические ссылки вне дерева и т. Д.

В идеале я хочу сделать это с как можно меньшим количеством шаблонов. Конечно, я мог бы написать от руки набор файлов, которые хочу увидеть, но я думаю, что кто-то должен где-то автоматизировать это для набора тестов. Есть предложения?

Ответы [ 2 ]

1 голос
/ 16 марта 2010

Я делаю такие вещи для тестирования создания пользователей Unix и копий домашних каталогов. Предложение Zip является хорошим.

Я лично храню две структуры каталогов - одна является источником, а другая становится структурой тестирования. Я просто синхронизирую источник с пунктом назначения через shutil.copytree как часть настройки теста.

Это позволяет легко изменять структуру теста на лету (и не нужно расстегивать молнию).

1 голос
/ 16 марта 2010

Каким образом?

Вы можете написать простой формат для определения базовой файловой структуры, используя вложенные словари:

## if you saved this as tree.py
## you could use it by doing:
# from tree import *
## then following the examples at the bottom of this file

import os, shutil, time

class Node:
    def __init__(self, name):
        self.name = name
        self.parent = None

    def setParent(self, parent):
        self.parent = parent

    def resolve(self):
        if self.parent: assert self.parent.exists()
        self.create()

    def exists(self):
        if os.path.exists(self.getPath()):
            return True
        else:
            return False

    def getPath(self): # you can nest things in symlinks
        if self.parent:
            return os.path.join(self.parent.getPath(), self.name)
        else:
            return self.name

    def create(self):
        raise NotImplemented, 'you must subclass node with your file type'

    def __repr__(self):
        return '<Node: %s>' % self.name

class Symlink(Node):
    def __init__(self, target, name):
        self.name = name
        self.target = target
        self.parent = None

    def create(self, basePath=None):
        os.symlink(self.target, self.getFilePath())

        assert 'symlink' in dir(os), "tried to create a symlink, but operating system doesn't support it"

class Folder(Node):
    def create(self):
        ## swap os.mkdir() for os.makedirs() if you want parent
        ## directories to be created if they don't already exist

        # os.makedirs(self.getPath()
        os.mkdir(self.getPath())

class File(Node):
    def __init__(self, name, contents=''):
        self.name = name
        self.contents = contents
        self.parent = None

    def create(self):
        f = open(self.getPath(), 'wb')
        f.write(self.contents)
        f.close()

def createAll(tree, parent=None):
    for node in tree:
        next = None
        if type(tree) == dict:
            if tree[node]:
                next = tree[node]

        if type(node) in (str, unicode):
            # coerce string to folder
            node = Folder(node)

        if parent:
            node.setParent(parent)

        node.resolve()
        if next: createAll(next, node)

if __name__ == '__main__':

    for name in ('src', 'src2', 'src3'):
        if os.path.exists(name):
            shutil.rmtree(name)

    time.sleep(0.1) # give it time to delete, took a second in one of my tests and denied access to creation

    empty = None # probably better than using None syntactically to indicate closed nodes of the tree

    test = {
        Folder('src'): {
            # if you *know* your folder won't contain any more levels, you can use a list instead of a dict
            # which means you don't need to specify None as the value for the folder key
            Folder('test'): [
                Symlink('..', 'recursive'),
                Symlink('..', 'still recursive'),
                Symlink('..', 'another recursion'),
            ],
            Folder('whee'): {
                Folder('nested'): {
                    Folder('nested'): {
                        Folder('done'): empty,
                        Symlink('recursive', '..'): empty,
                    }
                }
            }
        }
    }

    # the same structure expressed in a cleaner way, made possible by coercing strings to folder nodes:
    test2 = {
        'src2': {
            File('blank'): empty,
            File('whee.txt', 'this file is named whee.txt'): empty,
            # see above comment about using list as a container
            'test': [
                Symlink('..', 'recursive'),
                Symlink('..', 'still recursive'),
                Symlink('..', 'another recursion'),
            ],
            'whee': {
                'nested': {
                    'nested': {
                        'done': empty,
                        Symlink('..', 'recursive'): empty,
                    }
                }
            }
        }
    }

    test3 = {
        'src2': {
            File('blank'): empty,
            File('whee.txt', 'this file is named whee.txt'): empty,
            # see above comment about using list as a container
            'test': [
                File('file1.txt', 'poor substitute for a symlink'),
                File('file2.txt', 'I wish I could be a symlink'),
                File('file3.txt', "I'm hungry"),
            ],
            'nest': {
                'nested': {
                    'nested': {
                        'done': empty,
                        File('rawr.txt', 'I like pie.'): empty,
                    }
                }
            }
        }
    }

    if 'symlink' in dir(os): # these tests are no good if the OS doesn't support symlinks
        createAll(test)
        createAll(test2)

    createAll(test3)

Вы также можете сжать нужные файлы и сделать так, чтобы скрипт распаковывал их при запуске.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...