Step 14 - User Testing
This is part 14 of an 18 part series titled Vue.js Application Tutorial - Creating a Simple Budgeting App with Vue. It is highly recommended that you read the series in order, as each section builds on the last.
- Step 0: Intro
- Step 1: Planning Your Application
- Step 2: Data Architecture
- Step 3: Setup & Project Structure
- Step 4: Create & View Accounts
- Step 5: Edit & Delete Accounts
- Step 6: Adding LocalStorage to our Vue.js Application
- Step 7: Interlude & Refactor
- Step 8: Budgeting
- Step 9: Racing Through Budgets
- Step 10: Styling & Navigation
- Step 11: Finishing Budgets with Vue.js Dynamic Components
- Step 12: Planning for Transactions
- Step 13 - All Aboard the Transaction Train
- Step 14 - User Testing
The next entry is expected to be published on 03 August 2017. Sign up using the form at the bottom of this post to receive updates when posts are published.
Hey! it feels like our application is getting really close to a releasable state here. A very rough, untested beta release. But that's something. What we have is almost usable and possibly even useful. Pat yourself on the back. Or don't, because that's a really strange thing to do.
If a user visits Budgeterbium they find something that looks presentable, if not a little attractive.
They can add all of their financial accounts with a starting balance.
They can then setup a budget for this month (or another). A budget has spending categories, each with its own budget limit. As a category is added the entire budget for the month is dynamically updated. Categories are also saved for consistent use in future budgets.
Transactions can now be added. Each transaction records a date, a business name, a budget category, a note, and an amount. As a transaction is added, two things happen automatically. The associated account balance is updated. And the associated budget category's amount spent is updated, which updates the budget spend as well.
This is a great high level look at Budgeterbium. Before we release to the proverbial public we should ensure everything works as expected. (Hint: it doesn't.) We are not going to go through a traditional release cycle that professional software might use, but we should do our own user testing - run through every feature of the software in order to test its limits. Some of this work ideally should be covered by unit and functional tests, but we forewent those for the sake of a simpler tutorial.
So your task here is to go through the software and find as many bugs and issues and niggles as you can.
As you are testing, try to break things! The one thing you can be certain of when releasing software to the public is that users will do things with your application that you never expected. Your job here is to find all of those edge cases. One great and exceptionally common place to experience this - test the limits on your form fields. Try entering unexpected values in them in every direction possible.
I've done this experiment myself and came up with the list below, which we will be tackling in the next step of the tutorial. But I highly encourage the Readers to perform this task on their own. The odds are good that you will discover a problem that I missed.
Oh, and don't only look for bugs. Start keeping a list of things that are annoying or unintuitive. We are writing the software, we shouldn't have to deal with these annoyances because we can fix them.
Want to write tests but don't know where to begin? As you work your way through the application, write down exactly what steps you take take as you are hunting for problems. These should be detailed - every mouse click, every keypress entered, every pause, all the way to the results you received. With this list in mind, functional tests will practically write themselves.
While writing this list I'm going to assign each item a priority of either Low, Medium, or High. These are sort of arbitrary - as we don't have stakeholders or users dictating what we need to do. But it's a good exercise to begin thinking about what is important when developing a project. It might be tempting to tackle the month selector calendar right away because it is more interesting than mismatched budget categories, meanwhile those mismatches are causing problems in the application requiring us to frequently reset the database.
A user can attempt to save a transaction to a budget category that doesn't exist for the selected budget.
We're tackling the biggest systematic problem first. When setting up a budget for a month, the user budget categories to it. Then when adding a transaction, the user ties both a budget (via the date) and a category to the transaction. In the application's current state, the user can select a category that is not attached to the chosen budget. While this gives a console error, no error is presented to the user. Instead, nothing visible happens.
How can we fix this? I came up with 4 possible solutions.
- Filter the category list based on the budget date the user selected.
- Dynamically add the category to the budget when a transaction is added.
- Automatically add all categories to all budgets, so the user doesn't have to do this for each month.
- Simply show an error letting the user know they chose an invalid category.
The first two options are relatively minor bug fixes. The third choice would significantly change the way our application works - I would classify that as a feature change or a refactor.It's worth putting some serious consideration and planning into whether this user workflow would be better than the current one, and whether it fits within the methodology our application is promoting. The final choice might be an acceptable stopgap, but it isn't a permanent solution since it doesn't improve the user experience.
For now, I'm going to go with option number 2. It synchronizes well with our goal for an easy, intuitive user experience. It also sits well within a real-world model - sometimes expenses come up that you don't expect and plan for. We'll add the third choice to the backlog to explore further.
User story: when a user adds a transaction to a budget category that does not exist on the budget, a budget category should be automatically added with a budget of $0. High priority
A user can attempt to save a transaction to a budget that doesn't exist.
This is essentially the same problem as the previous bug. I won't go into details, but we're going with a similar solution.
User story: when a user adds a transaction to a date that does not have an existing budget, a budget and a budget category should be automatically added. High priority
After adding a budget, the user is redirected back to the list of budgets.
When I add a budget, I almost always want to edit it right away. The current workflow makes me click back into it, adding some frustration to the process.
User story: the user should be redirected to the newly created budget after adding a new budget. Low priority
Selecting a day of the month to represent a month's budget is confusing.
Not much needs to be said here - we were aware of this problem at the time, but left it as is. We'll create our own month-selector in a future tutorial.
User story: create a new month-selector component. Medium priority
Accounts don't immediately show in the sidebar after being added.
The user must refresh the application before the new account is added to the sidebar. This is an easy fix, stemming from an easy (but dangerous) mistake we made early on of not following some Vue.js best practices.
User story: when a new account is added, it should show in the sidebar automatically. Medium priority
There are times where I find the "user story" model limiting and this is one of them. After fixing this bug, I want to go through and ensure I do not have a similar bug in other places in the code that I haven't noticed yet. This doesn't translate well to a user story, but should still be an important task on the list.
A user has to switch from the keyboard to the mouse to click 'Add' or 'Save' when adding a line item.
What might seem like a minor irritance really does become a detrimental problem when you're using the application for any significant period of time. It's important to not break expected user functionality.
User story: when the Enter key is pressed in a form, the form should be submitted. Medium priority
Updating a transaction does not update every corresponding value.
This is something we left for later when creating the transaction module. Time to get it done.
User story: when a user updates a transaction, all corresponding values should be updated. E.g., moving a transaction's date to a different month should change both budgets; editing a transaction amount should update both the budget and the account balance. High priority
A user should be able to delete a transaction.
User story: a user can delete a transaction, which updates all corresponding values. Medium priority
Adding income to a budget category can show a positive value in the spent column.
While there is nothing technically wrong here, there's a clear breakdown of our system. The solution I'd like to implement is to log income as off-budget.
User story: a user can report income for each month. This does not affect their budget amount for the month. A 'log as income for this month' shows up in the budget category dropdown. Low priority
There is no reporting in the application.
This, of course, becomes a very big project in and of itself. I'm adding it here for completeness sake, as I was really craving some basic reports while testing.
User story: a user can view reports of their spending habits and budgets. Low priority
Some budget fields show strange dollar values like $-1419.5642.
We have largely ignored proper currency handling while developing our application, because it's beyond the purpose of the tutorial, and we're going to continue doing so now. (Sorry non-Americans!) So long as all of our values are operated on as floats, I'm not concerned with tiny rounding errors. We'll simply truncate all these values when displaying them.
User story: a user sees all dollar values in the application in the proper $XXX.XX format. Low priority
Forgetting to select a field in a transaction results in an error invisible to the user.
One other thing we ignored to this point is error handling and form validation. This one we're going to fix!
User story: when a user submits a transaction without a proper budget, category, business, or account selected a helpful error message is displayed to the user and the form is not submitted. Medium priority
A user can add an empty budgeted value to a budget category, resulting in a NaN error.
Continuing on with form validation, we should not allow a user to add an empty value to a budget category.
User story: when a user submits a budget category without a budgeted value, a helpful error message is displayed and the form is not submitted. Medium priority
A user can add multiple identical budget categories to a budget.
This looks like a form validation problem, but we're going to solve it another way.
User story: a user can only add a category to a budget once. Once a category is added to a budget, it no longer shows up in the select dropdown. Medium priority
The date selector for adding a transaction always defaults to today.
As a user, I often want to enter a list of previous transactions at once. These typically have the same date, or sequential dates. This would be a nice quality of life improvement.
User story: after a user adds a transaction, the next time they go to enter a transaction the date is set to the previously entered value by default. Low priority
As a developer, I want an easy way to load test database values.
I'm tired of re-entering information every time I change something or break something! There should be a good way to load a test database from a JSON file while developing the application.
Find problems that I didn't discover here? Open an Issue on the repository!
Just when we thought we were almost finished with the application, we now have an enormous list of tasks to tackle. Thankfully there are some lessons to be learned while working through this list, which is what we'll do over the next few sections of this tutorial.