Please see our main guide.
OpenFGA strives to maintain good code coverage with tests so that the possibility of regressions is reduced.
The purpose of this guide is to inform contributors where to write new tests.
- Any change to the OpenFGA storage interface must have an integration test in
pkg/storage/test/storage.go
. This is so that anyone writing their own storage adapter can have confidence that it is correct.
-
All APIs use an underlying
command
object. These commands must have- Unit tests. For example, Write API is backed by Write Command, which has unit tests in
pkg/server/commands/write_test.go
. These should target mocked dependencies to cover the majority of the business logic. If you are changing business logic, add a test in the appropriate commands test file. - Exported integration tests in
pkg/server/test/server.go
. These take in an unmockeddatastore
dependency. The goal of these is to test that the command and the underlying datastore work well. This is so that anyone who writes their own implementation of the datastore can run these tests by doing
import openfgatest "github.com/openfga/openfga/pkg/server/test" openfgatest.RunAllTests(t, datastore)
NOTE TO MAINTAINERS: ideally, these integration tests shouldn't exist. They are the result of not having enough coverage at the storage interface layer.
- Unit tests. For example, Write API is backed by Write Command, which has unit tests in
-
Functional tests in
tests/functional_test.go
. These are tests for validating the API inputs and functional API behavior. The inputs are defined in the proto files (https://github.com/openfga/api). -
Some APIs' behavior can be fine-tuned with server flags. If this is the case, the tests for the correct wiring of the flags live in
pkg/server/server_test.go
. -
Some APIs set specific response headers. If this is the case, update the test
TestHTTPHeaders
incmd/run/run_test.go
.
Take the Check API. Aside from the tests mentioned in "All APIs", it has:
-
Exported integration tests in
tests/check/check.go
. These take in aclient
dependency. This is so that anyone who writes their own version of the server and/or datastore can run these tests by doingimport "github.com/openfga/openfga/tests/check" check.RunAllTests(t, client)
The reason these tests live here is because:
- the test cases are defined using easy-to-write YAML files. This enables us to write test cases that apply to all query APIs. (If one Check returns
allowed=true
, the corresponding ListObjects call will, depending on server parameters and other factors, also include it in the response.) - since these tests are exported, it allows authors of datastores to get extra confidence that their implementations of some methods related to Read of Tuples are correct.
- the test cases are defined using easy-to-write YAML files. This enables us to write test cases that apply to all query APIs. (If one Check returns
NOTE TO MAINTAINERS: ideally, these tests need not be exported, since they are testing for correctness and should be independent of the storage layer. They are the result of not having enough coverage with unit tests.
- One test that asserts on the log fields that are emitted:
TestCheckLogs
intests/check/check_test.go
.
NOTE TO MAINTAINERS: ideally, we have a similar test for other APIs as well.
OpenFGA can be run within Docker. If changing any of the commands, or changing the Dockerfile itself, the tests in cmd/openfga/main_test.go
must be updated.