There are lots of small suggestions I’ve learned from experience when it is time to create a suite of integration / UAT test for your project. A UAT or integration test is a test that exercises the entire application, sometimes composed of several services that are collaborating to create the final result. The difference from UAT tests and Integration test, in my personal terminology, is that the UAT uses direct automation of User Interface, while integration tests can skip the UI and exercise the system directly from public API (REST, MSMQ Commands, etc).
The Typical Problem
When it is time to create a solid set of such tests, having them run in an automated build is a must, because it is really difficult for a developer to run them constantly as you do for standard unit tests.
Such tests are usually slow: developers cannot waste time waiting for them to run before each commit, we need to have an automated server to execute them constantly while the developer continues to work.
Those tests are UI invasive: while the UAT test runs for a web project, browser windows continues to open and close, making virtually impossible for a developer to run an entire UAT suite while continue working.
Integration tests are resource intensive: when you have 5 services, MongoDB, ElasticSearch, and a test engine that fully exercises the system, there are little more resources available for doing other work, even if you have a really powerful machine.
Large sets of integration/UAT tests are usually really difficult to run for a developer; we need to find a way to automate everything.
Creating a build to run everything in a remote machine can be done with VSTS / TFS, and here is an example.
Figure 1: A complete build to run integration and UAT tests.
The build is simple; the purpose is having a dedicated Virtual Machine with everything needed to run the software already in place. Then, the build will copy the new version of the software in that machine, with all the integration test assemblies, and finally, run the tests on the remote machine.
Running integration and UAT tests is a task that is usually done in a different machine from that one running the build. This happens because that machine should be carefully prepared to run the tests and simplify deployment of the new version.
Phase 1 – Building Everything
First of all, I have phase 1, where I compile everything. In this example, we have a solution that contains all .NET code, then a project with Angular 2. We first build the solution, then npm restore all the packages and compile the application with NG CLI. Finally, I publish a couple of web sites. Those two web sites are part of the original solution, but I publish them separately with an MSBuild command to have full control of publish parameters.
In this phase, I need to build every component, every service, every piece of the UI needed to run the tests. Also, I need to build all the test assemblies.
Phase 2 – Pack Release
In the second phase, I need to pack the release, a task usually accomplished by a dedicated PowerShell script included in source code. That script knows where to look for dll, configuration files, modify configuration files etc, copying everything into a couple of folders: masters and configuration. In the masters directory, we have everything needed to run everything.
To simplify everything, the remote machine that will run the tests is prepared to accept an XCopy deployment. This means that the remote machine is already configured to run the software in a specific folder. Every prerequisite, everything needed by every service, is prepared to run everything from a specific folder.
This phase finishes with a couple of Windows File Machine copies, to copy this version on the target computer.
Phase 3 – Pack UAT Testing
This is really similar to Phase 2, but in this phase, the pack PowerShell scripts create a folder with all the dll of the UAT and integration tests, then copy all test adapters (we use NUnit for unit testing). Once the pack script is finished, another Windows File Machine Copy task will copy all integration tests on the remote machine used for testing.
Phase 4 – Running the Tests
This is a simple phase where you use Deploy Test Agent on the test machine, followed by Run Functional Test tasks. Please be sure to always place a Deploy Test Agent task before EACH Run Functional Test task, as described in this post that explains how to Deploy Test Agent and run Functional Tests.
For complex software, creating an automated build that runs UAT and integration tests is not always an easy task, and in my experience, the most annoying problem is setting up WinRm to allow remote communication between agent machine and test machine. If you are in a domain, everything is usually simpler, but if for some reason the test machine is not in the domain, prepare yourself to have some problems before you can make the two machines talk together.
In the next post, I’ll show you how to automate the run of UAT and integration tests in a more robust and more productive way.