Should your BDD specifications be separated from your UI tests? - testing

Yesterday I went to a great presentation by Gojko Adzic about BDD. I might have missed one or two things he said so here is one question that hopefully will clear somethings up for me.
Often when you see BDD example online they have included steps in the UI. In a gherkin language you can often see something like:
Scenario: Successful booking
Given I am on the page ...
When I enter the following ...
Or something like that.
My question is, does that really have with BDD to do? Shouldn't BDD be targeted towards the domain and then you have those kind of tests as UI or regression tests. What I am thinking about is something like this use gherkin syntax to describe somekind of booking system:
BDD Spec:
Scenario: Successful booking
Given I am an authenticated user
When I place an order with the following items
| item | price ($) |
| book1 | 5 |
Then I should expect to pay $5
And I should get a confirmation mail of my order
Note that I am not mentoning the UI at all, I am only describing how the domain works and this test should be run on every build. Then you can have your UI test (also gherkin):
Scenario: Successful booking
Given I am logged in on the site
And I go to the page for item book1
And I click add to basket
Then I should have a basket with 1 item and $5
When I click checkout
Then I should get to the checkout page
and it continues, maybe it should be separated into two or three scenarios but that is not the point. Theses kind of tests are heavier to run and should probably only be run on nightly builds. The point of the question is still: Should you separated you BDD specs from your UI/regression test.

BDD boils down to collaboration between QA other non-technical people with the developers using native language as definitions for the functionality. So from this perspective, both of your examples are likely to be understood as a feature by the stakeholders.
But in general, the more abstract you can make the "story", the better. The difference,or potential issue, isn't so much about mentioning the UI, but potential assumptions and discussions about the layout. The initial workflow of the application is likely to change, so changes in the feature definition might require new discussions with the staeholders. Talks that might not really be required if the goal remains the same.
That said, practicality will come into play very quickly. An ambiguous feature definition will require a more exact definition for the ui, and that is in turn turned into a step definition or tests written with other UI testing tools. Writing the actual step definitions for the feature files is the hardest part so writing new scenarios is rather quick once you have a comprehensive set of step definitions in place. Not reusing these in UI tests seems like a waste, so we use the same set for UI tests.
We separate the UI tests only in the sense that not all scenarios are discussed with the stakeholdes. The most important ones tagged, and each feature has one or two scnearios tagged and the rest are UI tests. Also, sometimes the feature files are not written by the person writing the step definitions, so this allows the UI test writer to be less knowledgeable about the specifics how the UI operations are implemented in the framework in use.

Trying to separate out domain and UI tests is not recommended.
The big advantage of using Cucumber is that your specs (tests) can be read and understood by non-technical stakeholders. Those people probably aren't too concerned about user interface details.
So a good approach is to simply push the UI stuff down a layer to within the step definitions, e.g.
Given /^I place an order for "([^"]*)"$/ do |item|
visit catalog_url
click_link item
click_button "Add To Basket"
click_button "Submit Order"
end

Related

When and how much should I test third-party code integration when practicing behavior driven development (BDD)?

Context: I am trying to practice BDD in a Ruby on Rails environment using Capybara/Steak for integration tests, so that will be the example I use, but this question is a general question about BDD best practices.
Say I have an (admittedly broad) user story like so:
Feature:
As an administrator
I should be able to manage my products
I have been looking at the ActiveAdmin gem for Rails 3, which allows you to create sophisticated admin interfaces using a simple DSL. While the time-saving potential is huge, it also scares me to off-load so much functionality to third-party code without testing at all.
However, I've been taught that you generally only need to test code that you write yourself. So, by that logic, I just need to test that ActiveAdmin is integrated properly, since that's the only code I'm actually writing. A basic scenario to test this might be:
Scenario:
Given I have 20 products
When I visit the product index page
Then I should see 20 products.
This is a function offered by ActiveAdmin out of the box. So I could do the basic installation and create the Products Admin page using ActiveAdmin's documentation, and the scenario will pass.
Of course, then I have also integrated a massive number of other scenarios, such as:
Given I have 20 products
And my products include Apples, Bananas, and Berries
When I sort my products by name
Then Apples, Bananas and Berries should be on the first page in that order.
Given I have 20 products
And my products include Apples, Bananas, and Berries
When I type 'ap' into the Filter by Name field
Then I should see "Apples"
And I should not see "Bananas"
etc. etc.
Presumably though, these have already been tested by ActiveAdmin and so I shouldn't need to test them again, even though they are critical to my application. So I guess I'm done, and can move on to another feature(?).
TL;DR: My basic question is, should I be writing scenarios for critical functionality like sorting and filtering, even if they are already provided by an external library and I have tested my application's integration with that library?
The main advantage of BDD and scenarios is that it lets you share a common understanding through conversation about scenarios.
Since it looks like you're the only person on the team, the value you'll get from scenarios will come from thinking them through, capturing them for the future "you" who will use them as a reminder of what's already been developed, and automating them for use as regression tests.
You don't have to capture or automate scenarios if you think they're obvious. For obvious functionality which uses a library, it should be enough to be aware of that functionality, and only write scenarios around odd little edge cases if those exist.
This is because BDD's main focus is not about testing. BDD provides a vocabulary and conversational framework to help us share understanding - and, particularly, discover misunderstandings - making the software easier to change and maintain. We get to automate as a nice by-product.
If you want to actually test how your application works, you should go ahead and do that. If you're not changing the bits you're testing, then you only need to test it manually, once.
As a note, you're confusing the story and scenario templates, which won't help. Stories are normally small slices through features which have been broken down to get feedback faster.
As admin
I want to sort my products
So that I can find things easily by name.
A scenario is a specific example of the behavior of a feature, and normally uses the "Given, When, Then" syntax:
Given I have a 120 products
And my products include Apples, Bananas and Berries
When I sort my products by name
Then Apples, Bananas and Berries should be on the first page in that order
And the products should be paginated.
Quick answer, then: No, you don't need to write scenarios for behavior provided by software libraries. You can test them manually, then move on to the more interesting stuff.

Automatic testing for web based projects

Recently I've came up with the question is it worth at all to spent development time to generate automatic unit test for web based projects? I mean it seems useless at some point because at some point those projects are oriented on interactions with users/clients, so you cannot anticipate the whole possible set of user action so you be able to check the correctness of content showed. Even regression test can hardly be done. So I'm very eager to know to know the opinion of other experienced developers.
Selenium have a good web testing framework
http://seleniumhq.org/
Telerik are also in the process of developing one for web app testing.
http://www.telerik.com/products/web-ui-test-studio.aspx
You cannot anticipate the whole
possible set of user action so you be
able to check the correctness of
content showed.
You can't anticipate all the possible data your code is going to be handed, or all the possible race conditions if it's threaded, and yet you still bother unit testing. Why? Because you can narrow it down a hell of a lot. You can anticipate the sorts of pathological things that will happen. You just have to think about it a bit and get some experience.
User interaction is no different. There are certain things users are going to try and do, pathological or not, and you can anticipate them. Users are just inputting particularly imaginative data. You'll find programmers tend to miss the same sorts of conditions over and over again. I keep a checklist. For example: pump Unicode into everything; put the start date after the end date; enter gibberish data; put tags in everything; leave off the trailing newline; try to enter the same data twice; submit a form, go back and submit it again; take a text file, call it foo.jpg and try to upload it as a picture. You can even write a program to flip switches and push buttons at random, a bad monkey, that'll find all sorts of fun bugs.
Its often as simple as sitting someone down who's unfamiliar with the software and watching them use it. Fight the urge to correct them, just watch them flounder. Its very educational. Steve Krug refers to this as "Advanced Common Sense" and has an excellent book called "Don't Make Me Think" which covers cheap, simple user interaction testing. I highly recommend it. It's a very short and eye opening read.
Finally, the client themselves, if their expectations are properly prepared, can be a fantastic test suite. Be sure they understand its a work in progress, that it will have bugs, that they're helping to make their product better, and that it absolutely should not be used for production data, and let them tinker with the pre-release versions of your product. They'll do all sorts of things you never thought of! They'll be the best and most realistic testing you ever had, FOR FREE! Give them a very simple way to report bugs, preferably just a one button box right on the application which automatically submits their environment and history; the feedback box on Hiveminder is an excellent example. Respond to their bugs quickly and politely (even if its just "thanks for the info") and you'll find they'll be delighted you're so responsive to their needs!
Yes, it is. I just ran into an issue this week with a web site I am working on. I just recently switched-out the data access layer and set up unit tests for my controllers and repositories, but not the UI interactions.
I got bit by a pretty obvious bug that would have been easily caught if I had integration tests. Only through integration tests and UI functionality tests do you find issues with the way different tiers of the application interact with one another.
It really depends on the structure and architecture of your web application. If it contains an application logic layer, then that layer should be easy to unit test with automating tools such as Visual Studio. Also, using a framework that has been designed to enable unit testing, such as ASP.NET MVC, helps alot.
If you're writing a lot of Javascript, there have been a lot of JS testing frameworks that have come around the block recently for unit testing your Javascript.
Other than that, testing the web tier using something like Canoo, HtmlUnit, Selenium, etc. is more a functional or integration test than a unit test. These can be hard to maintain if you have the UI change a lot, but they can really come in handy. Recording Selenium tests is easy and something you could probably get other people (testers) to help you create and maintain. Just know that there is a cost associated with maintaining tests, and it needs to be balanced out.
There are other types of testing that are great for the web tier - fuzz testing especially, but a lot of the good options are commercial tools. One that is open source and plugs into Rails is called Tarantula. Having something like that at the web tier is a nice to have run in a continuous integration process and doesn't require much in the form of maintenance.
Unit tests make sense in TDD process. They do not have much value if you don't do test-first development. However the acceptance test are a big thing for quality of the software. I'd say that acceptance test is a holy grail of the development. Acceptance tests show whether the application satisfies the requirements. How do I know when to stop developing the feature --- only when all my acceptance test pass. Automation of acceptance testing a big thing because I do not have to do it all manualy each time I make changes to the application. After months of development there can be hundreds of test and it becomes unfeasible (sometime impossible) to run all the test manually. Then how do I know if my application still works?
Automation of acceptance tests can be implemented with use of xUnit test frameworks, which makes a confusion here. If I create an acceptance test using phpUnit or httpUnit is it a unit test? My answer is no. It does not matter what tool I use to create and run test. Acceptance test is the one that show whether the features is working IAW requirements. Unit test show whether a class (or function) satisfies the developer's implementation idea. Unit test has no value for the client (user). Acceptance test has a lot of value to the client (and thus to developer, remember Customer Affinity)
So I strongly recommend creating automated acceptance tests for the web application.
The good frameworks for the acceptance test are:
Sahi (sahi.co.in)
Silenium
Simpletest (I't a unit-test framework for php, but includes the browser object that can be used for acceptance testing).
However
You have mentioned that web-site is all about user interaction and thus test automation will not solve the whole problem of usability. For example: testing framework shows that all tests pass, however the user cannot see the form or link or other page element due to accidental style="display:none" in the div. The automated tests pass because the div is present in the document and test framework can "see" it. But the user cannot. And the manual test would fail.
Thus, all web-applications needs manual testing. The automated test can reduce the test workload drastically (80%), but manual test are as well significant for the quality of the resulting software.
As for the Unit testing and TDD -- it make the code quality. It is beneficial to the developers and for the future of the project (i.e. for projects longer that a couple of month). However TDD requires skill. If you have the skill -- use it. If you don't consider gaining the skill, but mind the time it will take to gain. It usually takes about 3 - 6 month to start creating a good Unit tests and code. If you project will last more that a year, I recommend studding TDD and investing time in proper development environment.
I've created a web test solution (docker + cucumber); it's very basic and simple, so easy to understand and modify / improve. It lies in the web directory;
my solution: https://github.com/gyulaweber/hosting_tests

Where to find good test case templates/examples? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I'm trying to establish more formal requirements and testing procedures then we have now, but I can't find any good reference examples of documents involved.
At the moment, after feature freeze testers "click through the application" before deployment, however there are no formal specification what needs to be tested.
First, I'm thinking about a document which specifies every feature that needs to be tested, something like this (making this up):
user registration form
country dropdown (are countries fetched from the server correctly?)
password validation (are all password rules observed, is user notified if password is too weak?)
thank-you-for-registration
...and so on. This could also serve as something client can sign as a part of requirements before programmers start coding. After the feature list is complete, I'm thinking about making this list a first column in a spreadsheet which also says when was the feature last tested, did it work, and if it didn't work how did it break. This would give me a document testers could fill after each testing cycle, so that programmers have to-do list, with information what doesn't work and when did it break.
Secondly, I'm thinking of test cases for testers, with detailed steps like:
Load user registration form.
(Feature 1.1) Check country dropdown menu.
Is country dropdown populated with countries?
Are names of countries localized?
Is the sort order correct for each language?
(Feature 1.2) Enter this passwords: "a", "bob", "password", "password123", "password123#". Only the last password should be accepted.
Press "OK".
(Feature 2) Check thank-you note.
Is the text localized to every supported language?
This would give testers specific cases and checklist what to pay attention to, with pointers to the features in the first document. This would also give me something to start automating testing process (currently we don't have much testing automation apart from unit tests).
I'm looking for some examples how others have done this, without too much paperwork. Typically, tester should be able to go through all tests in an hour or two. I'm looking for a simple way to make client agree on which features should we implement for the next version, and for testers to verify that all new features are implemented and all existing features are working, and report it to programmers.
This is mostly internal testing material, which should be a couple of Word/Excel documents. I'm trying to keep one testing/bugfixing cycle under two days. I'm tracking programming time, implementation of new features and customer tickets in other ways (JIRA), this would basically be testing documentation. This is lifecycle I had in mind:
PM makes list of features. Customer signs it. (Document 1 is created.)
Test cases are created. (Document 2.)
Programmers implement features.
Testers test features according to test cases. (And report bugs through Document 1.)
Programmers fix bugs.
GOTO 4 until all bugs are fixed.
End of internal testing; product is shown to customer.
Does anyone have pointers to where some sample documents with test cases can be found? Also, all tips regarding the process I outlined above are welcome. :)
ive developed two documents i use.
one is for your more 'standard websites' (e.g. business web presence):
http://pm4web.blogspot.com/2008/07/quality-test-plan.html
the other one i use for web-based applications:
http://pm4web.blogspot.com/2008/07/writing-system-test-plan.html
hope that helps.
First, I think combining the requirements document with the test case document makes the most sense since much of the information is the same for both and having the requirements in front of the testers and the test cases in front of the users and developers reinforces the requirement and provides varying view points of them. Here's a good starting point for the document layout: http://www.volere.co.uk/template.htm#anchor326763 - if you add: steps to test, resulting expectations of the test, edge/bound cases - you should have a pretty solid requirement spec and testing spec in one.
For the steps, don't forget to include an evaluate step, where you, the testers, developers, etc. evaluate the testing results and update the requirement/test doc for the next round (you will often run into things that you could not have thought of and should add into the spec...both from a requirements perspective and testing one).
I also highly recommend using mindmapping/work-breakdown-structure to ensure you have all of the requirements properly captured.
David Peterson's Concordion web-site has a very good page on technique for writing good specifications (as well as a framework for executing said specifications). His advice is simple and concise.
As well you may want to check out Dan North's classic blog post on Behavior-DrivenDevelopment (BDD). Very helpful!
You absolutely need a detailed specification before starting work; otherwise your developers don't know what to write or when they have finished. Joel Spolsky has written a good essay on this topic, with examples. Don't expect the spec to remain unchanged during development though: build revisions into the plan.
meade, above, has recommended combining the spec with the tests. This is known as Test Driven Development and is a very good idea. It pins things down in a way that natural language often doesn't, and cuts down the amount of work.
You also need to think about unit tests and automation. This is a big time saver and quality booster. The GUI level tests may be difficult to automate, but you should make the GUI layer as thin as possible, and have automated tests for the functions underneath. This is a huge time saver later in development because you can test the whole application thoroughly as often as you like. Manual tests are expensive and slow, so there is a strong temptation to cut corners: "we only changed the Foo module, so we only need to repeat tests 7, 8 and 9". Then the customer phones up complaining that something in the Bar module is broken, and it turns out that Foo has an obscure side effect on Bar that the developers missed. Automated tests would catch this because automated tests are cheap to run. See here for a true story about such a bug.
If your application is big enough to need it then specify modules using TDD, and turn those module tests into automated tests.
An hour to run through all the manual tests sounds a bit optimistic, unless its a very simple application. Don't forget you have to test all the error cases as well as the main path.
Go through old bug reports and build up your test cases from them. You can test for specific old bugs and also make more generalizations. Since the same sorts of bugs tend to crop up over and over again this will give you a test suite that's more about catching real bugs and less about the impossible (or very expensive) task of full coverage.
Make use of GUI and web automation. Selenium, for example. A lot can be automated, much more than you think. Your user registration scenario, for example, is easily automated. Even if they must be checked by a human, for example cross browser testing to make sure things look right, the test can be recorded and replayed later while the QA engineer watches. Developers can even record the steps to reproduce hard to automate bugs and pass that on to QA rather than taking the time consuming, and often flawed, task of writing down instructions. Save them as part of the project. Give them good descriptions as to the intent of the test. Link them to a ticket. Should the GUI change so the test doesn't work any more, and it will happen, you can rewrite the test to cover its intention.
I will amplify what Paul Johnson said about making the GUI layer as thin as possible. Separate form (the GUI or HTML or formatting) from functionality (what it does) and automate testing the functionality. Have functions which generate the country list, test that thoroughly. Then a function which uses that to generate HTML or AJAX or whatever, and you only have to test that it looks about right because the function doing the actual work is well tested. User login. Password checks. Emails. These can all be written to work without a GUI. This will drastically cut down on the amount of slow, expensive, flawed manual testing which has to be done.

User Stories To Code [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Suppose I have a bunch of User Stories ( as a result of the planing Session I went through with my team ). I don't have any code in the application yet and going to start with my 'A'
or highest Priority Stories/Epics
Say for example
"As A User I should be able to Search for more users so that I can add more friends on the website"
So how should the team go about coding the application while doing TDD.
Team starts with creating Unit tests ie .that take care of Creating models
Then everybody takes a story and starts writing functional tests to create my controllers / Views ( So Should they be doing integration testing while writing functional tests )
Then do the integration tests
I am actually confused how the integration tests fit in.if all the integration tests work ( ie all the functional, units tests should anyway pass )
So, If the application is just starting ( ie no Code has been written yet ). What is the process people usually take for TDD/BDD when they pick up a Story and start, for implementing a application from scratch
Very good question! The TDD/BDD way would suggest you take the user stories and write validation points (read high level tests). They use GWT (Given/When/Then) speak as follows.
"As A User I should be able to Search for more users so that I can add more friends on the website"
given the website URL
when the site loads
then a search field should be visible/accessible.
This is your first piece of feedback and first opportuniuty to iterate with the product owner. Ask questions like where should the search bar go? Should it auto complete? Etc. Next you assign "behavior to the UI objects. These also have validation points.
This would define the behavior of the search button:
given a go button next to the search field
when then button is clicked
then a search should be performed
this would describe the logic of your search:
given a search term "John" and a user set including "John, Joan, Jim, Steve"
when a search is performed
then the results should contain "John" an "Joan"
The first validation point would describe the behavior of linking the controller search button to an arbitrary model implementing the search algorithm. The second validation point describes the search algorithm itself. The advantage is that these pieces are defined independently and can be designed in parallel. It also gives you a nice API and small easily to plan features to iterate on. It also gives you the ability to iterate/refine on any piece of the puzzle without affecting the rest of the pie.
Update I also want to mention that what I refer to as validation points can loosely be associated with UATs or User Acceptance Tests. Don't get hung up on the terms because they're irrelevant. Focus on the idea behind them. You need to take the user story and break it down into specs. (can be done in one or many passes using either UATs or validation points or both or magic beans just make sure you break them down.) If what you have broken your user stories into can be written in a tool like FitNesse, JUnit, or RSpec then use one of these tools, other wise you need either further conversation (Are your user stories too vague?) or another pass over what you have to break down further (UATs to validation points). Don't obsess over the tools and feel like you need to automate everything from the beginning. Leave Selenium alone until you get the manual process down. Eventually you want specs that can be written in programmatic test-like form at this time you should be able to use something as simple as JUnit to start coding. When you get better/fancier you can pick up EasyB or RSpec story runner and other things.
This is where we usually start off with a Sprint 0 and in this spring is where we'll have what XP call's a Spike Session (or a Throw away code session). In this session is where you can begin prototyping.
In your session write a few user acceptance tests (preferrably in the BDD format) and then start writing a test first to match one of your UAT's.
For example:
Given a search is requested
where user's name is "testUser"
1 result should be returned.
With this you now have a goal for your first test, which you write, then begin writing code to make that test pass. As you go forward you should begin to see how the app should be put together to complete the story.
Then I would begin in the next sprint building stories/task's to complete the feature as needed based upon what you discovered in the sprint 0.
"I am actually confused how the integration tests fit in.if all the
integration tests work ( ie all the functional, units tests should anyway pass )"
It depends. Sure, it's possible to write integration tests in such a way that all unit and functional tests pass. It's just much more difficult.
Imagine that you have 3 models, 3 controllers and 3 views. Imagine that all are super simple with no conditions or loops and have one method each.
You can now (unit) test each one of these for a total of 9 assertions and have full coverage. You can throw in an integration test to make sure all these things work well together.
If instead you skip units/functionals and needed to have full coverage, you're going to need 27 assertions (3 x 3 x 3).
In practice things are more complicated of course. You'll need a much larger amount of integration tests to get to the same level of coverage.
Also, if you practice TDD/BDD, more often than not will wind up with lots of unit tests anyway. The integration test is there to make sure all these pieces fit well together and do what the customer wants. The pieces themselves have been tested individually by the unit tests.
First, break the story apart. You'll need:
A User object: What does it do? Create some tests to figure this out and write the code
A way to search users; maybe a SearchUserService? Again create tests and write the code
A way to connect users ...
Now, you have the model. Next, you do the same for the controllers. When they work, you start with the views.
Or, when you're a pro and have done this a thousand times already, you might be able to roll several steps at once.
But you must first chop the problem into digestible pieces.
Next for the integration tests. They will simulate what a user does. In the general case, you need to write a set of unit tests (they are just called integration tests but you should also be able to run them automatically). These tests need to talk to the web app just like the user does, so you need a simulated web browser, etc.
You can try httpunit or env.js for this.
If you're doing TDD, you start with a test that shows that the system does not perform the required behaviour described by the user story. When that is failing in the way you expect, with useful diagnostics, you then start implementing the behaviour by adding or modifying classes, working unit-test first.
So, in TDD you write integration tests before you write unit tests.
To bootstrap the whole process, one usually writes a "walking skeleton": a system that performs the thinnest slice of realistic functionality possible. The walking skeleton let's one build up the integration test infrastructure against simple functionality.
The rest of the project then fleshes out that skeleton.

BDD GUI Automation

I've started a new role in my life. I was a front end web developer, but I've now been moved to testing web software, or more so, automating the testing of the software. I believe I am to pursue a BDD (Behavior Driven Development) methodology. I am fairly lost as to what to use, and how to piece it together.
The code that is being used/written is in Java to write a web interface for the application to test. I have documentation of the tests to run, but I've been curious how to go about automating it.
I've been directed to Cucumber as one of the "languages" to help with the automation. I have done some research and come across a web site for a synopsis of BDD Tools/Frame works,
8 Best Behavior Driven Development (BDD) Tools and Testing Frameworks. This helped a little but then I got a little confused of how to implement it. It seems that Selenium is a common denominator in a lot of the BDD frameworks for testing a GUI, but it still doesn't seem to help describe what to do.
I then came across the term Functional Testing tool, and I think that confused me even more. Do they all test a GUI?
I think the one that looked like it was all one package was SmartBear TestComplete, and then there is, what seems to be, another similar application by SmartBear called, SmartBear TestLeft, but I think I saw that they still used Cucumber for BDDing it. There a few others that looked like they might work as well, but I guess the other question is what's the cheapest route?
I guess the biggest problem I have is how to make these tests more dynamic, as the UI/browser dimensions can easily change from system to system, and how do I go about writing automation that can handle this, and tie into a BDD methodology?
Does anyone have any suggestions here? Does anybody out there do this?
Thanks in advance.
BDD Architecture
BDD automation typically consists of a few layers:
The natural language steps
The wiring that ties the steps to their definition
The step definitions, which usually access page objects
Page objects, which provide all the capabilities of a page or widget
Automation over the actual code being exercised, often through the GUI.
The wiring between natural language steps and the step definitions is normally done by the BDD tool (Cucumber).
The automation is normally done using the automation tool (Selenium). Sometimes people do skip the GUI, perhaps targeting an API or the MVC layer instead. It depends how complex the functionality in your web page is. If in doubt, give Selenium a try. I've written automation frameworks for desktop apps; the principle's the same regardless.
Keeping it maintainable
To make the steps easy to maintain and change, keep the steps at a fairly high level. This is frequently referred to as "declarative" as opposed to "imperative". For instance, this is too detailed:
When Fred provides his receipt
And his receipt is scanned
And the cashier clicks "Refund to original card"
And the card is inserted...
Think about what the user is trying to achieve:
When Fred gets a refund to his original card
Generally a scenario will have a few Givens or Thens, but typically only one When (unless you have something like users interacting or time passing, where both events are needed to illustrate the behaviour).
Your page objects in this scenario might well be a "RefundPageObject" or perhaps, if that's too large, a "RefundToCardPageObject". This pattern allows multiple scenario steps to access the same capabilities without duplication, which means that if the way the capabilities are exercised changes, you only need to change them in one place.
Different page objects could also be used for different systems.
Getting started
If you're attacking this for the first time, start by getting an empty scenario that just runs and passes without doing anything (make the steps empty). When you've done this, you'll have successfully wired up Cucumber.
Write the production code that would make the scenario run. (This is the other way round from the way you'd normally do it; normally you'd write the scenario code first. I've found this is a good way to get started though.)
When you can run your scenario manually, add the automation directly to the steps (you've only got one scenario at this point). Use your favourite assertion package (JUnit) to get the outcome you're after. You'll probably need to change your code so that you can automate over it easily, by e.g.: giving relevant test ids to elements in your webpage.
Once you've got one scenario running, try to write any subsequent scenarios first; this helps you think about your design and the testability of what you're about to do. When you start adding more scenarios, start extracting that automation out into page objects too.
Once you've got a few scenarios, have a think about how you might want to address different systems. Avoid using lots of "if" statements if you can; those are hard to maintain. Injecting different implementations of page objects is probably better (the frameworks may well support this by now; I haven't used them in a while).
Keep refactoring as you add more scenarios. If the steps are too big, split them up. If the page objects are too big, divide them into widgets. I like to organize my scenarios by user / stakeholder capabilities (normally related to the "when" but sometimes to the "then") then by different contexts.
So to summarize:
Write an empty scenario
Write the code to make that pass manually
Wire up the scenario using your automation tool; it should now run!
Write another scenario, this time writing the automation before the production code
Refactor the automation, moving it out of the steps into page objects
Keep refactoring as you add more scenarios.
Now you've got a fully wired BDD framework, and you're in a good place to keep going while making it maintainable.
A final hint
Think of this as living documentation, rather than tests. BDD scenarios hardly ever pick up bugs in good teams; anything they catch is usually a code design issue, so address it at that level. It helps people work out what the code does and doesn't do yet, and why it's valuable.
The most important part of BDD is having the conversations about how the code works. If you're automating tests for code that already exists, see if you can find someone to talk to about the complicated bits, at least, and verify your understanding with them. This will also help you to use the right language in the scenarios.
See my post on using BDD with legacy systems for more. There are lots of hints for beginners on that blog too.
Since you feel lost as to where to start, I will hint you about some blogs I have written that talks a bit about your problem.
Some categories that may help you:
http://www.thinkcode.se/blog/category/Cucumber
http://www.thinkcode.se/blog/category/Selenium
This, rather long and old post, might give you hints as well:
http://www.thinkcode.se/blog/2012/11/01/cucumberjvm-not-just-for-testing-guis
Notice that versions are dated, but hopefully it can give some ideas as what too look for.
I am not an expert on the test automation but I am currently working on this part. So let me share some idea and hope it will help you at the current stage.
We have used selenium+cucumber+intellij for testing web application. We have used testcomplete+cucumber+intellij for testing java desktop application.
As to the test of web application, we have provided a test mode in our web application, which allows us to get some useful details of the product and the environment; and also allows us to easily trigger events through clicking the button and inputting text into the test panel under test mode.
I hope these are helpful for you.