cucumber / godog

Cucumber for golang
MIT License
2.22k stars 250 forks source link

Use `fs.FS` abstraction for filesystem #550

Closed tigh-latte closed 1 year ago

tigh-latte commented 1 year ago

🤔 What's changed?

Allow users to supply a fs.FS to files from. If not provided, we will fallback to the standard os file operations.

⚡️ What's your motivation?

As fs.FS is an interface it gives users flexibility beyond just the operating system's filesystem, such as mocking (see, for example, the tests. We no longer write data to /tmp) or at the very least, an in-memory fs. But the key feature is that it allows us to compile the feature files into an executable test binary, allowing that binary to be shipped independent from the feature files.

//go:embed features/*
var featuresData embed.FS

...

var opts = godog.Options{
    Paths: []string{"features"},
    FS:    featureData,
}

Then we can just:

> go test -c ./test/integration/integration_test.go
> mv integration.test /some/random/dir
> cd /some/random/dir
> ./integration.test

Currently I embed all test data into my test suite, and sometimes deploy these tests into a restricted environment for some non-user facing service tests in a live environment. With the current set up of godog, I have to also be concerned with shipping the feature files and placing them the correct location on the filesystem. This change would let users just fire a test binary into a scratch container and run without being concerned the underlying filesystem.

🏷️ What kind of change is this?

📋 Checklist:


This text was originally generated from a template, then edited by hand. You can modify the template here.

vearutop commented 1 year ago

This is a great feature, thank you!

I'm a bit concerned with the necessity of manual upgrade of existing code, as in

var opts = godog.Options{
    Paths: []string{"../testfiles/features"},
}

becomes

var opts = godog.Options{
    Paths: []string{"testfiles/features"},
    FS:    os.DirFS("../"),
}

It seems we can preserve backwards compatibility by having a special case for nil opts.FS, so that Paths are processed as before, what do you think?

tigh-latte commented 1 year ago

Sure we can do that, I'll see to sorting this at some point today.

tigh-latte commented 1 year ago

That's done here @vearutop

tigh-latte commented 1 year ago

@vearutop I fixed the build here, sorry about that.


# tigh in ~/go/src/github.com/tigh-latte/godog on git:enhancement/fs o
> go test ./...
ok      github.com/cucumber/godog       0.362s
?       github.com/cucumber/godog/cmd/godog     [no test files]
?       github.com/cucumber/godog/cmd/godog/internal    [no test files]
?       github.com/cucumber/godog/colors        [no test files]
ok      github.com/cucumber/godog/formatters    0.006s
ok      github.com/cucumber/godog/internal/builder      5.355s
ok      github.com/cucumber/godog/internal/flags        0.002s
ok      github.com/cucumber/godog/internal/formatters   0.026s
ok      github.com/cucumber/godog/internal/models       0.006s
ok      github.com/cucumber/godog/internal/parser       0.003s
ok      github.com/cucumber/godog/internal/storage      0.004s
ok      github.com/cucumber/godog/internal/tags 0.002s
?       github.com/cucumber/godog/internal/testutils    [no test files]
?       github.com/cucumber/godog/internal/utils        [no test files]
codecov[bot] commented 1 year ago

Codecov Report

Merging #550 (f9d3db5) into main (3bd9e9c) will increase coverage by 0.69%. The diff coverage is 84.78%.

@@            Coverage Diff             @@
##             main     #550      +/-   ##
==========================================
+ Coverage   82.24%   82.94%   +0.69%     
==========================================
  Files          27       28       +1     
  Lines        3340     3371      +31     
==========================================
+ Hits         2747     2796      +49     
+ Misses        484      461      -23     
- Partials      109      114       +5     
Impacted Files Coverage Δ
run.go 77.13% <69.56%> (+2.65%) :arrow_up:
internal/parser/parser.go 77.50% <100.00%> (+11.48%) :arrow_up:
internal/storage/fs.go 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

tigh-latte commented 1 year ago

@vearutop Ok I've added tests to cover the new storage.FS wrapper, and used fstest.MapFS to mock some file system failures to increase coverage in certain areas. Hopefully Codecov will be happy now.

aslakhellesoy commented 1 year ago

Hi @tigh-latte,

Thanks for your making your first contribution to Cucumber, and welcome to the Cucumber committers team! You can now push directly to this repo and all other repos under the cucumber organization! 🍾

In return for this generous offer we hope you will:

On behalf of the Cucumber core team, Aslak Hellesøy Creator of Cucumber