7.2 KiB
Testing the Frontend
Tests are divided into three categories;
- Karma based unit tests (AngularJS components only, standalone)
- protractor and mock based integration testing (AngularJS components only, standalone)
- Capybara/Cucumber/RSpec based tests (feature based and spec based, require the full Rails)
All of these are currently run on TravisCI for each push and each Pull Request.
Karma Unit tests
Note: the default browser for testing is PhantomJS. The configuration for all of this can be found at /frontend/karma.conf.js
.
All test files for karma
live in ./frontend/tests/unit/tests
. There are some factories
and mocks
present, which at some point in time were usable via rosie.js
.
Karma unit tests can be executed via
./frontend/node_modules/.bin/karma start
Optionally, if more than the default browser should be used, a --browsers
flag can be passed:
./frontend/node_modules/.bin/karma start --browsers PhantomJS,Firefox
By default, this command will wait and watch the test files and run the tests again if something changes. If only one run is required, use a --single-run
flag.
You may also want to use npm
from the project root:
# shorthand for ./frontend/node_modules/.bin/karma start --browsers PhantomJS,Firefox --single-run
$ npm karma
The tests use mocha
for it's test syntax. With a syntax looking like this:
describe('my new feature', function() {
/* tests */
});
Individual parts of the test suite can easily be run independently from the suite by adding .only
to the DSLs constructs (describe
, context
, it
):
describe.only('my new feature', function() {
/* tests */
});
Note on Templates
The karma runner uses a plugin to precompile the templates for directive tests called ngHtml2JsPreprocessor
to avoid problems when testing directives in isolation from the rest of the other modules.
Protractor based integration testing
Note: All of the test files live in ./frontend/tests/integration/specs
.
The protractor based suite offers integration tests for the angular
based views, first and foremost, the WorkPackage (list) application. It's based on angular
s own protractor library and therefore requires Selenium.
It does not offer real End to End (E2E) Testing, as there is currently no way to start up the whole application beforehand, so the suite uses a mock server and mock json to test each component independently and in the context of a page.
Every command related to the suite is wrapped via gulp
. The commands are:
gulp tests:protractor
- starts up a server, recompiles the codebase necessary and starts a single run via protractor.gulp webdriver:*
- the webdriver tasks are in there to update the selenium server necessary to run protractor at allnpm protractor
- a wrapper aroundgulp tests:protractor
, runnable from the project root
Note: Protractor process uses the same static server as the styleguide. All assets are served from ./frontend/public
. To get a grip on the entry point, see ./frontend/public/index.html
.
The protractor
library brings it's own syntax when it comes to writing the tests themselves:
describe('edit state', function() {
before(function() {
editor.$('.inplace-editing--trigger-link').click();
});
context('dropdown', function() {
it('should be rendered', function() {
expect( /* ... */
Tests can be focused by using iit
(not a typo) instead of it
and can be ignored by using xit
instead of it.
Configuration is done in ./frontend/tests/integration/protractor.conf.js
. The only usable browser right now for protractor is Firefox. You can change your browser locally to Chrome if you want to, however, TravisCI so far only supports running tests via Firefox.
The protractor suite currently only covers the work packages list and provides no integration testing for timelines and the other components (most of them are tested as collateral).
Mocking
As the backend ist not present during testing, the protractor suite actually uses mocked json responses to facilitate the behaviour of data when testing the components.
Note: All mocks are found under ./frontend/tests/integration/mocks/
and are usually loaded via a custom function defined in the tests which wrap WorkPackageDetailsPane
, which in turn wraps a call to browser.get()
(see ./frontend/tests/integration/pages/work-package-details-pane.js
)
A mock usually just represents a probable json response from the backend. As the protractor suite does not use the Rails backend, this can be a source of confusion:
Make sure you keep your mocks in sync with the current implementation of the API. Otherwise you will not be able to detect problems with the API and/or your component.
Dummy servers
The protractor suite also used dummy services to mock out the endpoints of all of the APIs. These files are still found under ./frontend/tests/integration/mocks/
and can probably be removed in future versions.
Capybara/Cucumber/RSpec E2E Testing
The heavy lifting is done via these Testsuites, which are tightly integrated with the Rails stack (and not even part of the ./frontend
folder). Most of them actually test Rails views, but there are a few exceptions: The specs in ./spec/features/work_packages/details
test a good deal of features related to the Work Package Details pane.
A note on plugins & commands used
So far, no plugins provide an extension for the protractor suite. The protractor suite is only for the core (opf/openproject
itself). The coverage is not complete.
However, plugins to provide some integration tests based on RSpec, Capybara and cucumber. To run the tests of a plugin, the core is required.
Example: openproject-plugin
Assumptions:
- The plugin
openproject-plugins
exists on your local file system, parallel to a clone ofopenproject
- The plugin contains a
spec
folder and spec that form a suite to testing the plugin - The plugin is installed into the Installation of OpenProject located in
openproject
Note: For installing OpenProject plugins, please refer to ./doc/DEVELOP_PLUGINS.md
To run specs for a given plugin:
$ pwd
/home/user/code/openproject
$ rspec ../openproject-plugin/spec
Same with cucumber:
$ pwd
/home/user/code/openproject
$ cuke ../openproject-plugin/features
Note: cuke
is a very useful shorthand for:
function cuke() {
bundle exec rake cucumber:custom["$1"]
}
There are (in older branches) some legacy tests that might have to be executed,which can be done via:
$ pwd
/home/user/code/openproject
$ rake test:units TEST=../openproject-plugin/test
These older legacy tests have been migrated for version 4.1
, but can still popup in some older plugins, or even an old version of OpenProject. the legacy tests have been converted by @myabc
via gem and are located (for newer versions) here: ./spec/legacy/
. These should be removed in the future an be replaced by either proper specs or even complete features.