diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | composer.json | 3 | ||||
-rw-r--r-- | composer.lock | 68 | ||||
-rw-r--r-- | doc/tests.markdown | 31 | ||||
-rw-r--r-- | tests/acceptance.xml | 13 | ||||
-rw-r--r-- | tests/acceptance/Base.php | 18 | ||||
-rw-r--r-- | tests/acceptance/UserAuthenticationTest.php | 86 |
7 files changed, 219 insertions, 3 deletions
@@ -57,6 +57,9 @@ test-postgres: unittest: test-sqlite test-mysql test-postgres +test-browser: + @ phpunit -c tests/acceptance.xml + sql: @ pg_dump --schema-only --no-owner --no-privileges --quote-all-identifiers -n public --file app/Schema/Sql/postgres.sql kanboard @ pg_dump -d kanboard --column-inserts --data-only --table settings >> app/Schema/Sql/postgres.sql diff --git a/composer.json b/composer.json index 2f6bec91..85fdb5ad 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "require-dev" : { "symfony/yaml" : "2.1", "symfony/stopwatch" : "~2.6", - "phpunit/phpunit" : "4.8.*" + "phpunit/phpunit" : "4.8.*", + "phpunit/phpunit-selenium": "^2.0" } } diff --git a/composer.lock b/composer.lock index 783d54cc..e0177ed5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "60ac519d67728cc5b125f77048d2e0c0", - "content-hash": "3dfc055d11c8010e9b16fb7df58c0f94", + "hash": "2de2026649db7bc41653bef80f974c6a", + "content-hash": "ea8ef74f1f1cf53b9f96b7609d756873", "packages": [ { "name": "christian-riesen/base32", @@ -1398,6 +1398,70 @@ "time": "2015-10-02 06:51:40" }, { + "name": "phpunit/phpunit-selenium", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/giorgiosironi/phpunit-selenium.git", + "reference": "2bad798ec0daf20d2854400e3bc5329ee0a7b2d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giorgiosironi/phpunit-selenium/zipball/2bad798ec0daf20d2854400e3bc5329ee0a7b2d1", + "reference": "2bad798ec0daf20d2854400e3bc5329ee0a7b2d1", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "php": ">=5.3.3", + "phpunit/phpunit": "~4.8", + "sebastian/comparator": "~1.0" + }, + "require-dev": { + "phing/phing": "2.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Giorgio Sironi", + "email": "info@giorgiosironi.com", + "role": "developer" + }, + { + "name": "Ivan Kurnosov", + "email": "zerkms@zerkms.com", + "role": "developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "original developer" + } + ], + "description": "Selenium Server integration for PHPUnit", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "selenium", + "testing", + "xunit" + ], + "time": "2016-03-01 10:33:56" + }, + { "name": "sebastian/comparator", "version": "1.2.0", "source": { diff --git a/doc/tests.markdown b/doc/tests.markdown index b2d95491..5e3d71d2 100644 --- a/doc/tests.markdown +++ b/doc/tests.markdown @@ -12,6 +12,8 @@ Requirements - PHP cli - PHPUnit installed - Mysql and Postgresql (optional) +- Selenium (optional) +- Firefox (optional) Unit Tests ---------- @@ -83,6 +85,11 @@ From your Kanboard directory, run the command `phpunit -c tests/units.postgres.x Integration Tests ----------------- +Acceptance tests (also known as end-to-end tests and sometimes functional tests) allow us to test the actual functionality of the browser using Selenium and PHPUnit. + +The PHPUnit config file is `tests/acceptance.xml`. +From your Kanboard directory, run the command `phpunit -c tests/units.sqlite.xml`. + Actually only the API calls are tested. Real HTTP calls are made with those tests. @@ -116,6 +123,30 @@ Time: 1.18 minutes, Memory: 14.75Mb OK (135 tests, 526 assertions) ``` +Acceptance Tests +----------------- + +Acceptance tests (also sometimes known as end-to-end tests, and functional tests) test the actual functionality of the UI in a browser using Selenium. + +In order to run these tests you must have [Selenium Standalone Server](http://www.seleniumhq.org/download/) installed, and a compatible version of Firefox. + +The PHPUnit config file is `tests/acceptance.xml`. +With Selenium and the Kanboard app running, from your Kanboard directory, run the command `make test-browser`. This will initiate the testing suite and you will see Firefox open automatically and perform the actions specified in the acceptance tests. + +Example: + +```bash +$ make test-browser +PHPUnit 4.8.26 by Sebastian Bergmann and contributors. + +.. + +Time: 5.59 seconds, Memory: 5.25MB + +OK (2 tests, 5 assertions) +``` + + Continuous Integration with Travis-CI ------------------------------------- diff --git a/tests/acceptance.xml b/tests/acceptance.xml new file mode 100644 index 00000000..a161f9ec --- /dev/null +++ b/tests/acceptance.xml @@ -0,0 +1,13 @@ +<phpunit stopOnError="true" stopOnFailure="true" colors="true"> + <testsuites> + <testsuite name="Kanboard"> + <directory>acceptance</directory> + </testsuite> + </testsuites> + <php> + <const name="SELENIUM_HOST" value="localhost" /> + <const name="SELENIUM_PORT" value="4444" /> + <const name="DEFAULT_BROWSER" value="firefox" /> + <const name="KANBOARD_APP_URL" value="http://localhost:8001" /> + </php> +</phpunit> diff --git a/tests/acceptance/Base.php b/tests/acceptance/Base.php new file mode 100644 index 00000000..e8684a9b --- /dev/null +++ b/tests/acceptance/Base.php @@ -0,0 +1,18 @@ +<?php + +class Base extends PHPUnit_Extensions_Selenium2TestCase +{ + + public function setUp() + { + $this->setHost(SELENIUM_HOST); + $this->setPort((integer) SELENIUM_PORT); + $this->setBrowserUrl(KANBOARD_APP_URL); + $this->setBrowser(DEFAULT_BROWSER); + } + + public function tearDown() + { + $this->stop(); + } +} diff --git a/tests/acceptance/UserAuthenticationTest.php b/tests/acceptance/UserAuthenticationTest.php new file mode 100644 index 00000000..3313e050 --- /dev/null +++ b/tests/acceptance/UserAuthenticationTest.php @@ -0,0 +1,86 @@ +<?php + +require_once __DIR__.'/Base.php'; + +class UserAuthenticationTest extends Base +{ + + public function validLoginInputsProvider() + { + $inputs[] = [ + [ + 'username' => 'admin', + 'password' => 'admin', + ] + ]; + + return $inputs; + } + + public function invalidLoginInputsProvider() + { + $inputs[] = [ + [ + 'username' => 'wrong_username', + 'password' => 'wrong_password', + ] + ]; + + return $inputs; + } + + /** + * @dataProvider validLoginInputsProvider + */ + public function testValidLogin(array $inputs) + { + $this->url('/'); + $this->assertContains('Login', $this->title()); + + $form = $this->byTag('form'); + foreach ($inputs as $input => $value) { + $form->byName($input)->value($value); + } + $form->submit(); + + $content = $this->byClassName('sidebar')->text(); + $this->assertContains($inputs['username'], $content); + } + + /** + * @dataProvider invalidLoginInputsProvider + */ + public function testInvalidLogin(array $inputs) + { + $this->url('/'); + + // Test wrong username with correct password + $form = $this->byTag('form'); + $form->byName('username')->value($inputs['username']); + $form->byName('password')->value('admin'); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + // Test wrong password with correct username + $form = $this->byTag('form'); + $form->byName('username')->value('admin'); + $form->byName('password')->value($inputs['password']); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + // Test wrong username and password + $form = $this->byTag('form'); + $form->byName('username')->value($inputs['username']); + $form->byName('password')->value($inputs['password']); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + + } +} |