Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Certain TypeInferenceTestCase assert types take forever in PHPUnit 11 #10757

Closed
BladeMF opened this issue Mar 19, 2024 · 19 comments
Closed

Certain TypeInferenceTestCase assert types take forever in PHPUnit 11 #10757

BladeMF opened this issue Mar 19, 2024 · 19 comments

Comments

@BladeMF
Copy link

BladeMF commented Mar 19, 2024

Bug report

Preface: I know it is not a bug, but it is still a problem.

I upgraded today to PHPUnit 11. I have an extension that provides the return types of $this->prophesize(...) expressions which has test cases. One of the test cases - this one...

	public function with_static(): void
	{
		assertType(
			ObjectProphecy::class.'<static('.__CLASS__.')>',
			$this->prophesize(static::class)
		);
	}

... causes serveral minutes delay in test execution. I traced it down to vendor/phpunit/phpunit/src/Event/Value/Test/TestMethodBuilder.php file and the statement on line 73...

            $testData[] = DataFromDataProvider::from(
                $dataSetName,
                $exporter->export($testCase->providedData()),
                $testCase->dataSetAsStringWithData(),
            );

... and namely this bit - $exporter->export($testCase->providedData()),. I haven't looked at the specific data structure that is passed by gatherAssertTypes for that test, but it is possibly so huge that the phpunit exporter is not able to deal with it. Frankly I am not sure why they are trying to export so early the whole data, but it is out of my control.

One possible workaround is to rework the test like this...

	// #[DataProvider('_provideDataFileAsserts')]
	public function test_type_inference(
		// string $assertType,
		// string $file,
		// ...$args
	): void {
		foreach (self::gatherAssertTypes(__DIR__.'/Fixtures/ProphesizeFixture.php') as $args) {
			$this->assertFileAsserts(..$args);
		}
		// $this->assertFileAsserts($assertType, $file, ...$args);
	}

... and that works, but I thought you'd want to know.

Code snippet that reproduces the problem

No response

Expected output

Not a bug really.

Did PHPStan help you today? Did it make you happy in any way?

Every day. I really like it, it makes me happy.

Copy link

mergeable bot commented Mar 19, 2024

This bug report is missing a link to reproduction at phpstan.org/try.

It will most likely be closed after manual review.

@staabm
Copy link
Contributor

staabm commented Mar 19, 2024

Could you provide a repo with a reproducer ?

@BladeMF
Copy link
Author

BladeMF commented Mar 20, 2024

If needed, sure.

@BladeMF
Copy link
Author

BladeMF commented Mar 20, 2024

There is the repo. Interestingly, it turns out to be more complicated - if I leave just the test case I mentioned, it is not slow. So it seems to be related to all the tests being in the same place. Just do composer install and run phpunit. I takes a good 5 minutes or so.

@staabm
Copy link
Contributor

staabm commented Mar 20, 2024

I will have a look when time allows. thank you

@ondrejmirtes
Copy link
Member

Looks like PHPUnit 11 does something suboptiomal with data providers again. On PHPUnit 10 it's instant.

@BladeMF
Copy link
Author

BladeMF commented Mar 20, 2024

Yes, it is instant, I can confirm.
Phpunit 11 exports the text representation of all arguments that the data providers are providing before executing anything and phpstan provides really large objects sometimes. On top of this, this behaviour is not cusomisable as the Exporter class is not injected, but instantiated where it is used.

@BladeMF
Copy link
Author

BladeMF commented Mar 20, 2024

You could just change the recommendation of how to create unit tests for type assertions and leave it at that.

@ondrejmirtes
Copy link
Member

You could just change

You're using PHPStan test case correctly, this is the recommended way.

Anyway, this rings a bell, I feel like we already fixed this once in PHPUnit.

@BladeMF
Copy link
Author

BladeMF commented Mar 20, 2024

I have had issues with their Exporter class for a while now, so it's not the first problem of that kind.

@staabm
Copy link
Contributor

staabm commented Mar 20, 2024

Anyway, this rings a bell, I feel like we already fixed this once in PHPUnit.

I have the same feeling

@ondrejmirtes
Copy link
Member

@BladeMF
Copy link
Author

BladeMF commented Mar 21, 2024

I did propose to write a new exporter system :-) If he agrees, I'd welcome ideas on how to export the data in PHPStan's case though, if that's alright with you. Or, since I'll probably try implementing the factory pattern (factory::getExporter() + Exporter::supports($arg):bool + Exporter::export($arg, $factory):string), it would probably be best then if you created an exporter for this type specifically.

ondrejmirtes added a commit to phpstan/phpstan-src that referenced this issue Mar 28, 2024
@ondrejmirtes
Copy link
Member

Fixed the performance problem with PHPUnit 11: phpstan/phpstan-src@da87a65

@BladeMF
Copy link
Author

BladeMF commented Mar 28, 2024

So when the new version is out I can revert to using data providers?

@ondrejmirtes
Copy link
Member

Yes, your example repository is fast again.

@BladeMF
Copy link
Author

BladeMF commented Mar 28, 2024

I have to say, the level of your involvement makes me really happy. I've been using Phpstan for over 4 years now and I am really happy with it. Especially if I can write an extension to deal with edge cases and my own insanity.

@ondrejmirtes
Copy link
Member

I'm glad to hear that 😊

Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants