We occasionally need to notify users about warnings or problems. But often times, especially if it's a common problem, users will just dismiss the warning and continue. Often times users won't even remember seeing the warning, but we check their logs and see that several were displayed. So, how do you get users to pay attention when you're trying to tell them something important?
This isn't as simple as forcing users to resolve all problems before allowing them to save. They often need to save data that isn't strictly okay by our business rules for various reasons (usually for problems that can't be solved right away, or at all).
We've got a better warning/error handling system in mind that I think will help a lot, but I want to see what others have done.
If you want users to pay attention to warnings, use them in moderation!
The big problem with the UAC in Vista is that people are getting so many notifications, that they stop reading who is exactly requesting access to what, they just give permission without thinking.
Another example is the delete confirmation in explorer when sending files to the recycle bin. I got so used to just hitting 'Ok' immediately after pressing 'delete', that I missed the fact that the dialog was telling me that the file would not be moved to the bin, but deleted immediately, for whatever reason.
My personal fix: I disabled the delete confirmation for the recycle bin. If something can not be moved to the bin, I still get a message, and this time I know that it might be important, so I pay attention.
Conclusion: Don't spam the user with messages, or the important warnings will get lost in the noise.
The quality of your warning will not prevent users from submitting invalid data. If you allow invalid data to be submitted, it will be.
If you have data that must be submitted to a rules system, then that data must be valid before it is submitted. However, allowing users to save their work is a separate issue. You should allow users to save their work, then submit the data to the rules engine when it is valid.
The fundamental problem is that users don't like to read, they just want to be left alone to do their work :).
The best way to combat this is the following:
Don't pop up a window unless absolutely necessary
If you do, make the error or warning message as short and succinct as you possibly can
Long error/warning messages simply won't get read. The user will get to about the fifth word and think "this is taking too much time, I just want to get back to work".
My advice boils down to three things.
Reevaluate what you think is important for the user to know.
Don't be lazy and ask the user to resolve what your program can resolve for itself.
Don't interrupt what the user is doing with stupid (and yes, they are stupid) messages.
If you have a form with required data, then color-code the field as red or highlight it with an asterisk to indicate it's required. Disable the "OK" or "Confirm" button until they fill out all required fields.
For fields with incomplete or inconsistent data, bring up a tooltip or color-code the field so the user knows that something may be wrong. You could also display the list of warnings prominently somewhere on your form. But don't stop the data entry. You'll just frustrate and anger your users.
I must admit that I too often click on "OK" or whatever I'm conditioned to do for a dialog to go away without thinking. Usually this occurs when there are just too many of them.
Without claiming to be a psychologist of any kind, I think it is natural to pay attention to unusual things and filter away repetetive things.
With that in mind it is maybe worth considering to make less important dialogues less intrusive so that the real important ones get more attention.
I think toaster messages and the way google handles messages in it's online apps are real nice examples of how to notifiy a user of something inessential.
--EDIT--
Now that I re-read my post, I remember reading this in "Don't Make Me Think".
A brilliant little book (few tens of pages) that's full of nice and easy to understand usability things. Somewhat focused on online usability, but defenatly applyable in offline applications too.
This is what we've got planned. Essentially, create something Bugzilla-ish for storing these errors/warnings/whatever. But it also goes hand in hand with some of the other answers.
Instead of using simple MessageBox, display warnings/errors in a Visual Studio-like error window. As long as there are problems, they'll be displayed in this window.
If the data is saved, save all warnings/errors to the database. Now anyone can see what the current issues are - bonus! Also, those problems can be loaded from the database instead of detecting them in the app all the time, which will help a lot - some problems are not trivial to detect.
Allow users to perform several actions, like:
Acknowledge the problem, so it is no longer displayed.
Assign the problem to another user
Flag the problem as "not really a problem"
Set a "must be solved by" date
(probably others, the design hasn't been fully thought out yet)
Log all of these actions to the database, so we have accountability
That's it in a nutshell. Now problems stick around, so they're in the users faces until they're solved. The problems can be tracked, so we can tell where the ball was dropped if we get bit. I hope it works!
Though I never got around to implementing this at a previous site, I wanted to create a custom dialog box where users would have to check a box stating that they have read and acknowledged the message (and then log that response). This was for an ISO-xxxx company so this kind of bureaucracy was a logical response to these types of mistakes.
My other, much more sinister, idea was to make "No" or "Cancel" the default options. Eventually they would get the Tab-Enter keystrokes down pat and then you would just switch it back.
Break the system!
It has honestly been my experience that if you don't want an end user to do something without explicitly understanding it, stop them from doing it...
As seriously anoying as the whole "Windows Error/warning Messages" gets, I never take notice until a program tells me I can't do something... then I am forced to ask myself "Why Not"
Time to google the answer... or RTFM
I know that it is not always feasible to use this approach, but if you can... they will listen!
I like programs that hint that there's a problem while ignoring it as long as possible - which sounds very like what you're striving for. One thing I've been thinking about (but vaguely, since I haven't had a use for it) is putting a status indicator for errors/warnings (a bit like the omnipresent throbber of a web-browser, but for errors). This icon would change state, a bit like a traffic light, to show that the program has problems that will have to be addressed sooner or later - perhaps yellow for warnings if the problem with the data could be corrected later and isn't going to cause any major problems, red for any problem that is going to have to be fixed before they complete the current job (for form data, that would mean the whole transaction, not the current form). Obviously the colours wouldn't be enough, there would have to be some support for colour-blind people, but you get the idea. Clicking the indicator would bring up a list of the problems (and perhaps explanations as to why that is a problem - so that people can point out when the code's assumptions are unhelpful or wrong), and selecting a problem would allow you to jump to the field where it can be fixed.
One thing you should probably do, whatever method you go with in the end, is to look through your warnings and work out whether they're actually necessary. I've seen far too many programs that warn me about perfectly reasonable input that is then accepted, or warn me about the usual behaviour of the program. That's the sort of thing that helps condition people to click through warnings. If you have logs of the warnings, you might start there - Why are people clicking through them? They might be conditioned, or it might be that there genuinely isn't a problem, and someone hasn't told you that things have changed.
I quite like the firefox method when installing plugins: The ok button is disabled and displays a countdown for 5 seconds. After that the use can choose to ignore it.
For web applications, the alert() and confirm() javascript methods, while somewhat basic, achieve the effect of either preventing users from doing something or making sure that they clearly agree to something that they have been warned about.
For other situations, where the action will not cause considerable disruption in the business processes, we often display a small warning box at the top of the page after, say, a form is submitted.
For example, our applications require location validation in several places (valid city/state/zip).
If the location is absolutely critical, we will make it required on the form.
If the location is required for some aspects of the application, we will use the confirm() to make sure they understand that they will not be able to use certain features without a valid location.
In some cases, we use a default location. In that case, we provide the message/warning box at the top of the next page indicating that a default location is being used.
I've found that if you're producing log messages for your own use (even if that use directly benefits the users themselves), the only way to get users to report problems is to have the application do it for them.
In the case of dealing with user input that might be wrong, have you considered using something like the red squigglies used by spell checking or some kind of highlighting of the problem areas as the user does their work? Most users have been trained to ignore dialogs by using buggy software, but that kind of message might make it clear that the error is the user's to fix.
Do you have a good idea why each of the exceptional situations occurs? What do you try to achieve with each of these messages:
make user review the data for obvious typos or mistakes
make someone else to review the data at a later stage when more information is available
inform this user and anyone else looking at the data at a later stage about any assumptions made
make sure user understands the consequences of their actions
Can any of these goals be achieved more effectively in a different way?
Some ideas (none of them automatically qualify as a silver bullet):
Keep messages short and relevant, exclude any language that does not contribute additional info (such as "please" etc), tell users what is expected of them (i.e. instead of "Post code is empty" use "Enter post code".).
Use language that is understood by the users, always give sufficient information, try to be as specific as possible.
Use different looking messages for different types of warnings and errors (use font, colour, imaging, possibly animation and sound).
Revisit the entire process, so that someone has to process any info submitted with warnings later on.
Visualise warnings the next time info brought to the screen (i.e. highlight problematic areas) so that they can be resolved later, when more info is available.
Add a sign off to the warnings, for instance request a user to enter their password each time they need to dismiss a warning.
Make actions undo-able, so you don't really need the warnings
Dont try to solve with programming. See if you can change the data input process.
Use colors and icons.
Green - everything is ok (or confirmation something happened as expected)
Yellow - Warning. You user may or may not want to look into the issue
Red - Error. Something that requires user interaction to resolve.
I would also suggest (as others have on this thread) to use sparingly.
Related
I am not a guru of stack traces, at all. I don't even know how to get them. Anyway, I am wondering if entering a password entered in an inputbox is safe. Can't it be retrieved by getting a stack trace?
A password entered that way will be found in many places:
Caption property of the TEdit
Result of the function which creates the inputbox
probably, a variable that stores the Result of the InputBox Command
etc...
If the answer is "yes, it is a vulnerability", then my world collapses :p. What can be done to avoid this security hole?
NOTE: The InputBox is an example but it can be with a "homebrewed" login prompt.
InputBox is a Delphi command but I haven't tagged the question with the Delphi tag because I suppose that the question concerns any language.
This is called the airtight hatchway problem, and stems (at least one of the sources) from a chapter in a book by Douglas Adams called The Hitchhikers Guide to the Galaxy. In it, our two protagonists are being carried by a large guard and dumped into a airlock, pending being evacuated into space. At some point, one of our protagonists says that he had a solution, but "it rather involved being on the other side of the airtight hatchway.".
Let me explain.
If you have a cracker that is able to execute code (or in other ways "be") on your own machine, you have already lost. There's a ton of things that the cracker can do at that point.
So your first line of defense should be to prevent bad-guys access to your machine, if you can handle that, security becomes much easier.
So no, this is not a vulnerability, it is the fundamental way your computer works.
In the simplest form, if someone is able to get hold of runtime live stack-traces of your program in motion, it probably means they have hooked up something that looks like a debugger to your program and is able to "debug" your program as it runs. A breakpoint could easily grab data from memory, process it, and then resume the program without the user ever knowing anything has happened, but in practice, there are far easier way to get hold of such information provided you can execute code on the system.
Now, having said that, in .NET and many other runtimes there is support for attempts to at least make it harder, by instead of storing the whole string, they intercept one and one keystroke into your input box, and encodes it together with the rest of the password, so that each character is not stored in plain-text.
However, the code that handles this becomes very cumbersome to work with, simply because any attempt to get the whole password in clear-text would make the whole exercise pointless, so unless you're able to pass such encoded passwords end-to-end around your system, this won't really help much.
In .NET, the class in question is System.SecureString.
However, again, if the bad-guy can execute code on your platform, what is there to stop him from intercepting the keystrokes and just combining them together to form your password?
Here's a couple of links with examples of similar questions:
It rather involved being on the other side of this airtight hatchway: Dubious escalation
It rather involved being on the other side of this airtight hatchway: If they can inject code, then they can run code
It rather involved being on the other side of this airtight hatchway: Elevation to administrator
You can tell I'm a fan of Raymond Chen.
I have a web site I am building for a client. I now have a tester on the project with me.
I feel testers are needed. REALLY! I cannot test my own code. I also appreciate the value of a new set of eyes. But what desires reporting?
It is easy to say everything should be reported, but I don't have someone between me and the tester to filter out the unimportant requests. The tester does not know the system nor the target user well. She is assigning me tasks and not the project manager. I think this will change soon, but until it does, what do you recommend? There seems to be a believe that our users have NEVER used the interent before at all, and they are as dumb as rocks.
The problem I am having is that EVERYTHING the tester suggests is being accepted automattically and assigned to me.
I have many cases that make me drop my jaw and say "Really? Are you serious? This deserves to be a issue?"
Ex: Need to add text at top of page that says "* = Required" for required fields.
Have you ever felt this way? How did you deal with it?
For now, I am just doing as I am told, but I am making it clear I do not agree.
It sounds to me like your tester is doing the right thing. You can't assume any level of user expertise when testing an application. If a user can break something, they will.
You and your tester need to work out a severity scale. The outliers (those that anybody with Internet experience could probably work around/would never hit) would be considered low priority and sit on the back burner until you knock out the high priority items.
...never the less, those outliers should still be logged because they can definitely come back to bite you in the ass in the end.
You need to add priorities for your issues. This will allow you to do the important issues first, and cosmetic issues last. Here is example priorities from Jira:
Priority 1 - a reproducible crash; issue blocking any further testing or development of a specific feature; loss of user's persistent data; huge memory leak
Priority 2 - a major issue that must be fixed before the product is released; prevents users from using a feature; negatively affects partner; significant memory leak in frequently used functionality
Priority 3 - a minor issue that should be fixed before a product is released; does not prevent users from using a product; highly visible usability issue; small memory leak in rarely used functionality
Priority 4 - a purely cosmetic issue; doesn't affect functionality
Actually it sounds like your tester is doing the right thing (and the text for "* = required" is a very good idea).
In addition to the suggestions about prioritizing reports, I would suggest that you categorize the reports as to whether they refer to user experience or functionality.
You and the tester will never exactly agree on what "needs" to be reported. Just set the priority on issues correctly, and get on with fixing the high-priority stuff first.
One thing you absolutely do not want to do is to discourage the tester from filing bugs. That'll come back to bite you when something ships totally broken, and they say "I thought that was just how it worked".
Do make sure that you're communicating the development schedule and status properly, so they don't waste time testing features that aren't sufficiently complete.
I would report to the client what each change will cost in terms of time and money. Things that are legitimate bugs you'll probably need to fix on your own time (unless your contract says otherwise). Things that are design / subjective issues you should be able to assign a cost to. Let the client know what it is going to cost them and they can decide if they want to proceed or not.
Hopefully you've got some sort of a project specification that the client has signed off on so that you know when the project is complete and what sort of things are not included in the project scope. If not, you might have a bit of a fight on your hands. For changes that you think are outside of the project scope, you might need to compromise - maybe bill them at a cheaper rate or split the cost with them. If you're in that situation it's a good learning experience to get everything documented in the project specification so that there is no question about what falls outside of the project scope. I've been there - one experience like this is enough to teach you to put more work into your specifications.
Report everything and triage. After a bit of time, she'll start to understand what gets past triage and what doesn't. Humans can learn; teach.
When doing hallway usability tests do most of you make your apps fully or near fully functional? Or do you just make sure the links or flow chain correctly? Or do you just draw on paper and go with that?
I'm would like to test early on a prototype and am trying to find a good balance. But at the same time am worried that some non functional parts might actually not give representative results.
Thanks.
Usability tests, hallway or otherwise, only need the functionality that you need to test. In most usability tests, you should go in with specific design questions to answer and develop your prototype to the point where it can answer those questions. For example, if you need to test if users understand your indication of the sort order for a table, all you need is a paper picture of the table showing the sort indication (with the table contents blurred) and ask them how the table is sorted. If you need to test the IA, all you need is a bunch of web pages, empty except for a title, that are linked through the navigation menus.
You only need the pages relevant for the tasks you give your users. If you’re just testing the IA, then you only need the pages on the normative path. If you are also testing error recovery, then you need the pages off the normative path along with the full navigation controls. If you are also testing error detection, then you need content on the pages as well.
You can also simulate functionality when that’s easier to do. For example, in testing if users can figure out how to get a desired sort order, when the user clicks on a non-functioning control for sorting the table, you can say, “Okay, doing that will get you this,” and you take the mouse and select a bookmark that shows the table in the new sort order.
In hallway testing, if users breach the fidelity envelope, you can simply say, “I haven’t made that part yet. Let’s go back to A, and continue from there.” Of course, you should note that the user made a wrong turn in the task you intended for them. I haven’t had any problems with users complaining about non-functional features when I tell them up front it’s an incomplete prototype and we’re only testing the UI for features x, y, and z at the moment.
For low fidelity prototypes, I often call them “mockups” or “drawings” to users rather than “prototypes” to indicate the low functionality. You can put obvious placeholders in for missing content (e.g., “Blah, blah, blah…”, “TODO: Picture of product about here.”). If a user comments on something outside the fidelity envelope (e.g., “This symbol should be red to stand out more”), simply note it, and say that topic is under development (e.g., “Thanks. We haven’t started work on the colors yet. We’re just trying to figure out how to organize the site right now.”).
Usability testing with limited-fidelity prototypes is really necessary for iterative design to be feasible for most projects. Otherwise, you waste too much work developing things that have to be redone.
A couple things to remember:
Test early and often.
The goal of usability testing is to find problems with the UI, not Q/A your code.
Therefore, if users can see the parts of your UI you are interested in testing and interact with them in a realistic way (e.g., click on buttons and links), you should be able to collect useful data. If some links are dead-ends, that's okay, as long as there's some way for users to recover and continue on. Basically, with prototypes, the "correct" path should work, but it's okay if incorrect paths don't (as long as there's a reasonably quick way to get back on the correct path). Even static storyboards (non-functioning drawings of a UI) can provide you with some information if you ask the right questions, e.g., "What would you do on this screen if you wanted to view your shopping cart?").
I would suggest a couple rounds of usability testing. First on paper, perhaps later on screen, generally throughout the application lifecycle (take an Agile approach to it).
There is a good argument to be made for paper prototypes. When users see a screen, even limited functionality, they may be hesitant to suggest changes since it looks "done."
Make no mistake, it's not trivial to get it all down on paper, but that's where I would start. Probably start with just a section or two of the application. And make sure somebody with good people skills and/or explaining skills is there to walk the user through it. Have a second person on-hand to take notes. Try to ask open-ended questions, etc.
For a hallway test, I would test with NONE of the functionality implemented.
Test against designs done on a whiteboard or on paper. You'll be surprised at how much you find out in these minimal mockups. And they are very inexpensive to make!
Functional prototypes are for later. If you give your usability subject a functional interface, they are much less likely to question whether you've implemented the right set of features in the first place.
I would make the UI functional, so that the user can really play with it, it will be much better than a static image. People can tell you whether they feel comfortable on the UI.
I would make sure everything in the UI works, or at least takes you to a clear, unambiguous message pointing out that the feature isn't implemented yet.
Showing prototypes to clients with a disclaimer up front about how feature X doesn't work yet will usually be ignored. They'll try out the prototype, click on featuree X and indignantly reply "Feature X doesn't work! This really needs to work in the final version! Why doesn't it work?". The client is confused and unhappy about the product, and it's frustrating for yourself because it overshadows the positive feedback. Besides, you told them it didn't work, why can't they use their imagination to envision how it would work in the final version?
Make it work, be it with a rough version, dummy data, or even a simple message saying "would show results sorted alphabetically now".
I was given a task of write the coding guidelines for my team, and it was going great until my manager asked me to write an explanation of Why Error Handling is Important.
I know it instinctively, but how do I express this in words?
I tried to google it first but came up empty, so I now ask my fellow coding wizards.
IMHO ... most programs are very large, very complex and written by multiple people. This combination of factors almost always leads to some kind of software bug. It's not that programmers are malicious, stupid or lazy ... it's just that in the rush to meet a deadline we often don't forsee every possible thing that a user can do to our programs and something is bound to happen.
In this respect error handling serves two purposes.
First, it lets the user know, in a relatively friendly manner, that something has gone wrong and that they should contact the technical support department or that someone from tech support has been notified. As we all know there's a HUGE difference between receiving a rather nasty, tech riddled notice that says something like "Object not set to reference of an object" etc. ... and receiving a nice popup type window that says "There has been an issue. Please contact the helpdesk".
Second it allows the programmer to put in some niceties to aid in the debugging of issues. For instance ... in my code, I typically write a custom error handler that takes in a number of parameters and spits back a nice, formatted message that can either be emailed to the helpdesk, stashed in an event log, written to a log file etc.. The error message will contain as much info as I can cram in there to help me figure out what happened, stack traces, function parameters, database calls ... you name it. I like verbose error messages to help me figure out what actually happened. The user never has to see any of it, they get the nice, friendly message above, letting them know that someone can figure out what's going on.
Error handling is important because it makes it easier for the end users of your code to use it correctly. Another important issue is that it makes your code easier to maintain. Error handling makes it easier to embed input specifications into the code, so you don't have to look up the design when you write and later maintain the code.
Why Error Handling is Important.
Because of what can happen if you don't.
If you're capable of writing coding guidelines, you should be able to handle this, surely?
Its quite simple to explain to a layman manager:
If your handle your errors, your program will likely continue to function after an error, your customer can likely continue working, and you can provide a report of exactly how the bug occurred so you can fix it.
If you don't handle your errors, your program may crash, lose all of your customers work and you likely won't know where the bug occurred (provided you don't handle your fatal exception with a stack trace).
Another huge reason that error handling is so important is security! Certain types of errors, if not handled properly can leave a program and the underlying operating system in a vulnerable state. Handling errors must be a deliberate and well thought out process because even when handled gracefully, errors can write to log files or splash error messages to the screen that supply potential attackers with very valuable information that they can use later to take advantage of specific vulnerabilities.
First I would ask is it important?
I've seen (ugly) code where some errors were ignored (eg null reference)
So what type of errors are important to handle?
There is a big difference between System.IO.FileNotFoundException, System.Data.SqlClient.SqlException and System.ApplicationException
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 4 years ago.
Improve this question
We're neck deep in a project right now, schedules are tight (but reasonable). Our general strategy is to get a strong beta done, release it for testing, and get feedback from our testers.
Quite frequently, we're being hit by small things that spiral into long, time-costing discussions. They all boil down to one thing: While we know what features we need, we are having trouble with the little details, things like 'where should this message go' and 'do they need this feedback immediately, or will it break their flow, so we should hold off'?
These are all things that our testers SHOULD catch, but
a) Each 'low priority' bug like this drains time from critical issues
b) We want to have as strong a product as possible
and
c) Even the best testing group will miss things from time to time.
We use our product, and we know how our users use the old version...but we're all at a loss as to how to think like a user when we try to use the new version (which has significant graphical as well as underlying changes).
edit - a bit more background:
We're writing a web app used by a widely-distributed base of users. Our app is a big part of their jobs, but not the biggest (and, of course, we only matter to them when it doesn't work). Getting actual users in to use our product is difficult, as we're geographically distant from the nearest location that serves as an end user (We're in Ohio, and I think the nearest location we serve is 3+ hours away).
The closest we can get is our Customer Service team (who have been a big help, really) but they don't really think like the users either. They also serve as our testers (it really motivates them to find bugs when they know that any they DON'T find may mean a big upswing in number of calls). We've had three (of about 12 total) customer service reps back here most of the week doing some preliminary testing...they've gotten involved in the discussions as well.
Watching someone using the app is a huge benefit to me. Possibly someone who is not entirely familiar with it.
Seeing how they try to navigate, how they try to enter information or size windows. Things we take for granted after creating/running the app hour after hour, day after day.
Users will always try and do things you never expected and watching them in action might bring to light how you can change something that might have seemed minor, but really makes a big impact on them.
Read Don't make me think.
Speaking generally, you can't. There's not any way you can turn off the "programmer" part of your brain and think like a user.
And you're right about (c), testing groups don't necessarily catch all the bugs. But the best thing you can do is get a testing group comprised of real, honest-to-goodness end users, and value their feedback. Draw further conclusions from their general comments.
If you want to know how your users will see your system, the closest you can get is usability testing with real users. Everything else is just heuristics and experience, and is also subject to error. There's no such thing as a bug-free product, but you should be able to get a "strong" product with usability testing.
Buy a cheap, easy to use video camera and record your testers using the app. Even better, get some people unfamiliar with the app. to use it and video them. It's relatively cheap, and you'd be surprised what it will highlight.
I like policy of "eating your own dog food"("http://en.wikipedia.org/wiki/Eat_one's_own_dog_food). It brings you one step closer, because you become a user, although you might think like one.
Try to use your app when you are very hurry (e.g. you have someone who waits for a dinner).
You will see all this little things because you have to wait, you have to go back to the mouse of the keyboard, etc.
And also, make your wife use it. Or your mother.
Another useful test : help someone to use it, by phone. If he can't find the button with your directions, that's probably a bug.
The important thing is to get enough information that you yourself can become a "user". Once you do that you can answer most questions yourself.
The way I always do this is to go talk with them about what they need to do, what they typically do, and how they use their current tools to do it. Then (very important) sit with them while they do it. Make sure you get on with them well enough that you can come back to them with questions about how they handle edge cases you think of later (often the answer will be the appalling "we go around the system manually for that").
I will almost always notice something they are doing that is a royal PITA that they didn't bring up because they are used to having to do that and don't know any better. I will always notice that their %90 typical workflow isn't the easiest workflow the tools provide.
You can't really rely on plain old-fashioned requirements gathering by itself, because that is asking them to think like a developer. They generally don't know what is possible to do with your software, what is easy, and what is hard. Also they typically have no clue on GUI design principles. If you ask them for design input they will just tell you to put any new control on their favorite page, until the thing looks like a 747 control panel.
The problem is often that even the users don't know what they want until they are actually working with the software. Sometimes, a small oversight can be a big usability problem, sometimes a well thought out function that was requested by many users sees only little use.
My suggestions to decrease the risk of not implementing the right usability features:
Take a look at users actually doing their day to day work. Even if they use another software or no software at all. You will be able to determine the artifacts they often need to get their job done. You will see what data they frequently need. Concentrate on the artifacts, data and workflows most used. They should be the most usable. Exotic workflows may be a bit more time consuming for the users than often used workflows.
Use working prototypes of the GUI to let users work through a realistic workflow. Watch them and note what hinders them and what works well. Adjust your prototypes accordingly.
If an issue arises in an often-used part of your software, it is time to discuss it now and in details. If the issue concerns a seldom used part, make it a low priority issue and discuss it if you have the time. If issues or suggestions are low priority, they should stay low priority. If you can't determine if solution A or solution B is the best, don't run in circles with the same arguments over and over. Just implement one of the solutions and see if the beta testers like it. The worst thing you could do is waste time over tiny issues, while big issues need to be fixed.
A software will never be perfect, because the viewpoints of users differ. Some users will think that a minor problem breaks the whole application. Others will live with even severe usability issues. People tend to lend their ear to those who argue the loudest. Get to know your users to separate the "loud" issues from the important ones. It takes experience to do this, and sometimes you will make wrong decisions, but there is no perfect way, only one of steady improvement.
If you can, set aside a certain amount of usability development resources for the rollout phase of your software. Usability issues will arise when people start working with it in a real production environment. Sometimes it is not important to present the perfect software, but to solve issues quickly as they arise.
The flippant (yet somewhat accurate) answer to how to think like a user is put a knitting needle in your ear and push really hard.
The longer response is that we as programmers are not normal and I mean that in a good way. I scratch my head at the number of people who still run executables they receive from strangers in emails and then wonder how their computer got infected.
Any group of people will in time develop their own jargon, conventions, practices and expectations. As a programmer you will expect different things from an operating system than Joe User will. This is natural, to be expected yet hard to work around.
It's also why BAs (business analysts) exist. They typically come from a business or testing background and don't think like programmers. They are your link to the users.
Really though, you should be talking to your users. There's no poitn debating what users do. Just drag a few in and see what they do.
A usability test group will help.. tests not focused on discovering bugs, but on the learning curve of the new design, made by a group of users, not programmers.
I treat all users like malicious idiots.
Malicious because I assume all users are going to try and break my code, do stuff that is not allowed, avoid typing in valid data, and will do anything in their power to make my life hell.
Idiots because again I can't assume they will understand simple stuff like phone formats, will run away screaming if presented to many choices, and will not make any leap of faith on complicated instructions. The goal is to hold their hand the entire way.
At the same time, its important to make sure the user doesn't realize you think they're an idiot.
To think like a user, be one. But are these actually bugs that your testers are reporting? Or are they "enhancement requests"? If the software behaves as designed per requirements and they just don't like the way it operates, that's not a bug. That's a failure of requirements and design. Make it work, make it rock solid, make it easy to change and you'll be able to make it what your users want.
I see some good suggestions here, especially observing people trying to use you app. One thing I would suggest is to look at the order in which things are presented to the user on paper forms (if they use these to do data entry from) and make the final data entry page mimic that order as closely as possible. So many data entry errors (and loss of data entry speed) are from them having to jump around on the page and losing their place. I did some work for a political campaign this year and in every case, entering data was made much more difficult because the computer screen did things in a differnt order than the paper inputs. This is particularly important if the form is one that can't be changed (like a voter registration form, a campaign has to use what the state provides) to match the computer screen. ALso be consistent from screen to screen if possible. If it is first Name last name on one form, making it last name first name on the next will confuse people and guanteee data entry errors.
If you are truly interested in understanding users though I strongly suggest taking a course in Human factors engineering. It is an enlightening experience.
The 'right' way to do this is to prototype (or mock up) your new interface features, and watch your users try to use them. Nothing is as enlightening as seeing a real user try to use a new feature.
Unfortunately, given most projects time and resources, this is not possible. If that is the position you are in I would recommend you discuss in the team who has the best grasp of usability, and then make them responsible for usability decisions - but that person will need to regularly consult real users to make sure his/her ideas are consistent with what the users want.
I'd suggest doing some form of usability testing; I've participated in such in the past, and found them quite useful.
If you were writing a ticketing system, for example, bring up tasks, and ask questions like "how would you update this ticket" or "what do you expect to happen if this button is clicked".
You don't necessarily need a full application, either, in some places screen shots can be used.
You could take the TDD/BDD approach and get the users involved before beta, having them work with you on refining requirements as you write your unit tests. We're beginning to incorporate some of those trends into our current project, and we're seeing fewer bugs in the areas where we have involved the users earlier.
There is no "think like a user" technique, get your hands on someone who knows nothing of the project and throw what you have done at them.
It's the only way to see how the look + feel + functionality present themselves to the end user.
Once you shocked that person who knew nothing of the product, listen to all of their idiotic (or so you think they are) complaints, fix them, arrange every silly cosmetic thing they point out (either by fixing the UI or by improving whichever documentation you had)..
and after you have satisfied the person you chose to look at your app from zero knowledge on the subject first round, pick another ...and another... until they stop being shocked when they see it, and they don't get stuck on.. "ok.. what does this do?" kind of phases.
You (as a member of the project, be it the project manager, developer, etc) will never think like a user is my answer to that question.
Old saying: You can make something "fool proof" but you can't make it "Damn-fool proof".
Additionally: When you make something "idiot proof" the world invents a better idiot.
Other than that, I agree with what everyone else said.
Ask someone with absolutely no knowledge, insight or programming experience to use the program and try to figure out every function of the program.
People who would NEVER use such a program are most likely to find bugs.
See it as a new Safari user (or FF) who tries to put the URL inside the search field...
As a programmer you guess no-one would be that stupid (or, well.. unknowing), but people actually sometimes find themselves in these situations. As a programmer, we miss these things.