Skip to main content

Testing Code

We test the Chemotion ELN using three different kinds of tests.

1. JavaScript unit tests (mocha)

 npm test

2. Ruby unit tests (RSpec)

RAILS_ENV=test bundle exec rake db:test:prepare && bundle exec rspec --exclude-pattern spec/features/**/*_spec.rb

3. Acceptance (feature) tests (Capybara)

Deprecated chapter

currently the system testing is in transition to the Cypress framework. Once finished the documentation will be added

RAILS_ENV=test bundle exec rake db:test:prepare && bundle exec rake assets:precompile && bundle exec rspec spec/features

General rules of thumb

  • All public methods should be tested, every statement, conditional branch should be covered.
  • Tests should be easy to read and understand. Try to use a maximum of 3 describe/context levels:
    • Describe: What is the class/method I want to test?
    • Context: Under what circumstances is the method tested?
    • It: What do I expect?
  • Verifying UI state should not be the focus of unit testing (with the exception of snapshot testing in JavaScript).
  • Useful resources

Javascript Unit tests

  • Test files should be placed in spec/javascript/..., mirroring the location of the source file (i.e., the file under test).
  • Test files should have the name of the file under test but end with .spec.js.
  • For simple plain JavaScript objects, test every "public" method. Without access modifiers, look what methods are called by other components.

Testing React components

  • Use the Enzyme library to create React components: wrapper = shallow(<CLASS_OF_COMPONENT/>);
  • React components can be used with their JavaScript-state or their HTML representation: wrapper.instance() and wrapper.html()
  • Example: ResearchPlanDetailsFieldImage.spec.js

When testing a component which includes a store you need to explicitly import he store in the test file. The import must be before the import statement of the component to test. The linter recognizes that the store dependency is not used and tries to eliminate it. You can prevent this by manually disabling the linter rule for these lines. Example: ResearchPlanDetails.spec.js


Creating models with factories

  • To create model objects, we use the library factory-bot
  • const researchPlan = await'empty');
  • By using a pseudoRandomGenerator in the factory for ids and checksums we can create reproducible objects
  • One can reset the generator by adding a build option: const researchPlan = await'empty', {}, { reset: true });

Creating a model is an asynchronous action, so the test must also be asynchronous: it('no img tag should be rendered', async function (){ }

Snapshot testing

Deprecated chapter

Currently no snapshot testing is applied due to lack of capacity. In addition, ui testing will be covered by the system tests in the future.

  • When testing a React component, we want to verify the state of the component. An easy way to achieve this would be to check if its HTML state is as expected.
  • By using the snapshot library expect-mocha-snapshot, a snapshot of the HTML state is generated at the first test run. After that, the state in the test is checked against the saved state from the first run.
  • Snapshots are saved in a folder snapshots at the same level of the test
  • Snapshots are not only restricted to HTML but can also be used for JSON or JavaScript-objects
  • Example: ResearchPlanDetailsFieldImage.spec.js

The expect extension by mocha refers to the current test-object by this. Using an lambda expression at the it definition, mocha have no access to it. Using an explicit function definition solves this problem.

Ruby Unit tests

Common infos

  • Tests should reflect the structure of the source package. That means having the exact same location and name ending with _spec.rb.
  • Example test

Creating database models with factory bot

  • Models can be created using the library factory bot. In factories, desired states of the models are predefined and can then be created using create (creates a DB entry) or build (creates a model without a DB entry).

Creating an attachment with factorybot must be handled carefully because create also triggers the create_derivative method and could remove a fixture file. By using build the create_derivative method is not executed, but one has no object in the database and some properties are not initialized.

Testing methods without classes

  • can be done by adding type :helpers Rspec.describe GenericHelpers, type: :helper do.
    Example generic_helpers_spec.rb


  • REST calls

Many REST requests that request INCHI keys are already defined in spec_helper.rb

  • Methods of classes/objects
    allow_any_instance_of(CLASS_NAME).to receive(METHOD_NAME_AS_SYMBOL).and_return(RESULT)
    allow_any_instance_of(CLASS_NAME).to receive(METHOD_NAME_AS_SYMBOL).and_raise(AN ERROR)
  • for more infos: rspec-mocks

API - testing

  • Tests for the api have to be in the subfolder spec/api/... to work properly

Acceptance tests

When you have freshly installed Chemotion ELN, make sure to create a file in the public directory inside Chemotion ELN before running acceptance tests. You can create it from the example file:


Infos about code coverage: Code Coverage

JavaScript unit tests

  • Using npm run coverage creates a coverage report in HTML written in .coverage. The method of covering is condition coverage.
  • in package.json one can exclude directories from coverage
  • Coverage is currently not included in CI

Rspec unit tests

By running the rspec unit tests, the coverage is currently calculated automatically. The results can be found in the folder .coverage