The Fully Containerized Testing Strategy

January 15, 2018
Geoffrey Shenk

Elevate Your Testing Career to a New Level with a Free, Self-Paced Functionize Intelligent Certification

Learn more

Did you know that Tesla can deploy firmware updates to its Model S seconds after a developer updates a module to improve the car’s acceleration performance or refine the car’s console? Streamlined development-to-deployment efficiency arises elegantly from a smart automated testing strategy. The automated testing procedure guarantees that this code update does not break any other part of the system. So an alteration in the acceleration module will not cause the steering to go haywire. This ultimate use of continuous deployment is possible because the company exploits every imaginable tool and innovation available for software testing, including containerization. Using containers in the testing cycle accelerates the refined software toward the customer! This is part of a holistic software development strategy which we will explore right now.

Containerization is a method of isolating and encapsulating an application in its own operating environment which is lighter, faster, and quicker to start than a virtual machine. Virtualization, the original concept of containers, is distinctly different from and an improvement over the virtual machine. Also known as virtualization, this method operates en suite with automated testing methods like Selenium, Webdriver, and Cucumber to many advantages which we will look at here. With these methods a code change can go through the entire development pipeline in seconds with zero human intervention! Let’s see how such an ideal strategy is composed. 

Containers enable developers to package an application with all its dependencies in an operating environment which is independent of any local machine settings that might affect behavior in testing. A Linux developer is then free from concern about variations on a tester’s local machine, and enjoys absolute portability of deployment. 

Containers abstract and automate the OS level of Linux and Windows so that applications run independently. Docker, the popular provider, offers an API to operate containers in a state of resource isolation in separate namespaces, without launching an OS, unlike virtual machines which have higher overhead. 1 Container architecture is so light on resources that 10 or more instances can run simultaneously on a single server in common test scenarios. Containers optimize testing of distributed apps by enabling multiple tasks and processes to run in tandem. 

Strictly speaking, containerization is operating system level virtualization. This technology lightens the load across the entire development cycle and accelerates testing by abstracting devices rather than loading actual OS components and drivers. An instance of virtualization is called a container, and from the point of view of the application it is an emulation of a computer, without the resource cost of a virtual machine. This concept provides integrity in maintaining a consistent and verifiable test procedure, as well as efficiency. But the gold standard of container technology is standardization. 

Containers enhance the development and release cycle by guaranteeing a standard of environment behavior. Builds, tests, and production are consistently repeatable, which further empowers development teams to work in parity as they observe and document equivalent and verifiable outcomes. An enterprise can divide the testing schedule into several teams to work on easily reproducible containers. And these models are arbitrarily scalable, so that teams can determine how fluidly applications expand or contract with the business requirements of an enterprise. Teams working on identical container images thus communicate concisely with engineers who in turn more efficiently diagnose and repair errors. And those engineers are freed from the task of setting up testing environments. 

Another advantage of containers in the SQA scope is the ability to replicate configurations and establish dependencies once, and then maintain these throughout a development to production cycle. This obviates the stress of configuration checking at each cycle. Container image settings facilitate versioning and redundancy; rollbacks to previous versions are fast and simple. Furthermore, the resource isolation provided by container technology ensures that each stack’s resources are discretely managed. A container can be deleted by SQA without affecting other app images; it can equally be restored if deleted in error by referring to previous versions. Containers are literally a virtual Elyssium for SQA. 

From Theory to Practice 

How do automated testing tools flow harmoniously into the container context? Let’s look at a familiar suite of tools and how they work with containers. A common plan is to use Cucumber to invoke a sequence of automated tests which run through bowsers by running scripts in the Gherkin language - a scripting language which is more readable to less technical people - more English like. To implement such a plan several dependencies are required such as Gems, browsers, and a target test environment. Creating this test environment and easily replicating it is precisely the strength of container technology. Suppose we set up testing scenario for a Rails web application, and run Cucumber tests using Docker to ensure a stable and consistent testing environment. The setup is straightforward. 

Cucumber is a scripting language intended to connect business and development staff; the language is like English, and is “business-facing,” which means that the input and output is easy to read. The first step in a typical automated testing sequence might be to invoke a Selenium procedure from a Cucumber. Below is a depiction of how an example set of tools leads naturally into a Docker container setup. After creating a Cucumber-on-Rails app, one would add the app and database component plus Selenium webdriver Gems to a Gemfile under a group called “development and testing.” One can then write their Cucumber test scripts to Firefox to view the testing in the browser, making it easy to see the two images running at the same time. The next natural step is to set up the app for a test run in Docker. 

According to Docker documentation, a container should not have multiple responsibilities. Ordinarily, a web app stack such as described so far should have a container each for for web server and database, caching and test run. With this in mind, two Docker images will be needed for our example: one for our Rails web server and another for testing. Start the web server in Docker by creating a Docker script in the application’s root directory and add a simple script to implement the whole procedure. We can now run our app through Docker, and we will see the duplicate images running concurrently. 

Continuous Integration 

Continuous integration tools run their JUnit tests every time a developer updates a module to ensure the updates do not adversely affect other components in the system. This means that testing and development are interwoven and simultaneous. It also means that every code commit is tested immediately on every repository share with an automated build procedure. This is the ideal concept, but it is complex to engineer in practice. Container technology essentially standardizes the deployment of app testing so that production can be simulated accurately. Docker achieves this standardization by simulating the production environment on a local machine and thus executing modules in containers. Containers are automated using Docker Compose. Using Docker Compose it is possible to build identical testing environments for apps and include all their dependencies for each testing cycle. 2The authoring of standard test procedures in this way serves to reduce errors, especially in the repetition of phases. 

Down to the Wire 

Hubspot and Etsy use a continuous deployment network to deploy revisions many times every day. Hubspot actually stated that they deployed more than 200 times in a single day. This effort to provide a gratifying and accurate user experience. Under such conditions, every measure to increase the efficiency within an enterprise deployment cycle is crucial. 

Enterprises can pass a container image through the entire CD pipeline. Provisioning build servers and publishing tests, deployment of testing automata and the integration of testing environments are all deeply and powerfully facilitated by containerizing testing workflows. So persuasive are the benefits of the new container paradigm that several major enterprises have spawned their own container platforms from the Docker model to maintain their proprietary developmental ecosystem. And the new technology now asserts is influence on human resources as well. 

QA engineers today face extraordinary expectations of their base expertise. A typical Tesla QA engineer is required to command programming skills in Java, JavaScript/Type Script or Python, plus computer architecture and knowledge of debugging distributed systems equal to software engineers, in addition to the standard automated testing tools we have mentioned such as Selenium, Webdriver, Appium, Protractor, Jenkins, Cucumber. Now the list of requirements is bound to include Container technology. To bring the Model S up to speed optimally, the enterprise and the testing engineers will have to accelerate their container skills to meet the challenges ahead. Accelerated -- even continuous -- deployment lets new features and improvements reach customers quicker. Testing is what keeps this manageable, beneficial, and safe. Functionize presents QA engineers a new paradigm as we fully manage the infrastructure to create and execute testing automation, eliminating the hassle of managing outdated automation scripting languages and frameworks. 

1 https://www.digitalocean.com/community/tutorials/how-to-configure-a-continuous-integration-testing-environment-with-docker-and-docker-compose-on-ubuntu-14-04 

2 https://testingrepository.com/how-to-run-cucumber-tests-using-docker-in-parallel/