Commit 219bd6e8 authored by Christian Ceelen's avatar Christian Ceelen Committed by Pierre Smeyers
Browse files

feat(bats): add opt-in coverage support with Bashcov

parent 83cf4366
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
{
    "name": "Bash Bats",
    "image": "mcr.microsoft.com/devcontainers/base:alpine",
    "features": {
        "ghcr.io/edouard-lopez/devcontainer-features/bats:0": {},
        // "ghcr.io/lukewiwa/features/shellcheck:0": {} # lacks alpine support

    },
    "customizations": {
        "vscode": {
            "extensions": [
                "mads-hartmann.bash-ide-vscode",
                "foxundermoon.shell-format",
                "jetmartin.bats",
                "GitLab.gitlab-workflow"
            ]
        }
    },
    "postStartCommand": "sudo apk add --update shellcheck bats ruby ; sudo gem install simplecov bashcov",
    "remoteEnv": {
        "BATS_LIBRARIES_DIR": "/usr/lib/bats"
    }
}
 No newline at end of file

.gitignore

0 → 100644
+2 −0
Original line number Diff line number Diff line
coverage
reports
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@ variables:
  GITLAB_CI_FILES: "templates/gitlab-ci-bash.yml"
  BASH_SHELLCHECK_FILES: "*.sh"
  BASH_BATS_ENABLED: "true"
  BASH_BATS_LIBRARIES: "bats-support@https://github.com/bats-core/bats-support/archive/v0.3.0.zip bats-assert@https://github.com/bats-core/bats-assert/archive/v2.1.0.zip"
  BASH_BATS_LIBRARIES: "bats-support@https://github.com/bats-core/bats-support/archive/v0.3.0.zip bats-assert@https://github.com/bats-core/bats-assert/archive/v2.1.0.zip bats-file@https://github.com/bats-core/bats-file/archive/v0.4.0.zip"
  BASH_COVERAGE_ENABLED: "true"

semantic-release:
  rules:

.simplecov

0 → 100644
+15 −0
Original line number Diff line number Diff line
require 'simplecov'
require 'simplecov-cobertura'
SimpleCov.start do
  coverage_dir 'reports'
  if ENV['CI']
    formatter SimpleCov::Formatter::MultiFormatter.new([
          SimpleCov::Formatter::CoberturaFormatter,
          SimpleCov::Formatter::SimpleFormatter
        ])
  else
    formatter SimpleCov::Formatter::SimpleFormatter
  end
  add_filter "tests/*"
  track_files '**/*.sh'
end
+63 −0
Original line number Diff line number Diff line
@@ -62,12 +62,18 @@ The job uses the following variables:
| `bats-tests` / `BASH_BATS_TESTS` | The path to a Bats test file, or the path to a directory containing Bats test files | `tests`           |
| `bats-opts` / `BASH_BATS_OPTS` | Bats [options](https://bats-core.readthedocs.io/en/stable/usage.html)                | _none_ |
| `bats-libraries` / `BASH_BATS_LIBRARIES` | Coma separated list of Bats [libraries and add-ons](https://bats-core.readthedocs.io/en/stable/writing-tests.html#libraries-and-add-ons) (formatted as `lib_name_1@archive_url_1 lib_name_2@archive_url_2 ...`) | _none_ |
| `coverage-enabled` / `BASH_COVERAGE_ENABLED` | Set to `true` to enable coverage measurement. [Using Bashcov](https://github.com/infertux/bashcov) | `false` |
| `coverage-formatters` / `BASH_COVERAGE_FORMATTERS` | Comma separated list of coverage report [formatters](https://github.com/simplecov-ruby/simplecov/blob/main/doc/alternate-formatters.md) and optional library/package name. Formatted as: `package-name1@formatter-class1, package-name2@formatter-class2 ...` | `SimpleCov::Formatter::SimpleFormatter` |
| `coverage-track-files` / `BASH_COVERAGE_TRACK_FILES` | Glob pattern of files to track coverage | `**/*.sh` |
| `coverage-filters` / `BASH_COVERAGE_FILTERS` | Comma separated list of files and directories to filter out from your coverage data (e.g. 'tests/*, .tools' ). | _none_ |


In addition to a textual report in the console, this job produces the following reports, kept for one day:

| Report         | Format                                                                       | Usage             |
| -------------- | ---------------------------------------------------------------------------- | ----------------- |
| `reports/*.bats.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportsjunit) |
| `reports/bash-coverage.cobertura.xml` | [cobertura](https://rubygems.org/gems/simplecov-cobertura) code coverage report | [Gitlab integration](https://docs.gitlab.com/ci/testing/code_coverage/cobertura/) |

#### How to manage libraries and add-ons

@@ -93,3 +99,60 @@ load "$BATS_LIBRARIES_DIR/bats-assert/load.bash"
    assert_line "Hello there"
}
```

#### Manage your own coverage configuration

Code coverage with Bats is based on [BashCov](https://github.com/infertux/bashcov) which is a wrapper around [SimpleCov](https://github.com/simplecov-ruby/simplecov?tab=readme-ov-file#maximum-coverage-drop) for Bash.

In order to access advanced configuration features (for example quality gate with minimum line/branch coverage, maximum coverage drop or else) all you have to do is to commit your own .simplecov configuration to the root of your Git repository.
Doing so, be aware that the template implementation expects some configuration to be set. Here is a basic .simplecov that you may use as a starting point to build your own:

```ruby
# /!\ MANDATORY for using bashcov and to-be-continuous
require 'simplecov'
require 'simplecov-cobertura'
# import additional libraries / plugins here (e.g. 'simplecov-csv')

SimpleCov.start do
  # /!\ MANDATORY for to-be-continuous
  coverage_dir 'reports'
  # Can be customized
  track_files '**/*.sh'
  # Can be customized with your own formatters
  # /!\ CoberturaFormatter is MANDATORY for the gitlab reporting of to-be-continuous
  formatter SimpleCov::Formatter::MultiFormatter.new([
    SimpleCov::Formatter::SimpleFormatter,
    SimpleCov::Formatter::CoberturaFormatter
  ])
  # >> Here you can add your extra options <<
end
```

Extra options can be:

- [filters](https://github.com/simplecov-ruby/simplecov?tab=readme-ov-file#filters)
- [minimum coverage](https://github.com/simplecov-ruby/simplecov?tab=readme-ov-file#minimum-coverage)
- [maximum coverage drop](https://github.com/simplecov-ruby/simplecov?tab=readme-ov-file#maximum-coverage-drop)
...

##### Conditional Configuration


You may implement conditional configuration whether you're using SimpleCov locally or in GitLab CI/CD based on the presence of the $CI variable:

```ruby
SimpleCov.start do
  ...
  if ENV['CI']
    formatter SimpleCov::Formatter::MultiFormatter.new([
      # /!\ CoberturaFormatter is mandatory for the GitLab coverage reporting
      SimpleCov::Formatter::CoberturaFormatter,
      SimpleCov::Formatter::SimpleFormatter
    ])
  else
    # locally generate html report
    formatter SimpleCov::Formatter::HTMLFormatter
  end
  ...
end
```
Loading