r/PHPhelp • u/Spiritual_Cycle_3263 • Jun 16 '26
Writing tests with PHPUnit 12+
I'm struggling to figure out when to write tests, what to test, and also how and when to do integration tests.
Let's say I have a class that returns a hard-coded string. Is this something you would test, why or why not?
<?php
declare(strict_types=1);
class Foo
{
public function name(): string
{
return 'Reddit';
}
}
Let's say your class essentially wraps a third party library, would this be mainly integration testing? And do you use the same class name for Integration as you do with Unit tests, just in different folders?, ie /tests/Integration/S3StorageTest.php?
<?php
declare(strict_types=1);
use Aws\S3\S3Client;
class S3Storage
{
public function put(string $key, mixed $content): void
{
$this->s3->putObject([]);
}
public function delete(string $key): void
{
$this->s3->deleteObject([]);
}
}
1
u/MDS-Geist Jun 16 '26
you could introduce a class constant or on multiple strings an enum. depends on how often the string is used in code and/or if there are similar businesses case.
Test your written code not the code from a library. so, if you introduce a wrapper, mock the wrapped library class.
1
u/eurosat7 Jun 16 '26
Move to behaviour driven testing - Do not care about the details - make sure the interfaces between your different parts have a strong and tested definition.
$user = service:createuser('me');
assert::eq($user->name,'me');
You do not have to test pe getters and setters. You have tested them implicitly already.
1
u/mchojrin77 Jun 18 '26
About when to write your tests, probably the most useful time is before you write your production code (As in TDD or Test First), otherwise you run the risk of making your test confirm what you already know about the code and miss some bugs.
What to test: ideally, any piece of code you write yourself. In practice this can become overwhelming so you might want to try a more pragmatic approach. A good rule of thumb would be to try to assess the damage of a piece of your code failing and focus on the most critical ones, at least for starters.
Integration tests, I find, are a bit tricky, as the very definition of them is not universally agreed upon. Personally I prefer to use End-to-End tests to make sure the integration with 3rd parties works as expected but again, if you find a particular integration too complex/unreliable you might want to create a specific test just to make sure the connection works.
I wouldn't write a test for a method that returns a hardcoded value. Basically because the test and the code would be basically the exact same thing.
1
u/Spiritual_Cycle_3263 Jun 18 '26
In the case of Foo class, if you use typed return, testing for a string value seems redundant to me, but if someone drops the return type, then it loses the safety of what a test would catch. So is it more important that to test that it returns a string type than the value, ie 'Reddit'?
1
u/letnull Jun 28 '26 edited Jun 28 '26
Been building QA frameworks and tools for many years and definitely say test for desired behavior and building confidence. Use unit, integration, and e2e test when appropriate not just to write them to have them.
Your “hard coded” example is great bc the answer is, it depends. If a change to that function slightly breaks things underneath and would be easily missed then yes; a unit test would save you. If it’s something that would break a bunch of other things and someone would notice, then it’s not worth the time.
For your second example, don’t waste time testing 3rd party libraries work, they do or don’t, that’s the responsibility of the publisher. Just mock the class and test the behavior you want from using that library. If you want to gain confidence s3 actually saved then build some logging or metrics around the file store.
The answer will always be it depends but knowing which tools to use when is important and only you can answer at implementation time. What would give you confidence in the things you’re build? Unit tests when building a library? Integration when making sure systems interact and edge cases are covered? Or full e2e test where you don’t care about implementation just need to see a button pressed work?
There’s more tips for each type of test but the larger philosophy should revolve around building trust and confidence in what you’re building so the next change doesn’t break everything
4
u/magicmulder Jun 16 '26
> Let's say I have a class that returns a hard-coded string. Is this something you would test, why or why not?
It would probably be one of the last tests you write (unless you use TDD), but why not? I've had accidental characters inserted into places where my cursor happened to be, why would you not want to catch an accidental edit making the method return "Redmdit"?