This guide outlines standards and best practices for automated testing of GitLab CE and EE.
It is meant to be an extension of the thoughtbot testing styleguide. If this guide defines a rule that contradicts the thoughtbot guide, this guide takes precedence. Some guidelines may be repeated verbatim to stress their importance.
GitLab uses factory_girl as a test fixture replacement.
spec/factories/, named using the pluralization of their corresponding model (
Userfactories are defined in
ActiveRecordobjects. See example.
Warning: Keep in mind that a Rails view may change and invalidate your test, but everything will still pass because your fixture doesn't reflect the latest view.
Keep in mind that in a CI environment, these tests are run in a headless browser and you will not have access to certain APIs, such as
Notification, which will have to be stubbed.
described_classinstead of repeating the class name being described.
.methodto describe class methods and
#methodto describe instance methods.
contextto test branching logic.
after, even when it would fit on a single line.
describesymbols (see Gotchas).
:eachargument to hooks since it's the default.
to_not(this is enforced by Rubocop).
Gitlab.config.gitlab.hostrather than hard coding
GitLab's RSpec suite has made extensive use of
let variables to reduce duplication. However, this sometimes comes at the cost of clarity, so we need to set some guidelines for their use going forward:
letvariables are preferable to instance variables. Local variables are preferable to
letto reduce duplication throughout an entire spec file.
letto define variables used by a single test; define them as local variables inside the test's
letvariable inside the top-level
describeblock that's only used in a more deeply-nested
describeblock. Keep the definition as close as possible to where it's used.
letvariable with another.
letvariable that's only used by the definition of another. Use a helper method instead.
GitLab has a massive test suite that, without parallelization, can take more than an hour to run. It's important that we make an effort to write tests that are accurate and effective as well as fast.
Here are some things to keep in mind regarding test performance:
spyare faster than
.build_stubbedare faster than
createan object when
doublewill do. Database persistence is slow!
create(:project)when you don't need the underlying Git repository. Filesystem operations are slow!
js: truein RSpec) unless it's actually required for the test to be valid. Headless browser testing is slow!
spec/features/and should be named
ROLE_ACTION_spec.rb, such as
featureblock per feature spec file.
GitLab moved from Cucumber to Spinach for its feature/integration tests in September 2012.
Adding new Spinach scenarios is acceptable only if the new scenario requires no more than one new
step definition. If more than that is required, the test should be re-implemented using RSpec instead.
To make testing Rake tasks a little easier, there is a helper that can be included in lieu of the standard Spec helper. Instead of
require 'spec_helper', use
require 'rake_helper'. The helper includes
spec_helper for you, and configures a few other things to make testing Rake tasks easier.
At a minimum, requiring the Rake helper will redirect
stdout, include the runtime task helpers, and include the
RakeHelpers Spec support module.
RakeHelpers module exposes a
run_rake_task(<task>) method to make executing tasks simple. See
spec/support/rake_helpers.rb for all available methods.
require 'rake_helper' describe 'gitlab:shell rake tasks' do before do Rake.application.rake_require 'tasks/gitlab/shell' stub_warn_user_is_not_gitlab end describe 'install task' do it 'invokes create_hooks task' do expect(Rake::Task['gitlab:shell:create_hooks']).to receive(:invoke) run_rake_task('gitlab:shell:install') end end end