Let’s face it, we all know Selenium is slow. Not the Selenium scripts themselves, but the process of interacting with the operating system and browser drivers, in addition to your application’s own responsiveness. Luckily for us, there’s a great way to speed up functional testing in Selenium by combining a comprehensive parallel testing grid with application mocks. Solutions like Sauce that offer a cloud-based testing grid go a long way toward improving the performance of your test runs by using optimized infrastructure and running parallel tests. This has the benefit of completing testing faster, but more importantly, avoids causing delays in application releases if your test fails for any reason. Of course, even with an optimized infrastructure and the capability to run parallel tests, the tests will only run so fast against your entire application. The speed is affected by the response time of your application which is directly attributable to your back end. So Remove the Backend! Removing the back end means creating an application mock which is just your application stripped of any back end. Without the back end to slow down processes, the responsiveness of your application is nearly instantaneous. Selenium operations execute much more quickly when they don’t have to wait for the production or test back end to respond. The time savings is relative to your application, but in my experience there was a 20 times (or more) increase in time savings. Some additional benefits to the application mock scenario are:
Faster testing, fewer delays;
Less time cost for failed tests;
Faster iterations on front end bugs; and
The ability to implement continuous testing.
But a few of the downsides are:
Inability to identify back-end to front-end related bugs;
Some assumptions are created on setup; and
Ongoing maintenance is required.
In a robust and ideal environment, you’ll still implement end-to-end testing with the back end, but application mocks are a great way to test in real-time. Since running a test is so fast, exposing the mocks to developers so they can test their code against the entire application on every commit is easy. Application mocks also allow the QA team to focus on the end-to-end testing so the front-end team is able to address bugs faster. Although application mocks are not intended to replace the standard Continuous Integration (CI) or Continuous Delivery (CD) processes, overall they are a way to fail better and faster—a second, even faster CI environment. With a more elaborate setup, you can test by keeping the back end in a limited capacity using a stripped down service virtualization to mimic back end responses, without the large overhead that your production or staging back end has. Implementing Application Mocks The initial setup of the mock environment does require some work, but is worthwhile in exchange for the benefits. There are five steps to framing the setup:
Take the current version of your application in production and deploy it to a limited infrastructure.
Wire up the integration setup using an integration tool like CircleCI, Jenkins or GO, with webhooks into GitHub or other source repository .
Modify the application. This is where it can get tricky, and your development team will need to creatively approach how to deploy the application as mock mode or production. In my experience, the best method is simply a flag in the code for each developer branch.The mock version of the application requires that there be no link to the back end unless you use the service virtualization option. In this version, all interactions with the UI will assume a positive response: if you click login, you are logged in as an authenticated user without any database lookup for the user. Unfortunately, for most applications you will either need to make some assumptions or establish different flows depending on the test iteration. For example, if you have two versions of your application, you can set your login to determine which loads. In addition, you can hard code the “test” user, so that different users are known to the app in mock mode to go to different locations. Alternatively, you can set the system so every second test run follows the flow to the “Enterprise” edition instead.
Configure Sauce Connect on your testing infrastructure to allow Sauce Labs to see your internal mock testing environment and run tests against the mock version of the application. Set up Sauce with two different sets of the same testing scripts—one for mock and one for pre-release.
Taking the process one step further, configure log analysis and error monitoring on the mock environment to help your developers identify non-obvious bugs. Since the size is so small relative to production, and the resources required to run the application are so low, it is viable for each developer to have their own mock environment. This is especially true when testing is run on Sauce Labs infrastructure. The above model is intended for web applications, but translates well to mobile applications, assuming you have the ability via API to drive emulators and have a robust testing grid of mobile device emulators. The above is a simplistic presentation of the setup, because all applications are different. Regardless of the possible complexity, the practice works to help companies test better and faster. While you can’t make the Firefox or Chrome web drivers for Selenium tests run any faster, you can create a mock version of your web application that responds lightning fast, allows front-end developers to do functional testing continuously and prevents failed test runs or slow Selenium scripts from delaying releases. By Chris Riley Chris Riley is a technologist who has spent 12 years helping organizations transition from traditional development practices to a modern set of culture, processes and tooling. In addition to being a research analyst, he is an O’Reilly author, regular speaker, and subject matter expert in the areas of DevOps Strategy and culture and Enterprise Content Management. Chris believes the biggest challenges faced in the tech market is not tools, but rather people and planning. Throughout Chris’s career he has crossed the roles of marketing, product management, and engineering to gain a unique perspective of how the deeply technical is used to solve real-world problems. By working with both early adopters and late, he has watched technologies mature from rough solutions to essential and transparent. In addition to spending his time understanding the market he helps ISVs selling B2D and practitioner of DevOps Strategy. He is interested in machine-learning, and the intersection of BigData and Information Management.