driftctl uses both **unit test** and **acceptance test**.
Acceptance test are not required, but at least a good unit test coverage is required for a PR to be merged.
This documentation section's goal is about how we manage our test suite in driftctl.
driftctl uses gotestsum to wrap `go test`, you can install required tools to run test with `make install-tools`
To run unit test simply run
```shell script
make install-tools
make test
```
Before the test suite starts, we run `golangci-lint`.
If there are any linter issues, you have to fix them first.
For the driftctl team, code coverage is very important as it helps show which part of your code is not covered.
We kindly ask you to check your coverage to ensure every important part of your code is tested.
We do not expect 100% coverage for every line of code, but at least every critical part of your code should be covered.
For example, we don't care about covering `NewStruct()` constructors if there is no big logic inside.
Remember, a covered code does not mean that every condition is tested and asserted, so be careful to test the right things.
A bug can still happen in a covered part of your code.
We use the golden file pattern to assert on results. Golden files could be updated with `-update flag`.
For example, I've made some modifications to s3 bucket policy, I could update golden files with the following command:
```shell script
go test ./pkg/remote/aws/ --update s3_bucket_policy_no_policy
```
⚠️ Beware that updating golden files may call external services.
In the example above, as we are using mocked AWS responses in json golden files, you should have to configure proper resources on AWS side before running an update.
For convenience, we try to put, as much as possible, terraform files used to generate golden files in test folders.
**A quick way to get started is to copy/paste an existing test and adapt it to your needs.**
## Unit testing
Unit testing should not use any external dependency, so we mock every call to the cloud provider's SDK (see below for more details on mocking)
### Mocks
In driftctl unit test suite, every call to the cloud provider's SDK should be mocked.
We use mocks generated by mockery in our tests.
See below each step to create a mock for a new AWS service (e.g. EC2).
1. Create a mock interface in `test/aws/ec2.go`
```go
package aws
import (
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)
type FakeEC2 interface {
ec2iface.EC2API
}
```
2. Use mockery to generate a full mocked struct `mockery --name FakeS3 --dir ./test/aws`
3. Mock a response in your test (list IAM users for example)
⚠️ If you have several mocks on the same method, the "mock" library will evaluate code in your `MatchedBy` multiple times even if the first parameter does not match.
It means your callback will always be called, this is an unwanted behaviour most of the time!
A workaround is to manage flags but this is an ugly solution, here is an example using a boolean flag: