Ankündigung

Einklappen
Keine Ankündigung bisher.

Command e2e test mit Benutzer-Eingabe schlägt fehl

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Symfony] Command e2e test mit Benutzer-Eingabe schlägt fehl

    Hallo,

    für ein Command versuche ich e2e Test zum Laufen zu bekommen.
    Das Command stellt Fragen und nach der Eingabe wird die Antwort ausgewertet und entsprechendes Feedback ausgegeben. Das Command funktioniert manuell.

    Der automatische Test schlägt fehl mit folgender Meldung:
    Code:
    1) e2e\Command\MyCommandTest::testExecute
    Symfony\Component\Console\Exception\MissingInputException: Aborted.2
    
    /var/www/my_module/vendor/symfony/console/Helper/QuestionHelper.php:274
    Die Exception wird aufgrund dieser if()-Prüfung geworfen.

    Leider gibt das Internet nicht viel her zum Thema.

    Der UseCase (auf cli):
    • Frage (ChoiceQuestion) mit exakt einem item
      • Case falsche Eingabe: Ausgabe Fehlerstring
      • Case richtige Eingabe: Nächste Frage

    Zur Umsetzung des Test folge ich den Symfony Handbuch: Testing Commands und Testing a Command that Expects Input

    Mein Test

    Frage hierzu: Handbuch sagt:
    • PHP-Code:
      use Symfony\Component\Console\Helper\HelperSet
    • PHP-Code:
      use Symfony\Component\Console\Helper\QuestionHelper
    Beide Klassen werden nicht eingestezt. Warum müssen diese eingebunden sein?
    PHP-Code:
    # tests/e2e/Command/MyCommandTest.php
    <?php

    namespace e2e\Command;

    use 
    Symfony\Bundle\FrameworkBundle\Console\Application;
    use 
    Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
    use 
    Symfony\Component\Console\Tester\CommandTester;
    use 
    Symfony\Component\Console\Helper\HelperSet;
    use 
    Symfony\Component\Console\Helper\QuestionHelper;

    class 
    MyCommandTest extends KernelTestCase
    {
        public function 
    testExecute()
        {
            
    $kernel = static::createKernel();
            
    $application = new Application($kernel);

            
    $command $application->find('app:my-command');
            
    $commandTester = new CommandTester($command);

            
    $commandTester->setInputs(['abc']);


            
    $commandTester->execute([
                
    'command' => $command->getName()
            ]);

            
    $output $commandTester->getDisplay();

            
    $expected 'The required resource with name >>abc<< does not exist!';
            
    $this->assertEquals($expected$output);

        }

    }
    Die Command Klasse
    PHP-Code:
    # src/Command/MyCommand.php
    <?php declare(strict_types=1);

    namespace 
    App\Command;
    ...
    class 
    MyCommand extends Command
    {
        protected static 
    $defaultName "app:my-command";

        public function 
    __construct(...)
        {
            
    parent::__construct();
            ...
        }

        protected function 
    configure()
        {
            
    // NOTE: nothing to configurate here
        
    }

         protected function 
    execute(InputInterface $inputOutputInterface $output)
        {


            
    $this->helper $this->getHelper('question');
           ...

            
    /**
             * start to ask with defined questions
             */
            
    $this->questionService->questionChoiceResource($this->resource$input$output);
            ...
            return 
    0;
        }
        ...
    }
    Was ist faul an meinem Test? Jede Hilfe ist Willkommen.

  • #2
    Weitere Infos:

    ich lass mir an der Stelle der Exception ein Dump ausgeben:
    PHP-Code:
    # vendor/symfony/console/Helper/QuestionHelper.php
    ...
    private function 
    autocomplete(OutputInterface $outputQuestion $question$inputStream, callable $autocomplete): string
    {
        ...
        while (!
    feof($inputStream)) {

            
    $c fread($inputStream1);

            
    var_dump($c);
         ... 
    Da sehe ich einen Unterschied bei der Ausgabe zwischen manuelle Eingabe und die vom Test automatisierte Eingabe:
    Code:
    # manuelle Eingabe
    
     > /var/www/my-module/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "a"
    a/var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "b"
    b/var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "c"
    c/var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "
    "
    The required website with name >>abc<< does not exist!
    
    
    # test Eingabe
    
    /var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "a"
    /var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "b"
    /var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "c"
    /var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(1) "
    "
    /var/www/my-module/payment-badlist-freesimcard/vendor/symfony/console/Helper/QuestionHelper.php:268:
    string(0) ""
    
    
    Time: 143 ms, Memory: 16.00 MB
    
    There was 1 error:
    
    1) e2e\Command\MyCommandTest::testExecute
    Symfony\Component\Console\Exception\MissingInputException: Aborted
    Also es wird ein Zeichen mehr mitgegeben als bei der manuellen Eingabe

    Der $inputStream für den Test wird an dieser Stelle gebaut. Warum gibt es ein 4. Zeichen? Ich denke, das erzeugt den Fehler wegen dieser Prüfung:
    PHP-Code:
    '' === $c 

    Kommentar


    • #3
      Edit: Achso hab deinen Link zur Dokumentation übersehen. Dann bin ich gerade auch überfragt.

      Wo hast du diesen Code Teil denn her? Also dann man den so verwenden soll. Ich hab auf die schnelle nur gefunden, dass man die Input Options und Argumente der execute() Methode mitgeben soll.
      PHP-Code:
      $commandTester->setInputs(['abc']); 
      Vll. hilft es auch in den interactive Modus zu wechseln. Laut Constructor Docs gibt es eine entsprechende Option:
      PHP-Code:
          /**
           * Executes the command.
           *
           * Available execution options:
           *
           *  * interactive:               Sets the input interactive flag
           *  * decorated:                 Sets the output decorated flag
           *  * verbosity:                 Sets the output verbosity flag
           *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
           *
           * @param array $input   An array of command arguments and options
           * @param array $options An array of execution options
           *
           * @return int The command exit code
           */
          
      public function execute(array $input, array $options = []) 

      Kommentar

      Lädt...
      X