HewlettPackard/oneview-puppet

View on GitHub
TESTING.md

Summary

Maintainability
Test Coverage
# Testing the 'oneview' module
The 'oneview' module provides a unit testing strategy and linting tools to help ensure its code style.
This document will cover on how to execute and implement these tests.

## Executing tests
The tests can be executed by `rake` tasks and by their original tools, like `rspec`, `rubocop`, `puppet-lint` and `puppet parser`.

### Rake
All the test strategies and checks can be executed by the rake command.
Please use `rake -T` to see a full list of commands.

### Examples
Every resource must have at least one example file, and one example inside it for each of its `ensure` states.
This example should aim to illustrate the common usage of that `resource` and its `ensure` states.

### Unit & Integration tests
All unit and integration tests are inside the spec folder. You can execute them manually by using `rspec` and specifying the test files, like `rspec spec/path/to/my/tests`.
If `bundler` was used to install the tools and test suite, which is a good practice, it is also recommended to run the unit tests prefixed by `bundle exec`, so that the correct gems and versions are used.

### Coverage
The unit tests issue a coverage report generated by `SimpleCov` and validated with `Coveralls`.

### Style checking
Style checking is performed by:
- `rubocop` for all the custom resource providers and types
- `puppet-lint` and `puppet parser` for manifests.

## Implementing tests
All code must have tests associated with it, and this section covers what tests need to be implemented.

### Minimum requisites
The necessary amount of testing is dictated by both the one performing the implementation and the one accepting the code, however, there is a floor acceptance level that must be followed:

- Each resource must have at least one example file in the [examples](examples) folder.
Inside those example files, at least one example on the usage of each `ensurable` property for a resource is **required**, with more examples being recommended for complex `ensure` states.

- All the custom provider and type methods are **required** to have unit tests hitting each of its lines of code, achieving 100% line coverage for this module.

### Examples
Examples on the usage of each `ensure` method available for a specific `resource` are a **requirement** for this module.

These examples should be written inside a `puppet manifest` by using a `resource declaration` style, and illustrating how a declaration of the `resource` and `ensure` state would be commonly used.

Example:
```puppet
oneview_fc_network{'fc1':
    ensure => 'present',
    data   => {
      name                    => 'OneViewSDK Test FC Network',
      connectionTemplateUri   => nil,
      autoLoginRedistribution => true,
      fabricType              => 'FabricAttach',
    }
}
```

These examples should also be used as a way to perform functional and OneView integration tests, but they need to be executed manually through the `puppet apply <manifest.pp>` command.

### Unit tests
Unit tests are **required** for each custom provider and type methods.

The custom providers and types are tested using the `rspec-puppet` and `rspec`, similar to pure `rspec` but enabling for the tests to call upon the puppet providers.

The actual tests are located in `spec/unit/providers` folder.

For each resource provider which contains code specific to it, a file should exist following the naming convention:

`<oneview/image_streamer><_resource_name><_specific_provider>_spec.rb`

- No unit test should require an appliance to run. Any calls to methods of the `oneview-sdk-ruby` which require communication to an appliance should have their expected return values `mocked`.
- `<_specific_provider>` is optional, if the resource does not have multiple providers it is not necessary.
- In case a `resource` possesses multiple `providers`, such as `C7000` and `Synergy`, and one of its `providers` only `inherits` from another provider and does not have code specific to it:

  It is not necessary to create spec files for both `providers`, as that would just lead to needless repetition.

  In such a case, the correct approach is to create a spec file specific to the `provider` that only `inherits` the code, and use it to test all of the methods. Ensuring line coverage and reducing needless repetition.

  Another good practice is to create *shared* tests which can be included into the `_spec` files and further reduce the amount of code repetition.

### Integration tests
The `Integration tests` are not a `requirement`, but provide an extra way to test complex methods against an appliance, in a way that might be too specific or would not add value to an example manifest.

These tests follow the same guidelines as the [Unit tests](#unit-tests) , with the key difference that these tests are expected to run against an appliance, so there is no need for `mock` calls.

The actual tests are located in `spec/integration/providers` and `spec/integration/types` folders.