You Can't Control What's Bigger than Yourself
Here in the great state of Kentucky it’s Derby Day, the first Saturday of May. The running of the Kentucky Derby is a world famed event, and draws visitors from royalty to rock stars to our state. Someone recently asked me if everyone in Kentucky had horses. I said no, but honestly, in the town where I live I believe everyone either owns one at one point in their life, or has access to one through family or friends.
Growing up I lived on a family farm. My grandparents, great-grandparents, and uncle all lived on the same farm within walking distance of my parent’s house. Sometimes that walk was a gravel road, and sometimes through a corn or a tobacco field. As my grandparents grew older they stopped growing crops and raised cattle in those fields. That gave them the opportunity to have horses. I loved horses, and can still tell you the names of each one they had (Dolly, Midnight, and Ginger).
One of the best gifts I received as a child was from my grandfather on his 62nd birthday. On his birthday, I was the one getting the present! Her name was Lady, and she was a beautiful golden blonde pony with a white mane and tail. She was old and gentle. I had her until I was in my late teens. During that whole time I never put a saddle on her. She simply didn’t need one. And rarely did I have to bridle her. I would take her by the mane, walk her up to the old bush hog beside my grandparent’s barn, step onto the bush hog to be taller, and then swing my leg over her back and ride. Just pulling her mane left or right is all she needed to be directed. That is, except for one day.
One hot day in the summer when I was about 12 years old I decided I was going to ride Lady. I got on her as usual, and she started walking. We were doing just fine until she turned to an old turtle pond. That pond was nothing but small fish, usually bluegill or sun perch, and turtles. It was muddy, would become covered in green algae most springs, full of snapping turtles, and yucky! Without so much as a hesitation, in spite of pulling back on her mane and all my commands to “Woooaaaahhh! Stop! Lady WOOOAAAHHH!!!” she went into the pond with me on her back.
I waited for her to come out of the pond for quite some time before realizing that wasn’t going to happen. It was hot, and the pond is where she wanted to be. Finally I climbed off her back and into the pond. My feet sunk inches deep into the muddy pond bottom and I had to walk out. (Being afraid of the snapping turtles, it really was more of a brisk jog than a run!)
Lady taught me a good lesson that day. You can never be in complete control of anything bigger than you are! Some development tasks and projects will take you places you never intended to go. What starts out as a short ride can end up as a swim in a turtle infested pond!
So how do you control something that becomes bigger than you? The same way you eat an elephant – one bite at a time. You can test much of your code long before delivery. There are various phases of testing, but the ones the developer is most concerned with are Unit, Integration, System, and Regression testing. (For more on testing phases, consult the SWEBOK guide.) These lead to the tweaks and changes that only a developer would notice. The project scope or user stories don’t change because of this type of testing – just the coding.
Know When to Get Off the Horse
We all have those little sensors that go off when developing that tell us when the code we’re writing is “iffy”. That’s the time to stop coding, and test that segment of code. Sometimes it’s as simple compiling the object at that point, and placing the object into debug to test the value of the variables.
Other times it may take a bit of development to test the code. I keep a simple processing-only report in my arsenal of tools just to test things like date calculations, setting unusual filter sets, and string manipulations. It’s a report using INTEGER as the data item, with a filter set on Number = 1. You can also use a codeunit, but I prefer the report.
Any time I need to test a few lines of code, I just add the global variables I need, the lines of code, and possibly a message statement to return the value of a variable. By doing it at the point that I sense there could be an issue, I alleviate the possibility that I will forget the “iffy” feeling when the whole task is done and ready to test.
Breaking it Down
Code can get complicated sometimes. If-begin-else-if-begin-else-case-case-case-end-end-else-if-begin-end-end-end– and how do you test all the various scenarios to get all the code tested? Sometimes code can be pulled apart and put into callable functions. When you can do that, and pass the parameters you need to test (either as multiple records with a variety of data, or simple strings of parameters), you can reduce the testing effort. If you can control the input to the code, you can test each code section quickly, rather than waiting for the data to hit all the sections of code to complete your tests.
Have the Proper Tools Available
The one and only time I can remember wishing I had bridled Lady was that fateful day I ended up in the pond. If I’d had that bit on the bridle in her mouth, I’d have been able to stop her from going in. Having the right tools at the right time is crucial to proper testing.
Build a developer’s toolkit database, and set up the developer’s toolkit. Sometimes when you’re coding something like an additional option to an option field, you need to know things like ‘is this field ever compared with a “<>” to a single option where my new option could come into play?’. Other times it’s questions like ‘where is this key being used that I’m about to add another field to?’ or ‘where are records added to this table?’ Having a developer’s toolkit database already prepared and loaded with your most recent set of objects makes this a quick process.
If you’re not familiar with the Developers Toolkit, talk to your VAR about it. There are two versions, the latest of which is for 2009 databases and forward. There are many tools in the kit, including string searches within the database code, and where-used tools for fields, tables, or other objects.
NOTE: The toolkit is discontinued effective October 1, 2011, but is still downloadable and accessible if within your license. Other tools, such as Mergetool and Object Manager Advanced, are also available. What version of the NAV database you are on and which client you are using weigh heavily in determining which tool is best for you.
Test the Water
Just as rain can change how a horse runs in the Derby, the data can create issues with your code. An unexpected value in a field you are filtering, or sets of records retrieved by your filters rather than a single one, can cause unexpected results. Testing your code with fresh data is vital to good testing. But to create your own data, you have to know the process that users follow to enter the data.
I can enter a sales order into NAV any day of the week, but I may not know all the varieties that are used by my company. Knowing the database from a user perspective is crucial to getting good test data for your code tests. Review past data entries – either in the current tables, or the posted versions, to determine if you’ve met all requirements for testing. One of the things I find that is often missed in testing of NAV documents such as Sales or Purchase Orders are the two line types of “G/L Account” and “Resource”. Because these are not used as often, we tend to forget they are there.
Likewise, when making changes to a posting routine, test the various document and record types. Just because you’ve coded your changes for Document Type::Order only doesn’t mean it won’t affect other types as well. The only way to know is test!
This one tends to get by developers more often than any other. We use special licenses to code changes into a database that has object permissions that our users may not have in their NAV license. The licenses give us special access to data as well as code.
Simple changes such as adding data to a field in a ledger entry table will work fine with our development license, but throw errors when used with the company license. You may have to assign permissions to the tables from the object properties itself. (If you’re working for your own company and using the company license, you won’t encounter this specific permission issue.)
Perhaps you just added a codeunit to the database. Even though the database license has 100 codeunits in it, they may not be “assigned”, meaning they have not been given a numbered object range (i.e. 50000 - 50099) to make them accessible to the user. You’ll find this immediately if you test with the database license.
If your code connects to an outside database, which is more and more common these days, be sure your users have been granted access to that database. This could be a SQL Linked database that is being accessed by a NAV called stored procedure, or an import that is pulling data via linked SQL tables.
You should also test with your user’s roles and permissions. Have you added a new table? Add it to the “ALL” permissions role, and assign special permissions as needed to the object and users. Delivering code without the proper permissions is like delivering a new car with no gas!
Scripted User Testing
Who knows better where the horse is going than the rider? As you write your code, you are continually thinking about the various things that are going on in the code you are delivering. You see some of the possible pitfalls long before they happen. Record these, take note of them, and test the ones you can yourself. But some of them you may not be able to test either due to customizations you aren’t familiar with, or a lack of data to sample in your development database. Deliver the scripts of tests to your users for use during acceptance testing (when the user gets to take a crack at your code before it’s in production). By noting these things as you go through the coding process, you increase the quality of the code that goes into production.
TIP: I thought I’d give you a tip for the Kentucky Derby in closing: What tests well does well! If you’re trying to pick a winner, find out how they did in the practice runs on Friday. Rarely does a horse change overnight. (Disclaimer: If you go and lose all your money on that Friday winner, I cannot be held responsible. I’m just a gal from Kentucky, and I’ve had good and bad experiences with horses.)