Unit test naming conventions
Recently I received a question; if I could explain these four lines:
/**
* @test
*/
public function it_works_with_a_standard_use_case_for_command_objects(): void
The author of the email had some great points.
- For each, my test I should write +3 new line of code instead write,
public function
testItWorksWithAStandardUseCaseForCommandObjects():
void
- PSR-12 say that "Method names MUST be declared in camelCase". [The source of this is actually PSR-1].
- In PHPUnit documentation author say "The tests are public methods that are named test*" and left example below
PHPStorm IDE from the last version gives for you ability to generate a TestCode and they do not use an underscore too:
I opened a popular frameworks (Symfony, Laravel, YII2, CodeIgniter4) test folders in Github and then I opened a popular PHP library and also do not find underscore usage in test and
@test
annotation.
This made me realize that, yes, what I'm doing here is a convention, and maybe it's not the most popular one. Well, I've seen tests that use an even less conventional approach to method naming by using some kind of character that isn't a space but still looks like one:
/**
* @test
*/
public function it works with a standard use case for command objects(): void
This is too much for me, but who knows, in a couple of years maybe...
I'll first respond to the objections now:
- I don't think it's bad to write 3 new lines for every test method.
It's not like it's actual code that gets duplicated, it's just an annotation.
The code never has to be modified, so it will never suffer from Shotgun Surgery (unless you switch test frameworks maybe).
Anyway, I have a live template configured in PHP so I only have to type
it
and it will complete this with/** @test */ public function
etc. We'll talk aboutit
later. Philosophically speaking, I don't think a test method is a regular object method. Yes, of course, it is technically a method. PHPUnit instantiates your
TestCase
and will call its methods. But that is just the way PHPUnit does it. You might as well write something like this:it('works with a standard use case for command objects');
In fact, there are test frameworks that let you write tests like this.
You will never find any normal code (a.k.a. production code) call these test methods. I do think that would look rather weird.
Instead of regular methods, I think we should consider test methods to be documentation or more specific: specification. This makes other aspects than code style conventions more important: it needs to be readable and precise. And in my experience
testItWorksWithAStandardUseCaseForCommandObjects
is really hard to read. Then again, maybe I just have to practice.But what if your code style fixer automatically turns "snake_case" method names into camelCase ones? Just configure the tool to ignore your tests.
- The way things are done in framework documentation can, but doesn't have to be considered the standard. The writer of the documentation has different goals than you have. Maybe they want to show the easiest way to get started with their framework. Maybe they just show the way that most users do it. Maybe nobody knows what most users do, and they just pick a way. What I do know is that the PHPUnit documentation also mentions this other way: "Alternatively, you can use the @test annotation in a method’s docblock to mark it as a test method."
- Although I love PhpStorm, I'm totally not inclined to do as they do.
As an example, they have invented the convention that we have to annotate all the exceptions that a method throws.
They also have an inspection that warns you about calling a method that could throw an exception.
I bet that a lot of developers have since been wrapping things in
try/catch
blocks and coming up with inventive ways of dealing with exceptions. Not because we have to, but because the IDE developers thought it would be a good idea. End of rant. Conclusion: don't let the IDE determine how you write your code (unless you have thought about it and agree with it of course). When it comes to generating a test class and "generating test methods": totally ignore what PhpStorm h
Truncated by Planet PHP, read more at the original (another 4445 bytes)