BDD (Behavior Driven Design) was a term coined by Dan North, and the best source for understanding his intent was this great blog post.
Here you can read that Dan wants to shift focus from the testing details to describe the behavior. Of course, this can (and has always been) interpreted in so many ways :). Therefore, wherever you turn, you will get a stubborn look - this is mine.
The idea with cucumber tools like SpecFlow is to write to the team a general understanding of the function in a language and instrument that all those involved can read and understand. This is done (again in cucumber-based tools) by recording several scenarios or examples of how this function can be used. Some people call this specification an example.
Some kindness arises from writing specifications by using examples as follows:
- you can discuss the behavior of a function before implementing it
- specifications give you an excellent specification for code after using an external approach
- specifications over time become regression tests that verify that the system behaves as directed
- the specification also goes through the old promise of TDD and becomes living documentation for the system. You can easily see what the current state of a function is by looking at the executable specification passed by that function.
So, now, finally, to your question (which, incidentally, is excellent, which I often asked myself and others). Sorry to paraphrase it, I hope I catch your intention:
Should my scripts (or should they) work against the user interface?
You are sure that you do not need to run scripts against the user interface - the principles of BDD and tools work perfectly against your domain at any level.
But in order to make the most of your specifications, you should consider my (unconvincing) list above. If you do not include a graphical interface (or a database or services, etc.), you cannot be sure that the entire application stack works correctly together. Therefore, specifications are often run from end to end.
And this makes these βtestsβ something very different from your unit tests (which you want quickly, like lightning, bullying external dependencies without getting into the database, etc.). They take more time to execute, all of them should not be launched at each registration, do not use mock, etc.
Often you start with a script stage and as a driver for behavior, and then use a regular TDD to extract the details of the internal system. This is external programming.
Finally, to your example above. Therefore, I recommend that you run your specifications against the user interface from end to end to the database; but I would advise you to describe the interface in technical terms, as described above (for example, using buttons, links, and text fields). When I asked this question in the Google BDD group, I got great advice from Elizabeth Keoch:
Do not describe the user interface. Describe what you are trying to achieve using the user interface.
So, to describe the login function, do not write:
Scenario: Login (describing the UI) Given I am on the Login-page When I enter 'AUser' in the textbox 'UserName' And I enter 'APassword' in the textbox 'Password' And I click the 'Login' button Then I should see the following text 'You are logged in'
rather write it something like this:
Scenario: Login (describing what we want to achieve) Given I am not logged in When I log in using 'AUser' and 'APassword' Then I should be logged in
This leaves complexity in how this is done (click buttons, filling out forms, checking messages, etc.) is carried out in the definitions of the steps that you write in the code.
Hope this was helpful. I also support myself for some of the βbeatingsβ that may come from other, more experienced BDD people. But hey, these are my two cents :)