Friday, November 14, 2014

Test your RESTful API using PowerShell

Before I get into the "how" on this topic, I want to start by addressing the "why" and "when", as in "Why / When the heck would I want to do this?" Here are some situations I've run into or thought of where having a functional test script was (or could be) rather handy:

  1. You have unit tests for your API, but also want some "client-facing" tests as well.
  2. You want to make sure when a new build is posted, the routes operate as they did before.
  3. You inherited an API that you need to maintain, but there are no unit tests.
  4. You need to provide some kind of automated test for your application, but do not have time / budget to write a full suite of unit tests.
  5. You do not like writing unit tests, but still need some kind of test coverage solution.
  6. You REALLY like automated tests, and can't get enough of them :).

So now with some (mostly) real-world uses in mind, let's take a look at how this can be accomplished with PowerShell. My code is posted below; take a minute to scroll down and read it, then come back up to the next paragraph. I want to point out a few nuances that will make more sense within the context of the code sample.

Finished? Cool - let's dig into the nitty-gritty:

Invoke-RestMethod vs. Invoke-WebRequest

If you read the code carefully, you probably noticed that I've used two different PowerShell functions to call the API - Invoke-RestMethod and Invoke-WebRequest. Gah? Why not just use one or the other? Well, I ran into a known issue while writing a test script for an API I built recently, and this was the recommended workaround. Essentially, if you're going to make multiple subsequent PUT or DELETE requests from a PowerShell script (which you'll probably want to do at some point), Invoke-WebRequest is the method to use for those HTTP Verbs.

-SecondsAllowed

Each of my RunRoute functions in the script has a $SecondsAllowed parameter. This allows you to do strict performance testing of your routes (should you choose to do so) by specifying the number of seconds until the route times out when you call each function using the -TimeoutSec parameter. If you don't want to set a timeout for certain tests, just pass a zero.

-DisableKeepAlive

I include this parameter on every request. According to the documentation, this tells PowerShell to "[establish] a persistent connection to the server to facilitate subsequent requests.". That seems harmless, but in a production setting, we have no clue IF there will be subsequent requests by the caller. I've noticed test scripts will run slightly faster without this parameter, which can disrupt the timing of the -TimeoutSec check discussed in the previous paragraph, and potentially cause you to get a false sense of "real-world" performance.

-Headers

Invoke-RestMethod allows for a -Headers parameter, but I'm not using it in the code sample. The test API is very basic, and doesn't require me to provide any headers to interact with it. However, I want to mention it here because you'll likely need to add this to tests for a production API, since this is usually where you would exchange security information with the server. The param accepts a hash object like so:
$RequestHeader = @{};
$RequestHeader.Add("Key", $Value);
Invoke-RestMethod ... -Headers $RequestHeader;
You can put as many custom headers into this collection as needed. Check the documentation for further details.

LOG_FILE

I don't specify where to create the log file; it should default to - C:\Users\{your-name}. Just update this variable to change the output location. The log will contain an entry for each RunRoute call you make, indicating PASS or FAIL of the executed route, as well as total run time for all of the routes in your script.


Here's my sample script. The API which I wrote the tests against (jsonplaceholder) is publicly accessible, so you should be able to just download the code and start running it. I'm hoping once you've done that and stepped through it a few times, it will be fairly clear how you can modify the structure I've provided to fit your specific API.

* Like this script? Have a look at some of the other PowerShell scripts I've published.

Tuesday, September 23, 2014

Design and document your RESTful API using RAML

Creating documentation is one of the more tedious aspects of the software development process. Not that writing algorithms and object-oriented class hierarchies isn't tedious, but it often seems (at least to me) that writing plain text explaining your code is more tedious than writing the code itself. Also, if you consider yourself an Agile practitioner (as I do), you're always evaluating the time spent vs. value added whenever you write much about working software outside of and separate from the working software you already wrote.

I find myself constantly analyzing and re-analyzing the darn thing. Is it too long? Too short? Too wordy? Oversimplified? Too granular? Too vague? Should I have even attempted this?

I don't claim this conundrum is unique to me. It's one of the main reasons that many software projects are undocumented or under-documented. Because of this, a tool that helps you write clear, simple documentation, and saves you time doing it, is an invaluable find.

RAML is one of these fabulous creatures.

I was introduced to RAML by a colleague while working on an ASP.NET Web API project over the the last few months. What I like best about RAML is that it solves multiple documentation problems through the creation and maintenance of a single file:

  • You can design and modify your API collaboratively without writing / re-writing any code.
  • The syntax is simple and to-the-point, reducing time needed to properly describe the routes, actions and parameters.
  • This document serves as a team "contract" of sorts throughout the development process. Server-side developers, client-side / mobile developers, and testers - everyone - can see and agree on the intended behavior and content of your API requests and responses.
  • When the project is done, you're left with an excellent artifact to hand off and / or publish describing exactly how your API works.

Now that's what I call valuable documentation. To get started, all you really need to write a RAML doc is a text editor and access to the spec. However the team over at MuleSoft has developed a superb browser-based editor for RAML, complete with spec references and "intellisense" of sorts. Best of all - it's free to use. They've labeled it as "API Designer" on their site; here's a sample:

I used it for the project I mentioned above; I found it to be far quicker than writing a text-only version. Being able to click on and view the routes on the right side of the screen was also a really handy feature during various design and testing discussions. I found the API Designer to be a solid tool, and highly recommend it.

So the next time you kick off a REST API project, *start* with the documentation - and write some RAML.

Saturday, April 26, 2014

Agile - principles make the processes work

Over the past month or so, I've seen a number of articles pop up announcing the "corruption" and "failure" of Agile. Here are a couple that specifically caught my eye:

Some thoughts from Mike Hadlow detailing "Why Agile has failed":
"Agile has indeed become a cargo cult. Stripped of actual software engineering practices and conducted by ‘agile practitioners’ with no understanding of software engineering, it merely becomes a set of meaningless rituals that are mostly impediments and distractions to creating successful software ... If your role is simply asking for estimates and enforcing the agile rituals: stand-ups, fortnightly sprints, retrospectives; then you are an impediment rather than an asset to delivery ... the word ‘agile’ has become so abused, that we should stop using it."
Additional thoughts from Magdy Hanna taking "A close look at the Agile Manifesto after 13 years":
"Recently, I was asked in an interview whether I believed that the Agile Manifesto is a good starting point for people who are new to agile. I found myself saying that I hope our young software engineers do not see the Manifesto! ... it ended up with a proliferation of systems that have no documentation and are totally unmaintainable ... This is exactly what has given management the excuse to push releases to production even with minimal documentation, minimal levels of discipline, and no repeatable processes being followed ... Let’s be very careful before we decide to adopt these practices."

Some pretty serious charges being leveled against those of us (including yours truly) who consider ourselves to be "Agile practitioners". As a member of this group, please allow me to respond:

I agree with you all. You're right. Well, partly right at least.

"Bad Agile", as these people seem to have experienced, is just that - bad. Hadlow rightly states, "it merely becomes a set of meaningless rituals that are mostly impediments and distractions". So what happened in these situations the authors describe? Why is it that some shops and teams have superb success with an Agile approach and others don't?

The truth is, it has nothing to do with the processes you use. To succeed with Agile, you must consistently apply the principles to your work.

This is well stated by Andrew Binstock in his piece on exposing "The Corruption of Agile":
"The fascination with today's way of doing things and the view that it is the one true path to good code is a seemingly permanent part of the programming culture. But it has been greatly abetted by the legions of Agile consultants. By stressing the practices, they have corrupted what Agile was about. It's important to remember that the Agile manifesto stated values, not practices." ... "Agile was a personal practice. Implicit is a personal way of orienting oneself towards a process that accepts, even welcomes, change." ... "you could have a fully Agile site without TDD, continuous integration, or scrum. Likewise, you can have a site that uses all three practices, but cannot adapt to changes and is wholly inflexible in its work — so, not at all Agile."

Consider the four "pillars" of the Agile Manifesto - People. Collaboration. Responsiveness. Results.

Consider The Essence of Agility - Observe. Orient. Decide. Act.

If you find yourself or your team struggling with Agile and feeling like it's a "failure", consider your situation. Are you focused on these principles? If not, perhaps it's time to respond and re-orient.

Tuesday, March 25, 2014

Great advice for beginning consultants

This year, I've had the privilege to undertake a part-time coaching engagement (~8 hrs a week) outside of my normal job responsibilities. It's with an IT hardware solutions firm that my employer has been partners with for a number of years; they actually host all of our production servers. They have a small software team they've been trying to get going for the past 18 months or so, but have really struggled with it for a variety of reasons. Having visited my shop a few times, they really liked our approach to software development and wanted to emulate it with their team.

I was really excited for the opportunity, but also a little nervous, having never done something like this before. I wasn't really sure how or where to start. After thinking it over, I decided the best first step was to talk to someone who had done something like this many times.

So I emailed my coach, explained the situation, and told him I'd greatly appreciate and value any insights he might have for "a newbie heading out on their first 'mission'". His reply was golden:

Great to hear about your part-time coaching engagement. And thank you so much for inviting my thoughts.

Even though they say they want to “emulate” [your process], [I] highly suggest you really take the time to appreciate their nuances (not to say that you wouldn't already) so that you can help them really discover their true identity. We’re all human, and I have found that far too many coaches are too eager too quickly to prescribe a solution versus really deeply appreciating the nuances of the current situation before moving towards offering suggestions and then co-creating a solution with clients.

Additionally, [I] suggest adopting mindset/behavior incrementally so as to not negatively impact their existing operations. However, if they are in extreme pain, it may be worthwhile to consider more drastic/aggressive adoption of mindset/behaviors.

Please don’t hesitate to reach out anytime (even if you just want to talk through what you are experienc[ing] & thinking and would like to explore together). Good luck. *

I've gone back to it many times throughout my engagement, and I'm sure I'll take it with me to future opportunities as well. Frankly, it's incredibly good advice for anyone beginning a new job of any kind, not just a consulting project. I just couldn't let it continue to sit in my inbox; it needed to be shared.

I hope you'll give it some thought when your next opportunity starts.


* I need to give credit where credit is due. Si has been my coach and friend for a number of years now. I sincerely hope you have the opportunity to work with him at some point; great teacher, great speaker, great thinker, great writer, and all-around awesome guy.

Sunday, January 26, 2014

Personal Retrospective - 2013

I wrote a personal retrospective last year, and intend to continue that practice going forward. If you've never done it, I highly suggest giving it a try. Publishing goals makes them (and the possibility for public failure) very real, and has helped me focus my time and efforts on achieving them.

As was the case last year, I got another considerate and much appreciated "Happy Holidays" email about a month ago from the same career mentor / role-model containing his personal retrospective. In replying, I described my year professionally as having been "bumpy". On the plus side, I did pretty well on my goals that I had set out to accomplish. However, there were also some shortcomings in each case as well:

"I spent about 22 hours a week in meetings ... I want to ... get a day back per week" - B-

That would make the goal about 14 hours a week. I ended up averaging 15.6. Definitely a big improvement although not quite as low as I was looking for. Also, one of the places I cut down meeting time was monthly 1-on-1 meetings with staff members. I switched from once a month with each individual to an "open office hour" on Fridays. My thought was that people could come by as they needed assistance or time to talk about things, each person able to use the amount of time they needed.

Unfortunately, almost nobody showed up. I ended up feeling disconnected from some team members because of it, and I'm guessing some of them probably felt the same. In hindsight, that was probably too deep a cut and a poor decision on my part.

"I want to spend more time building things" - B+

The lower number of hours in meetings did allow me to spend more time building things, such as:
  • I managed to release 5 new versions of my wsubi open source project.
  • I was able to attend two workshops on mobile development, one of which was described in my previous post.
  • At the office, I was able to prototype possible implementation plans for technological upgrades to the three core areas of our main web application platform:
    • Client-side code (HTML5 compliance)
    • Server-side code (Classic ASP -> .NET Razor 2.0 / Web Services)
    • Database (SQL Server Data Tools; SQL 2005 -> SQL 2012 compliance)
However, when it comes to newer technologies, I didn't really feel like I was quite able to "roll up my sleeves and dig in" like I had said in my post last year. There were some extraneous factors (mostly monetary) that inhibited my progress in this endeavor; hoping those will be alleviated and I'll be able to make more progress here in the coming year.

Unrelated to the goals above, I experienced a few more "bumps" in the loss of some team members that I'd hired and coached. It's always tough when people leave, but if there's a silver lining to be found, it does feel good to have had a hand in their professional growth and to see them move on to good organizations like BMO Harris, Robert Half and Rockwell Automation. I will miss them all in 2014, but wish them the best in their future endeavors.

But enough on 2013 - on to 2014 and new beginnings! My goals for 2014:

Read more professional books

Usually I'm able to get through one or two, but I'm embarrassed to admit that I finished 0 books last year. That's a poor showing, and I'm going to do better this year. The top books on my list are (not in any particular order): Clean Code, Joy, Inc., Conscious Agility, and Programming Pearls. I'd like to get through three if not all four of them, although I'll leave it open to the possibility that another book I don't know about today may make it onto the list by the end of the year.

Coach more / better

As stated in my review of goal #1 from last year, I cut back in this area to reduce my time in meetings, which was probably a mistake. Lesson learned; I'm going to do better in this area in 2014 and beyond. I'm also excited to be doing some coaching outside of my current organization with some other software teams. This is a new experience for me, but I'm really looking forward to being involved in it and helping them improve as best I can; should be a good challenge!

Start a new coding project

This is more of a stretch goal I guess. I feel that goal #2 from last year is somewhat unresolved, and I have a couple of ideas that I'd like to explore this year. One is for a PowerShell UI Snap-In; the other is a mobile & web application I've been kicking around in my head for a couple of years but haven't had time to build. Both would be alot of fun, but I'm not sure yet if I'll have the time to dedicate to them. We'll see how the year goes.

Anyway, thanks for reading and best of luck in achieving your personal goals this coming year. As my coach said in his message to me, a healthy and prosperous 2014 to you!