Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Symfony] Testowanie aplikacji
Malinaa
post 6.09.2023, 13:14:38
Post #1





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Cześć,
chciałbym wykonać testowanie rejestracji i logowania w Symfony.

Symfony -> w katalogu tests/Controller/ utworzyłem plik SecurityControllerTest.php (test logowania),
gdzie chciałbym uzupełnic formularz danymi i zalogować użytkownika, następnie sprawdzić, czy jest zalogowany.

Napisałem taki kod, ale ciągle sypie errorami (coś tu rzeźbię)?

  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Tests\Controller;
  6.  
  7. use App\Repository\UserRepository;
  8. use App\Tests\Integration\AbstractIntegrationWebTestCase;
  9.  
  10. class SecurityControllerTest extends AbstractIntegrationWebTestCase
  11. {
  12. public const TEST_USER_LOGIN = 'test@domain.com';
  13. public const TEST_USER_PASSWORD = 'test123';
  14.  
  15. public function testLogin(): void
  16. {
  17. $client = static::createClient();
  18. $crawler = $client->request('GET', '/login');
  19.  
  20. // Uzupelnij formularz danymi i zaloguj
  21. $dataLogin = [
  22. 'email' => self::TEST_USER_LOGIN,
  23. 'password' => self::TEST_USER_PASSWORD,
  24. //'submit' => 'Login',
  25. ];
  26.  
  27. //$formLogin = $crawler->filter('form')->form();
  28. $formLogin = $crawler->selectButton('Login')->form();
  29.  
  30. //$formLogin['email']->setValue(self::TEST_USER_LOGIN);
  31. //$formLogin['password']->setValue(self::TEST_USER_PASSWORD);
  32. //$formLogin['submit']->setValue('Login');
  33. // OFF $formLogin['_csrf_token"'] = 'It is generated automatically!';
  34.  
  35. //$client->submit($formLogin, $dataLogin);
  36.  
  37. //dd($client->getRequest()->request);
  38.  
  39. // Sprawdz, czy zalogowany -> sprawdza tylko czy email jest w bazie questionmark.gif?
  40. $repositoryUser = static::getContainer()->get(UserRepository::class);
  41. $testUser = $repositoryUser->findOneBy(['email' => self::TEST_USER_LOGIN]);
  42. $client->loginUser($testUser);
  43.  
  44. //dd($testUser);
  45.  
  46. $this->assertResponseIsSuccessful();
  47. }
  48. }


Mam prośbę o pomoc w wykonaniu testowania.



--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
VonSNAKE
post 20.09.2023, 22:57:24
Post #2





Grupa: Zarejestrowani
Postów: 5
Pomógł: 0
Dołączył: 6.10.2012

Ostrzeżenie: (0%)
-----


A pokaż Twig i Kontroler dla routa /login?
Go to the top of the page
+Quote Post
jacek.e3
post 21.09.2023, 11:28:23
Post #3





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


Która wersja Symfony? Masz w kodzie
  1. $client->loginUser($testUser);
więc zakładam, że 5.1+

ten fragment:
  1. $repositoryUser = static::getContainer()->get(UserRepository::class);
  2. $testUser = $repositoryUser->findOneBy(['email' => self::TEST_USER_LOGIN]);
  3. $client->loginUser($testUser);

to takie ułatwienie, żeby od razu mieć zalogowanego usera do dalszych testów. Ten kod nawet nie dotyka formularza tylko ustawia usera ze zmiennej $testUser jako zalogowanego użytkownika.

co do reszty to spróbuj tak:
  1. $client = static::createClient();
  2. $crawler = $client->request('GET', '/login');
  3.  
  4. // Uzupelnij formularz danymi i zaloguj
  5. $dataLogin = [
  6. 'email' => self::TEST_USER_LOGIN,
  7. 'password' => self::TEST_USER_PASSWORD,
  8. //'submit' => 'Login',
  9. ];
  10.  
  11. //$formLogin = $crawler->filter('form')->form();
  12. $formLogin = $crawler->selectButton('Login')->form();
  13.  
  14. $formLogin['email'] = self::TEST_USER_LOGIN;
  15. $formLogin['password'] = self::TEST_USER_PASSWORD;
  16. $this->client->submit($formLogin);


teraz możesz sprawdzic jakies inne rzeczy np. czy nastąpiło przekierowanie na stronę główną (o ile takie ustawiłeś):
  1. // BTW. dodaj sobie router i generuj sciezki zamiast wstawiac je na sztywno
  2. $router = static::getContainer()->get(UrlGeneratorInterface::class);
  3. $this->assertResponseRedirects($router->generate('app_home'));


albo czy zwrócona strona zawiera jakiś tekst np. "zalogowano", możesz też sprawdzić to po zasymulowaniu kliknięcia np:

  1. $client->request('GET', '/home');
  2. $this->assertResponseIsSuccessful();
  3. $this->assertSelectorTextContains('h1', 'Witaj');


Go to the top of the page
+Quote Post
Malinaa
post 25.09.2023, 14:28:11
Post #4





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Cytat(VonSNAKE @ 20.09.2023, 23:57:24 ) *
A pokaż Twig i Kontroler dla routa /login?


Kontroler

<!--Geshi:502619:php--><pre class="php-brief" style="font-family:monospace;"><div class="head">
  1. [topic=0]oken"</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">"_csrf_token"</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">"97e..."</span> <span class="sy0">/</span>><<span class="sy0">/</span><span class="kw2">div</span>></span></div><li class="li2"><div class="de2"><span class="sc2"><<span class="sy0">/</span><span class="kw2">form</span>></span></div>
  2. [/list]<div class="foot">[HTML] [url="./Pobierz-Plik-502620.html"]plaintext[/url] </div></pre><!--/Geshi:502620:html-->
  3.  
  4.  
  5.  
  6. <!--quoteo(post=1261873:date=21.09.2023, 12:28:23 :name=jacek.e3)--><div class='quotetop'>Cytat(jacek.e3 @ 21.09.2023, 12:28:23 ) [snapback]1261873[/snapback]</div><div class='quotemain'><!--quotec-->Która wersja Symfony?<!--QuoteEnd--></div><!--QuoteEEnd-->
  7.  
  8.  
  9. Symfony w wersji 5.4
  10.  
  11. Przesłany kod już wcześniej sprawdzałem, ale wg. tego co napisałeś teraz jest tak:
  12.  
  13. [php]class SecurityControllerTest extends AbstractIntegrationWebTestCase
  14. {
  15. public const TEST_USER_LOGIN = 'test@email.com';
  16. public const TEST_USER_PASSWORD = 'Test123';
  17.  
  18. public function testLogin(): void
  19. {
  20. $client = static::createClient();
  21. $crawler = $client->request('GET', '/login');
  22.  
  23. $formLogin = $crawler->selectButton('Login')->form();
  24.  
  25. $formLogin['email'] = self::TEST_USER_LOGIN;
  26. $formLogin['password'] = self::TEST_USER_PASSWORD;
  27. $client->submit($formLogin);
  28.  
  29. $router = static::getContainer()->get(UrlGeneratorInterface::class);
  30. $this->assertResponseRedirects($router->generate('app_main'));
  31.  
  32. //dd($client->getResponse()->getContent());
  33. }
  34. }


i sypie błędem:

FAILURES!
Tests: 1, Assertions: 2, Failures: 1.


dd($client->getResponse()->getContent());
daje jakiś wynik przekierowania chyba z vendora

<body>
Redirecting to <a href="/login">/login</a>.\n
</body>

i za chiny ten $formLogin nie loguje usera z formularza logowania?

Ten post edytował Malinaa 25.09.2023, 14:31:10


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 25.09.2023, 17:56:43
Post #5





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


3 sprawy:
1) jak się logujesz "ręcznie" - to działa?

2) kolega prosił o twiga formularza i kod kontrolera. Nie chodziło nam o wygenerowany kod w htmlu tylko o surowe pliki z twiga i klase controllera.
Formularz powinien mieć dynamicznie generowany token csrf:
  1. <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" >

a w kontrolerze można dodać np:
  1. $error = $authenticationUtils->getLastAuthenticationError();

i podejrzeć co jest nie tak.

3) Phpunit powinien dać Ci coś więcej niż tylko surową liczbę - wklej co mu tam nie pasuje.

FAILURES!
Tests: 1, Assertions: 2, Failures: 1.


Ten post edytował jacek.e3 25.09.2023, 17:57:06
Go to the top of the page
+Quote Post
Malinaa
post 26.09.2023, 08:19:41
Post #6





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Sprawy

1. Tak, wypełniam pole login, hasło, zaznaczam Agree terms i loguje się.

2. Przesłałem wygenerowany kod HTML, ponieważ tu wszystko widać i jest też token csrf

  1. <input type="hidden" id="_csrf_token" name="_csrf_token" value="abc..." />


bynajmniej było widać, teraz to chyba forum nie poradziło sobie z formatowaniem i "brzydko" wyświetla w PHP plaintext

dodatkowo przesyłam kod Twig

{%- block form -%}
{{ form_start(form) }}
{{- form_widget(form) -}}
{{ form_end(form) }}
{%- endblock -%}

w kontrolerze jest dodane:
$error = $authenticationUtils->getLastAuthenticationError();
i nie pokazuje, aby coś tu było nie tak,
chyba, że jest tu mowa o dodaniu w kontrolerze testowym?

3. Oprócz F - fail i liczby jest komunikat

Deprecated: App\Shared\Uuid\Uuid implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in /var/www/src/Shared/Uuid/Uuid.php on line 11

Przesyłam ponownie klasę testu po wprowadzeniu zmian, o których pisałeś chociaż była już wcześniej podana

  1. class SecurityControllerTest extends AbstractIntegrationWebTestCase
  2. {
  3. public const TEST_USER_LOGIN = 'test@email.com';
  4. public const TEST_USER_PASSWORD = 'Test123';
  5.  
  6. public function testLogin(): void
  7. {
  8. $client = static::createClient();
  9. $crawler = $client->request('GET', '/login');
  10.  
  11. $formLogin = $crawler->selectButton('Login')->form();
  12.  
  13. $formLogin['email'] = self::TEST_USER_LOGIN;
  14. $formLogin['password'] = self::TEST_USER_PASSWORD;
  15. $client->submit($formLogin);
  16.  
  17. $router = static::getContainer()->get(UrlGeneratorInterface::class);
  18. $this->assertResponseRedirects($router->generate('app_main'));
  19. }
  20. }


Powyższa klasa sypie błędem FAILURES... Nie działa.

Ten post edytował Malinaa 26.09.2023, 08:34:24


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 26.09.2023, 13:18:46
Post #7





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


Cały czas chodzilo o kontroler do logowania, a nie klase do testowania.

Jeżeli nie ma tam nic innego przy tym failure to w takim razie może wszystko jest tam ok. W zależności od wersji phpunit były różne defaultowe zachowania co zrobić z deprecation errorami.

Zobacz tu: https://symfony.com/doc/current/components/...recation-helper

  1. <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" />
Go to the top of the page
+Quote Post
Malinaa
post 27.09.2023, 08:52:27
Post #8





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Ten kontroler podałem w [PHP] pobierz, plaintext ale coś się tu poprzestawiało przy wyświetlaniu, stąd zmyłka (wiem, że podałem kod kontrolera, ale faktycznie gdzieś zaginął w akcji).
Jeśli jest error to raczej nie jest wszystko ok. Zobaczę co pod tym linkiem piszą.

Dodałem
  1. <!-- phpunit.xml.dist -->
  2. <listeners>
  3. <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
  4. <arguments>
  5. <array>
  6. <element key="debug-class-loader"><integer>0</integer></element>
  7. </array>
  8. </arguments>
  9. </listener>
  10. </listeners>

ale nadal wyświetla błąd.

There was 1 failure:

App\Tests\Controller\SecurityControllerTest::testLogin
Failed asserting that Symfony\Component\HttpFoundation\RedirectResponse Object &00000000000009450000000000000000 (
...
) is redirected and has header "Location" with value "/".

Ten post edytował Malinaa 27.09.2023, 08:58:20


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 27.09.2023, 09:20:01
Post #9





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


ok, ale jak kontrolera nie było tak dalej nie ma.
W końcu jest za to jakiś konkret. Dostajesz info, że adres strony nie zgadza się z adresem przekierowania. Do tego gdzieś tam wcześniej pisałeś, że content robi redirect na /login

Pamiętasz to?
  1. $error = $authenticationUtils->getLastAuthenticationError();


możesz zdumpować ten $error to się dowiesz, co to za problem. Mój obecny typ to - nieprawidłowy user /hasło a wynika to stąd, że developujesz na jednej bazie, ale do testów jest odpalana lustrzana baza z sufixem "_test" i w niej tez powinny byc zapisane dane do logowania dla tego usera.

Go to the top of the page
+Quote Post
Malinaa
post 27.09.2023, 11:39:08
Post #10





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Testuje, sprawdzam itp., ale coś to testowanie idzie jak krew z nosa

Klasa kontrolera

  1. class SecurityController extends AbstractController
  2. {
  3. #[Route(path: '/login', name: 'app_login')]
  4. public function login(AuthenticationUtils $authenticationUtils): Response
  5. {
  6. if ($this->getUser()) {
  7. return $this->redirectToRoute('app_main');
  8. }
  9.  
  10. $error = $authenticationUtils->getLastAuthenticationError();
  11. if (isset($error)) {
  12. $this->addFlash('danger', $error->getMessage());
  13. }
  14.  
  15. $form = $this->createForm(LoginType::class, [
  16. 'email' => $authenticationUtils->getLastUsername(),
  17. ]);
  18.  
  19. return $this->render('security/login.html.twig', [
  20. 'form' => $form->createView(),
  21. 'error' => $error,
  22. ]);
  23. }
  24.  
  25. // and more...
  26. }


może z redirect mam coś zamieszane?

dump($error) daje null

w kontrolerze mamy
if ($this->getUser()) {} i powinno przekierować,
ale wygląda, że nie wchodzi do tego ifa, czyli nie loguje usera

Pytanie co z bazą, bo czytam, że powinna być osobna "test",
ale nie widzę tu żadnego połączenia i bazy "test", testuje na jednej bazie

Ten post edytował Malinaa 27.09.2023, 11:45:03


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 27.09.2023, 11:49:47
Post #11





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


Masz route "app_main"?
Masz usera w bazie testowej?

Spróbuj dodać to dump($error) w kontrolerze i odpal test jeszcze raz;

Go to the top of the page
+Quote Post
Malinaa
post 27.09.2023, 12:09:31
Post #12





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Mam route 'app_main'
$router = static::getContainer()->get(UrlGeneratorInterface::class);
$this->assertResponseRedirects($router->generate('app_main'));

User jest bazie projektu, a że jest jedna baza to też jest w testowej! Chyba?

Dodaje dump($error) w kontrolerze SecurityController i odpalam test jeszcze raz,
otrzymuję null z dumpa i błąd... wcześniej wymieniony

Kontroler test
  1. class SecurityControllerTest extends AbstractIntegrationWebTestCase
  2. {
  3. public const TEST_USER_LOGIN = 'test@email.com';
  4. public const TEST_USER_PASSWORD = 'Test123';
  5.  
  6. public function testLogin(): void
  7. {
  8. $client = static::createClient();
  9. $crawler = $client->request('GET', '/login');
  10.  
  11. $formLogin = $crawler->selectButton('Login')->form();
  12.  
  13. $formLogin['email'] = self::TEST_USER_LOGIN;
  14. $formLogin['password'] = self::TEST_USER_PASSWORD;
  15. $client->submit($formLogin);
  16.  
  17. $router = static::getContainer()->get(UrlGeneratorInterface::class);
  18. $this->assertResponseRedirects($router->generate('app_main'));
  19. }
  20. }

Czy
$formLogin['email'] = self::TEST_USER_LOGIN;
$formLogin['password'] = self::TEST_USER_PASSWORD;
wystarcza, aby się zalogować, czy cos tu brakuje?
Sprawdzałem z np. dodatkowo
$formLogin['agreeTerms'] = true;
ale też daje ten sam błąd.
A token, a zakodowane hasło itp.?

Albo $formLogin = $crawler->selectButton('Login')->form() podpowiada, że powinno tu być value.
Czy dla takiego buttona: <button type="submit" id="submit" name="submit" class="btn btn-primary">Login</button> value to na pewno: Login?

Ten post edytował Malinaa 27.09.2023, 12:55:57


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 27.09.2023, 17:22:29
Post #13





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


Masz jakis serwer z bazodanowy - mysql ?

Zaloguj się tam i wyświetl bazy danych. Sprawdź, czy jest tam baza danych z suffixem '_test'. Jak jest to wejdz do niej, sprawdz czy masz wszystkie tabele, a w szczegolnosci czy masz tabele z usarami i czy jest w niej rekord dotyczacy Twojego testowego konta.
Sprawdź to, nie zakładaj że to jest to samo.


defaultowy suffix do bazy w srodowisku testowy:
app/config/packages/doctrine.yaml
  1. when@test:
  2. doctrine:
  3. dbal:
  4. # "TEST_TOKEN" is typically set by ParaTest
  5. dbname_suffix: '_test%env(default::TEST_TOKEN)%'


Go to the top of the page
+Quote Post
Malinaa
post 4.10.2023, 11:26:13
Post #14





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Ustawienia są tak zmienione, że powinno działać na bazie głównej (nie _test) i wygląda, że działa, ponieważ dla repozytorium podbiera dane z bazy bez problemu.

Przykład:
  1. $userRepository = static::$container->get(UserRepository::class);
  2. $testUser = $userRepository->findOneBy(['email' => 'test@email.com']);

i otrzymuję dane usera z bazy.

Znaczy się teoretycznie zakładam, a praktycznie sprawdziłem, że powinno działać tak samo,
chociaż pewności nie mam jak to jest z tą bazą _test, na serwerze takiej nie mam, w ustawieniach jest zmienione, aby łączyło z bazą aplikacji.
Po dodaniu dbname_suffix: '_test%env(default::TEST_TOKEN)%' aplikacja się wysypie, nie ma bazy _test.

Patrzę jeszcze na. env, czy tutaj ma być APP_ENV=dev czy przy testach powinno być zmienione na APP_ENV=test?


Ten post edytował Malinaa 4.10.2023, 11:28:26


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post
jacek.e3
post 5.10.2023, 07:11:04
Post #15





Grupa: Zarejestrowani
Postów: 20
Pomógł: 6
Dołączył: 2.02.2010

Ostrzeżenie: (0%)
-----


Kod
  1. $userRepository = static::$container->get(UserRepository::class);
  2. $testUser = $userRepository->findOneBy(['email' => 'test@email.com']);


sprawdzi tylko czy user o takim adresie jest w bazie. Nie sprawdzi czy hasło jest poprawne.

W głównym folderze powinien byc plik konfiguracyjny do phpunit: phpunit.xml.dist
w środku znajdziesz:
  1. <server name="APP_ENV" value="test" force="true" />


Skoro zmieniasz jakieś rzeczy z defaultowym configu i o nich nie piszesz, to nie oczekuj, że ktoś się domyśli co tam zmieniłes. Wrzuc całość na jakiegos githuba to wtedy bedzie sens to kontynuowac.
Go to the top of the page
+Quote Post
Malinaa
post 5.10.2023, 07:23:26
Post #16





Grupa: Zarejestrowani
Postów: 518
Pomógł: 6
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


W phpunit.xml.dis mam

  1. <server name="APP_ENV" value="test" force="true" />


Przy testach może hasło koduje inaczej, pozostaje pytanie jak je sprawdzić?

Nie za bardzo mogę udostępnić ten kod, ale dziękuje za informacje.


--------------------
I welcome you on the Internet >>> Design by Malina
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 27.04.2024 - 13:08