Last time I discussed some of the improvement I’ve seen in development since automated tests have been a standard part of our development process. I also promised to continue discussing what I will be speaking on in May at CreatorCon. So let’s get to that today with a look at server side unit testing using something I’ve developed (and am continually working on to make usability improvements), UnitTestNOW.
Link to Download Update Set
After installing the update set, bring up the UnitTestNOW application in your left nav. It should look like what is the picture below:
Click on Scheduled Unit Tests, and the the New button at the top of the page to make a new Unit Test record.
Give your unit test a name, and if you’d like, change how often it runs. You can also take this opportunity to link it to a script include.
I’ve left the default script field to contain the setSetup and setTeardown functions, but if you don’t need to create anything, feel free to ignore them or delete them. Set the nae of the table with the setTableName function, then change the test name.
Inside each test, set the name of the function you are testing with the setFunctionName function. Now you’re officially ready to test.
An example of each assertion is in the default code. You may want to copy them for easier use later.
Inside the body of the test function, create the logic to run your tests. For example, let’s take the following script include: TaskStateUtil, which is an out of the box script include. I simply picked this one at random.
Right off the bat I see that the isStateInactive function is ripe for a test. It just takes a single parameter (state), and returns a boolean if it’s an inactive state, based on the constants of the class.
So let’s write a test for that function. Looking at the constants, I expect that 3, 4, and 7 will be my inactive states.
I expect a pass here, but much to my surprise, I’m given a failure.
After adding some log statements, I find that the variable “this.inactiveStates” was “undefined”, which is why it never hits the true condition. I replace that variable with this.SYSTEM_INACTIVE_STATES, which is class constant, and…
Horray, the test passes, just like we expect. Let’s add a few more cases, testing -5, 0, 1, 2, 4, 5, 6, 7, and 8.
Great, everything is working fine so far. Let’s see what happens if we add them as strings. I expect them to work just fine.
Once again, everything passes. Fantastic. Let’s add cases for an empty input, an empty string input, null, and undefined, just to make sure we get “true” (since none of those are 3, 4, or 7).
Is this satisfying enough for one method? We have 22 tests for it. If this behavior is desired, and we feel we have enough scenarios, let’s move on. If something is bothering you about this, keep at it.
We could make this test production safe in a couple of ways. One, we could change the initialize method to not completely crash if it doesn’t receive a GlideRecord. (Try creating the TaskStateUtil object without a GlideRecord, and see what happens!). That way we don’t need a record at all to any tests. We could also get a record we know will be there, but that’s a lot less reliable and is prone to errors caused by a record being deleted or cloned over.
As some of you may know, I’m speaking at CreatorCon this year about the subject of automated testing in ServiceNow. If you plan on attending my session, I’m going to speak on server side unit tests (using SNUnit/UnitTestNOW, which I’ve recently made a little better), client side unit tests (using QUnit), functional acceptance testing (using Selenium Web Driver), and web services testing using REST Assured. Since we’re roughly four weeks away, I’ll spend some of that time previewing what I’m discussing.