Here I will present to you the second version of the Failed Tests Analysis engine part of the Design Patterns in Au﻿tomated Testing Series. The first version of the engine utilized the Chain of Responsibility Design Pattern however it has some drawbacks that I will mention in this publication. I decided that we need more easy to use solution so I developed the second version of the engine using the Ambient Context Design Pattern.

Definition

Definition Provide a place to store scope or context related information or functionality that automatically follows the flow of execution between execution scopes or domains.

UML Class Diagram

Participants The classes and objects participating in the Ambient Design Pattern are: ​TestExceptionsAnalyzerContext - the main class that do most of the work. It holds a static reference to the scope stack where the chain of handlers is kept. It contains a method for adding new handlers in front of the chain. It implements the IDisposable interface so that it can be used through using statements. For usability purposes, the classes are create as a generic type where you can specify the type of the handler that needs to be added. There are successors of this class where you can specify more than one generic type.

- the main class that do most of the work. It holds a static reference to the scope stack where the chain of handlers is kept. It contains a method for adding new handlers in front of the chain. It implements the interface so that it can be used through using statements. For usability purposes, the classes are create as a generic type where you can specify the type of the handler that needs to be added. There are successors of this class where you can specify more than one generic type. Handler - defines an interface for handling requests. Contains the HandlerRequest method.

- defines an interface for handling requests. Contains the method. ConcreteHandler - holds the actual logic for handling a request. It has access to its successor. If it cannot manage the request itself, passes the execution to its successor. What Are the Problems That We Try to Solve? The previous solution described in the previous article Failed Tests Аnalysis- Chain of Responsibility Design Pattern was fairly good. However, if you need to specify multiple custom test-case-specific handlers, you need to call multiple methods in the right order. So I believed that the usability of the API could be improved. I thought that it might be a good idea to use the built-in goodies of the C# language such as the using statements. Through them, the readability of the code is slightly improved. The reader can find almost immediately the different handlers' scopes. Ambient Context Design Pattern for Failed Tests Analysis TestsExceptionsAnalyzerContext

The TestsExceptionsAnalyzerContext is the class where all of the magic is happening. As previously mentioned, here you can find a static stack variable that holds the chain of handlers. When you create the class with new generic type, it will add a new instance of it in front of the chain because the stack is a LIFO (last-in first-out) collection. We use Unity IoC container to get the primary handler of the application though an instance name- "MAIN_APP_HANDLER". When a new handler is moved on top of the stack, it is registered as the new main handler. Once the Dispose method of the IDisposable interface is called the new main app handler is the successor of the current primary handler. This way once you leave the using statement's scope the created custom handler is no more valid. ExceptionAnalyzerConstants

Though this class we can reuse the name of the primary handler registered in Unity. TestsExceptionsAnalyzerContext<THandler1, THandler2>

As I mentioned earlier, there are successors of the TestsExceptionsAnalyzerContext base class. This particular class adds two handlers to the static stack. The order depends on order of the specified generic types. TestsExceptionsAnalyzerContext<THandler1, THandler2, THandler3>

You can add even three handlers using a single TestsExceptionsAnalyzerContext. ExceptionAnalyzer

If you are not a fan of the curly brackets and using statements, this class is specially designed for you. This is a helper wrapper around the TestsExceptionsAnalyzerContext where you can specify a handler and a custom action. The specified handler will be valid only for the code of the anonymous action. I prefer the pure using statements approach.

While ago when we were working on the first version of the BELLATRIX test automation framework, I did this research while I was working on a similar feature for our solution.

Ambient Context Design Pattern in Tests ExceptionAnalizedElementFinderService

The only difference compared to the previous solution here is how we get the main app handler. Instead of passing it as a parameter, this time, we resolve it through the named instance.

ExecutionEngineBehaviorObserver

The above code should be added to the ExecutionEngineBehaviourObser so that the primary chain of handlers to be initialized correctly. The handlers that are specified here won't be modified by the ambient context. LoginProductSiteTests