Ruby on Rails’ bundled support for automated testing has contributed to building a culture of testing within the community, but it’s also been a source of some debate. Differences in testing styles and preferences have spawned long-running discussions and flame wars over the years. Most of this amounts to bikeshedding, but if there’s one area where The Rails Way has lagged behind RSpec, it’s been in the area of end-to-end application testing. RSpec has long had expressive feature specs based on Capybara, while Rails default integration tests, though functional, have never been as expressive.
With the release of version 5.1, Rails introduces system tests built on Capybara. These look like just the thing to fill this longstanding gap, and the fact that they’ll be configured to work right out of the box with no additional setup required will make it easier for more developers to start using them. In this post, we’re going to look at the approach Rails takes toward system tests and what kind of advantages they offer over both old-school integration tests and current solutions for testing apps with Capybara.
API versioning is one of those topics that divides developers into two camps: those who just know that their way is the best way, and those that are confused by the first camp and would rather pass on the whole thing. Once we set aside the bikeshedding, there are sound, sane justifications for choosing one method over another, but in a lot of cases, discussions move from theoretical to hypothetical problems instead of worrying about making things that work.
The good news for Rails developers is that adding versions to an existing application doesn’t have to be painful. If you know what to do, you can implement it and maintain it with little effort.
In this article, we’ll look at what you get by versioning your API, why you need to think really hard before deciding not to, and how to update your application to make it work.
The introduction of API-only applications in Rails 5 makes it easier than ever to write simplified apps that render JSON responses. This is terrific news for those of us who’ve spent years building up expertise in the platform, but as we already know, getting off on the right foot makes a big difference in how development proceeds. This tutorial offers a quick overview of the first steps you’ll use to get set up and coding on a typical Rails API application.
In the last article, I explained why it’s a bad idea to test your Ruby code against real API endpoints and introduced WebMock as one option for stubbing out those integrations and keeping your tests speedy and manageable even as your suite grows.
That post used a really basic example application to show how to structure your tests under a simple use case. But writing and testing distributed applications is rarely that simple, and most of the time, you’ll find yourself needing to stub whole classes of requests and handle a number of common edge cases. So using the patterns from last time as a baseline, let’s now take a look at some other practical WebMock techniques to help you use it more effectively.
I’ve recently been working on a number of projects that are built on multiple Rails applications, microservices, and data from third-party providers. I can tell you one thing for sure: when your application is flinging JSON blobs all over the place, you can’t use the same direct testing style that you would with a monolith. Do so, and you create all sorts of problems for yourself including:
- Lousy test performance due to network overhead
- Unexpected failures caused by connectivity issues, API rate limiting, and other problems
- Undesired side effects from using a real web service (possibly even in the production environment)
But the thornier problem is the lack of control you have when using live APIs for testing. Working against a real system, it becomes a real trick to exercise your code against a full range of reasonable (and unreasonable) responses, so you find yourself stuck testing a few “happy path” scenarios and perhaps any cases that might happen to throw an exception from somewhere in the stack.