This is an interesting topic I came across and my co-workers and I have different opinions on the matter. Should your Gherkin describe exactly what the test is doing, or ONLY show the business logic you tried to achieve in the test.
The biggest example that I run into all the time at work is that if you have access to item A, then you should be able to access A. We can have 20 different types of users with access to A, so we only choose 1 (to keep our test suite from taking 40 hours to run). So which is "better"?
A
Scenario: A user with access to item A can access A
Given I am a type 4 user with access to item A
When I try to access A
Then I am granted access to A
or B
Scenario: A user with access to item A can access A
Given I am a user with access to item A
When I try to access A
Then I am granted access to A
Notice the difference in the given statements (type 4 user)
Granted in the step definition we are going to use a type 4 user for our test, but the test is not specific to a type 4 user. Any user with item A will work for this test, we're just using a type 4 user because we need a user type to login with.
So A describes what the test is doing (Logging in with a type 4 user with access to item A)
And B describes the functionality needed to access item A (just a user with access to item A)
Before you ask, how we determine who has access to item A is a SQL call to the database looking for a specific item linked to a user.
For a cucumber test you are testing the business logic - as an acceptance test - not hte specific implementation details. So you SHOULD do the second not the first. Your Request specs or Integration tests can be more tied to specifics if you want to run tests for type X, type Y and edge cases.
I think one can think of this - and it's not a hard fast rule - as something like:
Unit test to isolate methods and test one thing at a time. Mock & stub everything else to isolate what is being tested.
Integration tests to test how things interact together to test a larger part of your stack, including the interaction of multiple objects. Some would argue that you test everything soup to nuts here, but I think there's a place in a large complex app to test lots of pieces integrated while still not testing the full request cycle.
Request specs - sometimes in simple apps these are pretty much the same as integration tests, in other cases I will do integration tests for everything except the request stack and specifically separate out my request specs. Opinions will vary.
Acceptance tests - this is where you're sitting with your question - where the tests are written in plain business language and avoid technical implementation details within the feature definitions.
Anyway, even if you ignore the thoughts on the rest of the test stack, in the specific question you're asking go for B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With