![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Na co powinienem zwrócić uwagę, pisząc testy w PHPUnit? Co powinienem testować, a czego nie?
Napisałem kiedyś taki test kontrolera w Symfony. Jak przetestować klikanie w linki bez Symfony? Przeglądam pisanie testów w PHPUnit i nie widzę przykładów, jak to zrobić. Podpowiedzcie mi, co powinienem przetestować w mojej aplikacji... ![]() |
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Cytat Jak przetestować klikanie w linki bez Symfony? Ja do tego uzywam Panther -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Ja do tego uzywam Panther Zainstalowałem Panther Composer'em dla mojego projektu i mam problem. Gdy uruchamiam test w "Wierszu polecania"... Kod php vendor/bin/phpunit tests/ ...wyświetla mi się "General error": Cytat '.' is not recognized as an internal or external command Znalazłem na stackoverflow.com, aby użyć WSL2 "Windows Subsystem For Linux". Z poziomu okna MSYS2 uruchamiam test w PHPUnit... Kod /c/xampp/php/php ./vendor/bin/phpunit tests/ ...i wywala mi ten sam błąd. W czym tkwi problem? Bo użycie Bash'a w WSL nie pomaga i jakiś tam skrypt dalej wyrzuca mi ten błąd pod Windows... :| ![]() PS W pliku mojego testu MainPageControllerTest.php w linii 21 - wskazywanej jako problematyczna - jest kod: Kod $client->request('GET', '/'); ...i to on przyczynia się do wyświetlenia błędu. Jak go zakomentuję/usunę, to błędu nie ma. Dziwne. ![]() PS2 Żeby było łatwiej, podaję wersje roboczą tej klasy: Kod <?php declare(strict_types=1); namespace App\Tests\Controller; use Symfony\Component\Panther\PantherTestCase; class MainPageControllerTest extends PantherTestCase { public function testMainPageAndClickPolishLanguageLink(): void { // your app is automatically started using the built-in web server $client = static::createPantherClient(); $client->request('GET', '/'); /* $client = self::createPantherClient([ 'hostname' => '127.0.0.9', // defaults to 127.0.0.1 'port' => 8080, // defaults to 9080 ]); $client->request('GET', '/'); */ // use any PHPUnit assertion, including the ones provided by Symfony... //$this->assertPageTitleContains('PHP Framework from EEQSOFT'); [...] } } PS3 Wydaje mi się, że sprawę rozwiąże użycie Docker'a. Jutro sprawdzę. ![]() Ten post edytował eerie 16.03.2025, 11:09:59 |
|
|
![]()
Post
#4
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Cytat ydaje mi się, że sprawę rozwiąże użycie Docker'a. Jutro sprawdzę. No ja uzywam tego wlasnie na linux z dockerem i nie mialem takich problemow wiec trudno powiedziec co jest zle u ciebie. Daj znac jak ci poszlo z tym docker -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Daj znac jak ci poszlo z tym docker Odpaliłem projekt na Docker'ze. Użyłem Composer'a, aby zainstalować biblioteki. I niby wszystko jest zainstalowane, włącznie z dbrekelmans/bdi, a przy uruchamianiu testu phpunit wyświetla mi się komunikat: Cytat Symfony\Component\Panther\Exception\RuntimeException: "geckodriver" binary not found. Install it using the package manager of your operating system or by running "composer require --dev dbrekelmans/dbi && vendor/bin/dbi detect drivers" Jak wpisuję "composer require --dev dbrekelmans/db" czy "composer update dbrekelmans/db", to wyświetla się info, że jest zainstalowany. Natomiast polecenie "./vendor/bin/dbi detect drivers" nic nie zwraca. Pod Windows miałem jakiś komunikat, że jest ok. A tu nic... Coś jest nie tak, a ja jestem trochę "zielonkawy" z Linux'a. ![]() |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Nie wiem, nigdy nie widzialem takich problemow. Podam ci co ja mam, moze ci to pomoze:
docker-compose.yml version: '3' services: php8: container_name: php8 build: context: . dockerfile: docker/images/php/Dockerfile volumes: - ./appcode:/var/www/html - ./docker/images/php/conf/dev-php.ini:/usr/local/etc/php/conf.d/php-settings.ini web: container_name: web ports: - "8083:80" build: context: . dockerfile: docker/images/nginx/Dockerfile volumes: - ./appcode:/var/www/html - ./docker/images/nginx/conf:/tmp/nginx PHP Dockerfile: FROM php:8.4.1-fpm-alpine3.21 # Set the system locale and time ENV TZ=Europe/London LANG=en_GB.UTF-8 LANGUAGE=en_GB.UTF-8 LC_ALL=en_GB.UTF-8 LC_CTYPE=en_GB.UTF-8 RUN apk update \ && apk upgrade \ && apk add --no-cache \ tzdata \ musl-locales \ musl-locales-lang \ && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo $TZ > /etc/timezone # Install additional php extensions ADD https://github.com/mlocati/docker-php-exten...-php-extensions /usr/local/bin/ RUN chmod +x /usr/local/bin/install-php-extensions \ && sync \ && install-php-extensions \ bcmath \ gd \ intl \ pcntl \ pdo_mysql \ xdebug \ zip # Chromium and ChromeDriver ENV PANTHER_NO_SANDBOX=1 ENV PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage' RUN apk add --no-cache chromium chromium-chromedriver # Install Composer RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # Install php-cs-fixer RUN curl -L https://cs.symfony.com/download/php-cs-fixer-v3.phar -o php-cs-fixer \ && chmod a+x php-cs-fixer \ && mv php-cs-fixer /usr/local/bin/php-cs-fixer # Clean up temporary files to keep image small RUN rm -rf /var/cache/apk/* /var/tmp/* /tmp/* # Configure the run.sh script to be executed COPY docker/images/php/run.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/run.sh; CMD ["/usr/local/bin/run.sh"] composer.json { "type": "project", "license": "proprietary", "minimum-stability": "stable", "prefer-stable": true, "require": { "php": ">=8.4", "ext-ctype": "*", "ext-iconv": "*", "doctrine/annotations": "^1.0", "doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.12", "guzzlehttp/guzzle": "^7.3", "phpdocumentor/reflection-docblock": "^5.3", "phpoffice/phpspreadsheet": "^1.29", "phpstan/phpdoc-parser": "^1.6", "symfony/asset": "7.2.*", "symfony/console": "7.2.*", "symfony/doctrine-messenger": "7.2.*", "symfony/dotenv": "7.2.*", "symfony/expression-language": "7.2.*", "symfony/flex": "^2", "symfony/form": "7.2.*", "symfony/framework-bundle": "7.2.*", "symfony/http-client": "7.2.*", "symfony/intl": "7.2.*", "symfony/mailer": "7.2.*", "symfony/mime": "7.2.*", "symfony/monolog-bundle": "^3.0", "symfony/notifier": "7.2.*", "symfony/process": "7.2.*", "symfony/property-access": "7.2.*", "symfony/property-info": "7.2.*", "symfony/proxy-manager-bridge": "6.4.*", "symfony/runtime": "7.2.*", "symfony/security-bundle": "7.2.*", "symfony/serializer": "7.2.*", "symfony/string": "7.2.*", "symfony/translation": "7.2.*", "symfony/twig-bundle": "7.2.*", "symfony/validator": "7.2.*", "symfony/web-link": "7.2.*", "symfony/webpack-encore-bundle": "^2.1", "symfony/yaml": "7.2.*", "twig/extra-bundle": "^2.12|^3.0", "twig/twig": "^2.12|^3.0" }, "config": { "allow-plugins": { "composer/package-versions-deprecated": true, "symfony/flex": true, "symfony/runtime": true }, "optimize-autoloader": true, "preferred-install": { "*": "dist" }, "sort-packages": true }, "autoload": { "psr-4": { "App\\": "src/" } }, "autoload-dev": { "psr-4": { "App\\Tests\\": "tests/" } }, "replace": { "symfony/polyfill-ctype": "*", "symfony/polyfill-iconv": "*", "symfony/polyfill-php72": "*", "symfony/polyfill-php73": "*", "symfony/polyfill-php74": "*", "symfony/polyfill-php80": "*", "symfony/polyfill-php81": "*" }, "scripts": { "auto-scripts": { "cache:clear": "symfony-cmd", "assets:install %PUBLIC_DIR%": "symfony-cmd" }, "post-install-cmd": [ "@auto-scripts" ], "post-update-cmd": [ "@auto-scripts" ] }, "conflict": { "symfony/symfony": "*" }, "extra": { "symfony": { "allow-contrib": false, "require": "7.2.*" } }, "require-dev": { "dbrekelmans/bdi": "^1.0", "phpunit/phpunit": "^9.5", "symfony/browser-kit": "7.2.*", "symfony/css-selector": "7.2.*", "symfony/debug-bundle": "7.2.*", "symfony/maker-bundle": "^1.0", "symfony/panther": "^2.0", "symfony/phpunit-bridge": "^7.2", "symfony/stopwatch": "7.2.*", "symfony/web-profiler-bundle": "7.2.*" } } A tak odpalam testy z panther (e2e - tam trzymam testy dla panther) docker exec -it --user=1000 php8 /bin/sh -c "php -d xdebug.mode=coverage bin/phpunit --testsuite e2e -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Udało mi się rozwiązać ten problem. Wystarczyło dodać "geckodriver" [firefox'a] w Dockerfile:
Kod [...] RUN apt-get update \ && apt-get install -y --no-install-recommends \ ca-certificates curl firefox-esr \ && rm -fr /var/lib/apt/lists/* \ && curl -L https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz | tar xz -C /usr/local/bin \ && apt-get purge -y ca-certificates curl [...] Niestety nie wiem, dlaczego test dla mojej klasy MainPageControllerTest pokazuje błąd, iż metoda assertPageTitleContains() jest niezdefiniowana. |
|
|
![]()
Post
#8
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
No bo nie ma tej metody?
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Co mam zrobić, aby móc użyć tej metody? W dokumentacji Panther'a napisali, że można użyć dowolnej "PHPUnit Assertion", ale u mnie nie są dostępne... A klasa TestCase jest abstrakcyjna. Nie mogę utworzyć obiektu klasy TestCase, a przy tym - o ile dobrze pamiętam - PHP pozwala rozszerzać maksymalnie jedną klasę. Da się jakoś użyć "extends" dla klas "PantherTestCase" i "TestCase" jednocześnie? A może brakuje mi jakichś bibliotek i dlatego nie działa? Jestem w kłopocie...
![]() ![]() Ten post edytował eerie 19.03.2025, 18:12:33 |
|
|
![]()
Post
#10
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Sam sobie komplikujesz rzeczy. Poprostu zobacz co ma Panther. Jesli chcesz sprawdzac tytul, to masz przeciez:
self::assertPageTitleSame -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Udało się... Działa! Napisałem taki test. Ma to sens?
![]() Kod <?php
declare(strict_types=1); namespace App\Tests\Controller; use Symfony\Component\BrowserKit\HttpBrowser; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Panther\PantherTestCase; class MainPageControllerTest extends PantherTestCase { public function testMainPageTitleAndForm(): void { $browser = new HttpBrowser(HttpClient::create()); $browser->request('GET', '/'); $response = $browser->getResponse(); preg_match( '/<title>(PHP Framework from EEQSOFT)<\/title>/', (string) $response, $matches ); $this->assertEquals($matches[1], 'PHP Framework from EEQSOFT'); $browser->clickLink('Polish'); $response = $browser->getResponse(); preg_match( '/<title>(PHP Framework od EEQSOFT)<\/title>/', (string) $response, $matches ); $this->assertEquals($matches[1], 'PHP Framework od EEQSOFT'); $browser->clickLink('Angielski'); $browser->submitForm('Confirm', ['name' => 'Robert']); $response = $browser->getResponse(); preg_match( '/(Welcome, Robert!)/', (string) $response, $matches ); $this->assertEquals($matches[1], 'Welcome, Robert!'); } } |
|
|
![]()
Post
#12
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Nie bardzo rozumiem po co uzywasz regexp i szukasz po calym response... Po to uzywasz Panther by sie nie bawic w takie rzeczy
Twoje Witaj Robert pewnie jest w jakim div o jakiejs klasie. Robisz wiec $this->assertSelectorTextContains('#twojDIV', 'Witaj Robert'); -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Cytat $this->assertSelectorTextContains('#twojDIV', 'Witaj Robert'); Metoda jest niezdefiniowana... Nie mogę jej użyć. Kod preg_match( '/<p class="ok">\r\n (Welcome, Robert!)<br>/', (string) $response, $matches ); $this->assertEquals($matches[1], 'Welcome, Robert!'); Takie coś działa, ale nie wygląda to zbyt profesjonalnie. :] PS Zdaje się, że w PHPUnit 9.6 część dawnych metod została usunięta, ale można użyć takie coś: Kod <?php
declare(strict_types=1); namespace App\Tests\Controller; use Symfony\Component\BrowserKit\HttpBrowser; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Panther\PantherTestCase; class MainPageControllerTest extends PantherTestCase { public function testMainPageTitleAndForm(): void { $browser = new HttpBrowser(HttpClient::create()); $browser->request('GET', '/'); $response = $browser->getResponse(); $this->assertStringContainsString( '<title>PHP Framework from EEQSOFT</title>', (string) $response ); $browser->clickLink('Polish'); $response = $browser->getResponse(); $this->assertStringContainsString( '<title>PHP Framework od EEQSOFT</title>', (string) $response ); $browser->clickLink('Angielski'); $browser->submitForm('Confirm', ['name' => 'Robert']); $response = $browser->getResponse(); $this->assertStringContainsString( 'Welcome, Robert!', (string) $response ); } } Ten post edytował eerie 22.03.2025, 11:53:01 |
|
|
![]()
Post
#14
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Cytat Metoda jest niezdefiniowana... Nie mogę jej użyć. To uzyj innej, podobnej, moze zmienili nazwe troche czy cos takiego -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
To uzyj innej, podobnej, moze zmienili nazwe troche czy cos takiego Przeszukałem wszystkie assertions w dokumentacji i nic podobnego nie znalazłem. ![]() ![]() PS Wygląda mi, jakby pousuwali sporo metod i ostro to uprościli. |
|
|
![]()
Post
#16
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Ale czemu ty tego szukasz w phpunit?
To jest w Panther a nie w phpunit https://github.com/symfony/panther/blob/mai...rtionsTrait.php -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#17
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Przeanalizowałem klasę PantherTestCase dla v2.0.0 mojej instalacji Panther'a. Bez instalacji FrameworkBundle Symfony klasa WebTestCase jest niedostępna i klasa abstrakcyjna PantherTestCase rozszerza TestCase PHPUnit oraz używa PantherTestCaseTrait, a nie WebTestAssertionsTrait. Przez to metody takie jak assertSelectorTextContains() są niedostępne. Nie wiem, czy powiniennem zainstalować specjalnie FrameworkBundle... I czy to będzie działać? Prościej będzie użyć metody assertStringContainsString() z PHPUnit, jak ja to zrobiłem w moim teście MainPageControllerTest.
Metoda assertSelectorTextContains() i tak używa assertStringContainsString(): Kod public static function assertSelectorTextContains(string $selector, string $text, string $message = ''): void { self::assertStringContainsString($text, self::getText($selector), $message); } Dlatego można spokojnie użyć tej metody... Tak myślę... Kod $this->assertStringContainsString(
'<title>PHP Framework from EEQSOFT</title>', (string) $response ); |
|
|
![]()
Post
#18
|
|
![]() Grupa: Moderatorzy Postów: 36 556 Pomógł: 6314 Dołączył: 27.12.2004 ![]() |
Aha. To by wyjasnialo pare rzeczy
![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#19
|
|
Grupa: Zarejestrowani Postów: 109 Pomógł: 0 Dołączył: 3.08.2017 Ostrzeżenie: (0%) ![]() ![]() |
Napisałem kilka testów dla klas source'a. Nie da się zbytnio przetestować Controller'ów i Service'ów, przynajmniej ja nie wiem jak, więc użyłem HttpBrowser. Przetestowałem też Repository, ale moje testy ingerują w dane bazy danych. Nie wiem, czy tak można? Przetestowałem też Validator'a z użyciem Mock'a dla klasy CsrfToken, która zapisuje token w sesji... Czy macie uwagi? Popełniłem rażące błędy, które wypada poprawić?
PS Wypadałoby chyba przetestować jeszcze Core'a? Czyli rdzenne klasy mojego framework'a... ![]() |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 29.04.2025 - 07:37 |