My name is Warren. I’m a software developer at Net Reply UK working primarily with Golang on an agile project, developing microservices for a client. Within our project we use many forms of automation to speed up the development process using CI/CD (continuous integration/continuous deployment) which includes automated testing. The purpose of this blog is to discuss automated testing within projects, to outline how this is done on a high level as well as explaining how beneficial automated testing is within any software project.
Source: https://www.onpathtesting.com/
The above image is the ‘Agile Testing Triangle’ and it’s important to understand this visualisation of the different testing methods, starting with ‘Unit Testing`. The purpose of a unit test is to make sure some functionality or process works as expected, we will usually have input, then the process or function followed by output or some expected result. Unit testing is the base of any testing process because it is testing a single function withing the larger project and here we able to verify that all the small processes are working as expected before we move on to test larger amounts of code. The code below on the left shows us a toy example of a function that sums two integers. The code on the right is how we can test this functionality, even though this is a toy example the process will work for larger and more complex functions.
The great thing with unit tests is that these are incredibly easy to add to a CI/CD pipeline so every time there are code changes, unit tests can automatically run and verify that we are getting the expected results. This allows the developer or tester to get quick feedback without having to manually run code or setting up test environments just to test a single code change for example, saving resources such as time and even money. Unit test are quick and effortless to automate compared with the rest of the testing methods, for example the command `go test ./…’ can be added to the CI/CD configurating to run all of the unit tests in a Golang project, most popular programming languages have similar testing functionality.
As we move up the testing triangle, we start to test an increasingly larger amount of the code base. The unit test will test for some single functionality in the code whereas ‘Component Testing` will test a larger amount of code that usually involves a dedicated ‘test case’ such as logging onto a website. The `login` test case can use many different processes/functions such as verifying that a valid email and password has been used, and then verify that that the email used it unique to the website and then lastly the website will open the webpage to a certain page. Using unit tests in this case is not enough because we have many processes interaction with another and not a single defined process/function.
To test this we can use something like the robot testing framework, this framework is not language dependant as it runs outside of the code base. A tester will define a test case for Robots Framework to run and validate what the expected result of the action should be. In the login example shown on the Robot Framework website they have defined a simple test case as shown below. The test case is very simple to read and doesn’t use any fancy or special syntax, most non-technical people could also look at this and have some understanding of what is happening.
This way of automating component testing adds big value to the development process as you can now verify that code changes on one component have not affected another component indirectly, these types of issues are usually only discovered with manual or end-to-end testing. Automatic component testing can save time and other resources, as this is now an automatic process built into the pipeline. Lastly by using automated component testing there is proof that components work together as expected, this can be documented and referred to.
The final automated testing topic I want to discuss is, Integration testing. This is a test to see how well different code packages interact or interface together, therefore sometimes Integration Testing is also referred to as Interface Testing. We are testing to make sure that the different code packages can interface with each other, there needs to be assurance that data sent to the other package is expected, and that data received is what is needed/expected. The different packages could be written by other developers, teams or even companies and so it can be a difficult process to test, therefore, tools such as the Pact are used to aid developers/testers.
Source: docs.pact.io
Pact testing is a useful tool way to test HTTP and message integrations. When sending data via HTTP (Hypertext Transfer Protocol) the interfaces are not strictly defined, this means that if I for example performed a HTTP request to get todays weather, I wouldn’t know what data to expect unless I looked at the weather package and sometimes this could be private, so I have no way of knowing. Pact testing is useful because we can provide and consume ‘contracts’ with HTTP services, we are able to test using this contract that our request is what the HTTP client is expecting as well as testing to make sure that the HTTP client or ‘provider’ returns the expected response.
We can then add Pact/Integration testing to our CI/CD pipeline and automate this testing, so now when we add or change code, we have the automatic unit tests testing specific functionality, component testing to test the larger processes and then Pact tests to ensure that we fulfil the contract of other packages or HTTP clients/endpoints. This greatly improves testing and removes the need for a tester to manually test the interfaces between different packages, saving time.
The testing methods discussed are not the only testing methods as seen from the Testing Triangle, these have just been tests that are able to be automated well and built into a testing pipeline. Unit testing is the simplest method of testing, and it is very close to the code, the tests directly interact with the functionality of the code. This can then be automated using built in tools from most modern languages, in the case of Golang we only need to add the command `go test ./…`. Moving up the Testing Triangle we have gone over what component testing is and how it can be automated using tools such as Robot Framework. The focus being on testing multiple components of code at the same time and making sure they produce the expected outcome. Lastly, we covered Integration Testing with special attention to the tool, Pact, and explained how the Pact test can be used to validate and test HTTP interfaces.
If you’d like to learn more about the tools discussed today, then please follow these links: