In this episode of technical Thursday we look at the concepts of dependency injection and inversion of control. You will learn how to make your life as an automation engineer simpler by using Autofac. This manages your dependencies so that you don’t have to worry on how your solution should be tied up to work correctly! Stay tuned!
Inversion of control/dependency injection can help you to simplify the use of services, page object and much more. Before we get started, we need to be familiar with the concept of dependency injection. Dependency injection or DI is a way to create loosely coupled code. Tight coupling is when your inner modules highly depend on one another to work. In other words, you do not follow the object-oriented principles of single-responsibility and separation of concerns. One way to achieve loosely coupled code is the use of interfaces instead of concrete classes.
But what is a dependency?
A dependency is an object that your class/module needs in order to work. Therefore, we inject those dependencies by its constructor or methods. We do not want the instantiation inside the class but outside of it. This makes it easier to maintain, simpler and easier to test. An example of dependency injection in a test automation solution looks like this (click on the images to see them in full size):
→ Which would result to the following code in your tests →
Now imagine this doing in ALL your tests where there are big flows with a lot of page objects and other components. Or if you have an additional dependency, and you would need to inject that additional dependency in all your page objects.
Inversion of control or IoC
To have more control about your objects and how your objects are created. We need to shift the responsibility of creation to the architecture and not the developer. This leads to inversion of control or IoC. Like dependency injection, inversion of control, is a design pattern to manipulate object control. This allows the code you write to be loosely coupled and even easier to maintain. The great part of this, is that the architecture itself will be responsible for this. In the following example we use Autofac as our IoC system, but you can use any other system.
Basically, what we do there is to register our objects in a container. This can be done for your services like logging modules, database modules, reporting modules and so on. As soon as you need them, you will need to resolve them, but you must not worry anymore about injecting the right dependencies. Because the software architecture handles this for you! (click on the images to see them in full size)
→ It‘s now much simpler to use the MenuBar page object without injecting the Dependencies ourselves. →
Adding an additional service using a MenuBar object
Let us say we now want to add an additional service to handle rest requests and we need to use this in our MenuBar object, we can see a huge difference. If we do it in the traditional manner, we will have to modify every reference to include the service. However, if we use an IoC system we can just modify the constructor and we are done.
If we look at after picture (click to enlarge), you will see that IoC makes life much easier:
This was in a nutshell the benefits of using dependency injection and how to step it up even further using inversion of control. Of course, there is still a lot to be said about these things especially about using advanced features of an IoC systems like AutoFac, but I hope this triggers you to find out more on this. If you are interested in knowing more about this topic, please feel free to contact us. Our team of test professionals is always eager to take your testing to the next level.
Written by Laurens Putseys.