[Test] Guidelines proposal to test the commands interactive mode. #2972
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The goal of this PR is to set the path to a more uniform way to test commands using the interactive mode. I'm using the
AuthenticationProviderCommandas an example. There should be some similarities for all the commands that generate code.First, I replaced most of the traits from the command with classes and its corresponding tests. I identified 2 main collaborator objects.
ConfirmGenerationwhich is the object that stops the command in case the user cancels the operation andAuthenticationProviderQuestionswhich is the object that asks the user for any required parameter that might be missing, in this command is themodule, theclassand theprovider-id.Both objects require the use of the
DrupalStyleclass, which is the first big change to the code, because it requires to add the$inputand$ouputobjects as a services. Please take a look tobin/drupal.php,config/services/drupal-console/generate.ymlandservices.ymlto see how this affects the configuration.The
AuthenticationProviderQuestionsclass needs to use the extensionsManager, which is hard to mock because of its chained method calls.I replaced this sequence of calls with 2 new methods
Manager#showModuleNamesExceptCoreandManager#showAllProfileNames. In order to replace the manager with a double in an easier way. I'm open to suggestions for better names for this 2 methods.Having said that, I'll explain the organization of the tests. I did several opinionated changes to the tests structure which I'd like to discuss/explain as needed.
@testannotation instead of using the prefixtestfor method names.snake_caseand the formatit_behaves_this_waysimilar to what you do withphpspec@beforeannotation instead of asetUpmethod. I named this methodconfigureas a convention and its structure is similar to this one inAuthenticationProviderQuestionsTest.The method
initValuesis optional as you can see inAuthenticationProviderCommandTestwhere the initialization of the values is in the field declaration. I'm asking for your input on these 2 options. Which one would you like? I prefer the initialization on the field declaration because you can go directly to the field declaration and see what the value is, without having to go to the method declaration.@beforemethod. This order makes test methods easy to find. You don't have to navigate to them because it's the first thing to find on any test class. For instance:I know this changes are costly in time if you try to the same for all the commands, but I think its worth it. I'm willing to pair with you or review the tests for new code. Or also do some pairing or help documenting the process to add tests to existing code.
Thank you all.