Воспроизводимые случайные тесты - PullRequest
0 голосов
/ 27 июня 2019

Я недавно натолкнулся на следующую часть документации .Беглый поиск показал только гист .Поэтому я решил воплотить эти идеи в жизнь.

Первая из них далеко не используется как есть.Второй слишком многословный и не работает в случае сбоя (failureException должен быть класс , соответствующий метод может быть закомментирован).

Прежде чем я опишумои решения, позвольте мне задать вопросы.1. Я что-то не так делаю?Задача такого рода, должно быть, была упрощена давным-давно.По крайней мере, в моей книге. 2. Есть ли способ улучшить мои решения?

Первый (ветвь factory-boy-state) хранит состояние случайных генераторов в файлах, которые позже могут бытьиспользуется для передачи состояния в тесты:

class MyTestRunner(DiscoverRunner):
    def setup_test_environment(self):
        self.handle_rnd_state(faker.generator.random, 'faker.state',
            'FAKER_RANDOM_STATE')
        self.handle_rnd_state(factory.random.randgen, 'factory.state',
            'FACTORY_RANDOM_STATE')
        super().setup_test_environment()

    def handle_rnd_state(self, rnd, fname, env_var):
        state = self.retrieve_rnd_state(fname, env_var)
        if state:
            rnd.setstate(state)
        else:
            self.store_rnd_state(fname, rnd.getstate())

    def retrieve_rnd_state(self, fname, env_var):
        state = os.environ.get(env_var)
        return pickle.loads(b64decode(state.encode('ascii'))) if state else None

    def store_rnd_state(self, fname, state):
        encoded_state = b64encode(pickle.dumps(state))
        with open(fname, 'w') as f:
            f.write(encoded_state.decode('ascii'))

Использование:

$ ./manage.py test --testrunner p1.tests.MyTestRunner
$ FAKER_RANDOM_STATE=`cat faker.state` FACTORY_RANDOM_STATE=`cat factory.state` ./manage.py test --testrunner p1.tests.MyTestRunner

Еще один (ветвь factory-boy-seed) отбирает случайные генераторы, но затравкуможет быть переопределено через переменную окружения:

class MyTestRunner(DiscoverRunner):
    def setup_test_environment(self):
        seed = os.environ.get('FACTORY_SEED')
        if seed:
            seed = seed.encode('ascii')
        if not seed:
            seed = b64encode(os.urandom(16))
        print('-- seed: %s' % seed.decode('ascii'))
        factory.random.reseed_random(seed)
        super().setup_test_environment()

Использование:

$ ./manage.py test --testrunner p1.tests.MyTestRunner
$ FACTORY_SEED=IPnHCxdWehAxz6ctbNvyPQ== ./manage.py test --testrunner p1.tests.MyTestRunner

Бегун теста может быть установлен в настройках .

...