Summer Sale! All accounts are 50% off this week.

dmag's avatar
Level 6

Avoid duplicate primary key error in parallel testing

I have a model "Building" where the primary key is an id set manually, it's hard-coded in enum.

So, the model's factory looks like this:

class BuildingFactory extends Factory
{
    public function definition(): array
    {
        return [
            'Id' => BuildingEnum::getRendomValue(),
            ... 
        ];
    }
}

There're five entries in BuildingEnum, so in parallel testing I get many "duplicate primary key violation" error.

How do I avoid that? How can I make so that factory used existing next id if current one existed in db?

Db transaction is being used in tests.

0 likes
5 replies
Snapey's avatar

why on earth would you do this for a primary key?

dmag's avatar
Level 6

@Snapey well, I can do it for another column, but it will have to be unique, and eventually it will run into the same error

dmag's avatar
Level 6

@Snapey the value should come from the enum, and enum has five entries, so the enum has values 1, 2, 3, 4, 5. So I need to work with these values and somehow make parallel testing not to run into the "duplicate" error.

Snapey's avatar

@dmag What little I know of your app shows a number of code smells

  • Why would you have a model and table with enum in the name, this is not what is expected of the concept of enum and will be confusing to anyone else looking at the code
  • having a table whose primary key has to be supplied by a separate model is a smell
  • having a function `getRendomValue (ignore the typo for a moment) that can only return the values 1 to 5 seems ill conceived.
  • clearly a 'random' range of 1 to 5 is not going to allow parallel testing of more than 1 or two tests

Show your code for generating random 1 to 5 entry? I'm sure its not atomic.

Please or to participate in this conversation.