Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seeding the random generator for tests

I made it work using factory-boy's get_random_state/set_random_state, although it wasn't easy. And the biggest downside is that the values are big. So the thing that comes to mind is to write it to a file. But then if I accidentally run the tests not telling it to seed from the file, the value is lost. Now that I think about it, I can display the value too (think tee). But still I'd like to reduce it to 4-5 digits.

My idea is as follows. Normally when you run tests it somewhere says, "seed: 4215." Then to reproduce the same result I've got to do SEED=4215 ./manage.py test or something.

I did some experiments with factory-boy, but then I realized that I can't achieve this even with the random module itself. I tried different ideas. All of them failed so far. The simplest is this:

import random
import os
if os.getenv('A'):
    random.seed(os.getenv('A'))
else:
    seed = random.randint(0, 1000)
    random.seed(seed)
    print('seed: {}'.format(seed))
print(random.random())
print(random.random())
/app $ A= python a.py
seed: 62
0.9279915658776743
0.17302689004804395

/app $ A=62 python a.py
0.461603098412836
0.7402019819205794

Why do the results differ? And how to make them equal?

like image 764
x-yuri Avatar asked Jan 30 '26 05:01

x-yuri


1 Answers

Currently your types are different:

if os.getenv('A'):
    random.seed(os.getenv('A'))
else:
    seed = random.randint(0, 1000)
    random.seed(seed)
    print('seed: {}'.format(seed))

In the first case, you have a str and in the second an int. You can fix this by casting an int in the first case:

random.seed(int(os.getenv("A")))

I'm also not entirely following your need to seed random directly; I think with Factory Boy you can use factory.random.reseed_random (source).

like image 88
Alex Watt Avatar answered Feb 01 '26 20:02

Alex Watt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!