Criteria catalogue for the best possible choice of test automation tools

In the first part of this blog series, we outlined the challenges that arise when selecting the right tool for test automation. The second part was about the relevance and possible classification of tool selection criteria, some of which can be standardised, but some of which need to be variable. In this third article we will look at the list of criteria, the criteria catalogue, how it was validated and the results of this validation.

Symbolbild: aufgeschlagenes Buch
Designed by Freepik

List of criteria

The following figure shows the final list of selection criteria. The variable criteria have been marked as “SuT criteria” (software under test). The criteria identified can be modified, supplemented and updated.

table showing list of criteria
Figure 1: List of criteria

The standard criteria are divided into fourteen (14) main criteria, including compatibility, operability, performance and documentation. Sub-criteria are assigned to the main criteria. For example, the main criterion “documentation” has three (3) sub-criteria.

Criteria catalogue

Once the criteria had been established, the next step was to create the actual criteria catalogue. Since there are different, multi-dimensional goals involved in making decisions, it is advisable to take a systematic approach. This requires multi-criteria decision analysis (MCDA). Utility value analysis is one method of multi-criteria decision analysis (Gansen 2020, p. 5). Utility value analysis can be applied whenever an evaluation is being carried out or an assessment is being made, e.g. in project management or controlling.

table showing sample for utility value analysis
Figure 2: Sample table showing a utility value analysis

Requirements for the criteria catalogue

Before actually compiling the criteria catalogue, we started by defining its requirements. These are summarised in the table below in the form of user stories and outline all the work steps required.

Nr.User Stories
1As a user, I would like to be able to enter project master data in order to better understand by whom, when and for which project the catalogue was created.
2As a user, I would like to compile a new catalogue in order to perform a utility value analysis.
3As a user, I would like to perform a utility value analysis in order to make an objective decision.
4As a user, I would like to apply fair and moderate weighting to the criteria in order to better control their relevance to the project.
5As a user, I would like an overview of the basis for evaluation in order to better assess alternative solutions.
6As a user, I would like a clear overview of the utility value analysis performed in order to quickly identify the most useful tool.
7As a user, I would like to access to the most recently edited utility value analysis in order to make further edits.
8As a user, I would like to be able to export the catalogue in order to share it.
Table 1: Requirements for the criteria catalogue

Structure of the criteria catalogue

The criteria catalogue was developed using Excel as well as Visual Basic for Applications (VBA). The developed tool was divided into different workbooks, each reflecting a specific task.

The starting screen

When you open the file, a dialogue window appears (see figure 3). You first have to choose whether to open the most recently edited catalogue or to create a new catalogue. If you want to create a new catalogue, a form is displayed which has to be filled in. SuT criteria entries are added to the catalogue as variable criteria (see figure 4).

starting screen
Figure 3: Starting screen of the criteria catalogue
screenshot SuT criteria

Figure 4: SuT criteria entries in the catalogue

Utility value analysis

A utility value analysis is performed in four steps. Once the criteria have been identified, they are weighted. Then fulfilment of the criteria is measured and finally the utility value is calculated for each alternative (Gansen 2020, p. 6). Once the evaluation criteria have been properly assessed, an objective, rational decision can be made with the help of the utility value analysis (Kühnapfel 2014, p. 4).

Weighting the criteria

Once the criteria, especially the variable criteria, have been established, these criteria need to be weighted. It is crucial to weight the criteria according to their importance for the specific test automation project in order for them to make the best possible contribution towards the achievement of the project’s goals. The sum of the weightings for standard criteria and variable criteria should always add up to 100%. For the standard criteria, the main criteria are weighted first using the pairwise comparison method in the form of a matrix and are compared with each other in pairs (Wartzack 2021, p. 315).

comparison of main criteria for a sample project

Figure 5: Pairwise comparison of main criteria for a sample project

Main criteria: security, installation effort, language support

The importance of each sub-criterion is then determined using an ordinal scale from zero to two:

0 = “unwichtig”; 1 = “teilweise wichtig”; 2 = “wichtig”

The points awarded are added up and multiplied by the corresponding weighting of the main criterion. This produces a proportional weighting for all standard criteria. The same procedure is applied to the other main criteria and sub-criteria. In the end, the sum of all weightings for the standard criteria equals 100%.

Measuring the fulfilment of criteria

The starting point is to answer the following question: “To what extent is the criterion fulfilled by the test automation tools being assessed?”. A 5-step model is used to determine the degree of criteria fulfilment, as shown in figure 7 (Gansen 2020, p. 17).

0Not fulfilled.
1Insufficiently fulfilled.
2Partially fulfilled.
3Fulfilled to a satisfactory extent.
4Well / completely fulfilled.
Table 2: Evaluation scheme for criteria fulfilment

If a score of 4 is given, the tool completely fulfils a criterion. If it does not fulfil the criterion, a score of 0 is given. This method converts the relevant properties of a test automation tool into a measurable quantity.

Evaluation consolidation

Once the degree of fulfilment has been established for each criterion, the utility value can be calculated. The following formula is used to determine the utility value:

N i = utility values of the alternative i

Gj = weighting of the criterion j

nij = partial value of the alternative i with respect to the criterion j

The partial values are added up. The result represents the actual value of a tool. The alternatives being considered can then be ranked according to the calculated utility values and this can subsequently be used for decision-making (Gansen 2020, p. 6). The tool solution that best meets all requirements and has the highest utility value can be selected.

Certain criteria can be identified as essential. These are called knock-out criteria (K.O. criteria). If a knock-out criterion (K.O. criterion) is not fulfilled (0), this is deemed a “breach”, which leads to the immediate exclusion of the alternative solution.

screenshot evaluation selection
Figure 6: Evaluation and selection

Navigation bar and export

The navigation bar provides the user with an overview of the catalogue’s structure and allows them to navigate through it effortlessly.

screenshot navigation bar
Figure 7: Navigation bar of the criteria catalogue

The catalogue can be exported as a PDF or Excel file and saved in any location.

screenshot template criteria catalogue
Figure 8: Excerpt of the blank template for the criteria catalogue

Results of the criteria catalogue validation

The following insights were gained from the validation:

  • The target model for identifying variable criteria was useful for collecting together ideas for the SuT criteria.
  • The use of pairwise comparison helped to identify the important factors and main criteria. The matrix made it possible to make comparisons. This resulted in a significant reduction in “gut decisions”.
  • The criteria catalogue offered a systematic, understandable and transparent method for recommending a suitable tool. It was also possible to determine the strengths of the recommended test automation framework. This verified the framework’s coverage of selection criteria with higher relevance. This reduces the need for discussions within the team that would delay the final decision.
  • The 5-step model used for evaluation required very in-depth knowledge of test automation tools, which is usually lacking. This would result in staff evaluating some of the criteria based on their own feelings and perceptions. Consequently, the evaluations would be partially subjective and the selected alternative would ultimately not be the optimal one. In order to obtain a more reliable result in this scenario, at least one other person with testing expertise should be involved in the evaluation.

Conclusion & outlook

In this work, we have examined a structured and systematic approach to the selection process. This can be used to select a suitable GUI test automation tool that meets the requirements of both the project and the company. A corresponding criteria catalogue was developed, which primarily provides transparency and comprehensibility in the decision-making process.

We intend to use the criteria catalogue in other projects. The experience gained during this process will be incorporated into the next version of the criteria catalogue (version 2.0).

This article was technically supported by:

Kay Grebenstein

Kay Grebenstein works as a tester and agile QA coach for ZEISS Digital Innovation, Dresden. Over the last few years, he has ensured quality and tested software in projects in various specialist domains (telecommunications, industry, mail order, energy, …). He shares his experiences at conferences, meetups and in publications of various kinds.

Alle Beiträge des Autors anzeigen

Tester Teatime (Part 3): Documentation in software projects – eternally unloved

The article series “Tester Tea-Time” covers topics and issues that our testers face every day and that are, above all, recurring. We should like to use these articles to explain such phenomena, to find solutions and to encourage discussions and new mindsets. In testing, we can learn a lot from each other by observing our behaviour in our daily lives!

Moderator: Welcome to Tester Teatime! In the interviews with testers of ZEISS Digital Innovation (ZDI), we regularly address interesting topics. Today, we shall be dealing with the issue of documentation in day-to-day project work. Our guest is Sandra Wolf (SW), tester at ZDI.

Sandra, why do you call documentation “eternally unloved”?

SW: The daily work of a tester is often stressful, and we often work under high pressure. We make the experience that for some tasks little or no time remains. Among others, this applies to documentation. It is readily forgotten or postponed – hence the attribute “eternally unloved”. This is due, among other things, to the fact that proper documentation is time-consuming. Time is precious. In modern society, it is usually dedicated to the most critical tasks of the daily work routine. Today, we shall look into the effects of good documentation on the daily work of the testers and why we should change our mindset regarding the importance of documentation. Because one thing is certain: It deserves to be firmly established in our life as testers.

Zwei Personen im Interview
Image: Max Wielsch and Sandra Wolf during the interview at the Tester Teatime.

Moderator: Where in the day-to-day project work do testers encounter the topic of documentation?

SW: In our daily work, each tester is confronted with the need to document test results or deviations. To this end, it is important, among other things, to collect all information other team members may need. But how about documentation for the purpose of knowledge transfer? In particular, it can be very important to document tips and technical know-how concerning software, especially if it is very complex. Of course, scope and design depend on the specific project. Is any there documentation available from conception or the customer? This may be used as a starting point. If not, all team members should have the ambition to develop such a documentation step by step. Many will now think that this is way too much effort. That there is no time for this during the daily routine. We testers should now stop and consider the positive effects of a well-made documentation on our day-to-day project work and on the daily routines of our colleagues.

Moderator: What exactly are the positive effects of an adequate documentation?

SW: Documentation is a prerequisite for knowledge management, i.e. for the development, exchange and preservation of knowledge. If knowledge management is well-organised, arising questions are usually first researched in the documentation. This saves meetings, calls and time. A great amount of relevant information is available from one central source – forming the basis that permits colleagues to work independently. This eliminates for example recurring questions from team members, and it makes the on-boarding of new colleagues a lot easier. Such a knowledge base can also support the testing of certain complex application areas by documenting specific tests or by providing technical background knowledge. Researching these requirements and tips can also speed up the actual testing.

All examples described save time that we think we don’t have to document something. Of course, it takes a high initial effort to build up such a knowledge base, but the yield is a valuable tool that saves time in the long run and that increases the efficiency of your day-to-day work and the testing process.

Moderator: Does this mean that investing into documentation time always pays off for the project?

SW: Yes, on the whole, I believe that investing into the time and resources necessary to develop a knowledge base pays off. The return of this investment is again time which is always short in your daily work. The time saved can be dedicated to other tasks. Well-organised knowledge management is a prerequisite any project if you wish to improve efficiency.

Moderator: How can knowledge management be introduced to or implemented into the project? On this issue, we ask Max Wielsch (MW), developer at ZDI. Max, what can you tell us about this issue?

MW: In my project, a very comprehensive wiki documentation in Confluence is used. It is amended by code-based documentation that is integrated into the wiki. I have created this knowledge base together with my team. We already used documentation in the past, however, this was restricted to two Word files, and the sources of knowledge were no longer available at that time. Since we support a very complex platform comprising several micro-services – mostly on the technical side – it was clear to us that a comprehensive documentation will yield a decisive value-added.

Moderator: How exactly did you master this tremendous task? Can you give other colleagues some tips along the way?

MW: My objective was to structure the existing chaos. Of course, creating a well-made documentation is a job that’s never done. Throughout all stages of the process, documentation requires continuous and adequate maintenance to ensure correct knowledge transfer. I started off by obtaining an overview and then decided to use arc42 as a structure template for the wiki. The tool was then adjusted to our project. Since the structure of our system is highly complex, our documentation is structured accordingly. Individual modules or elements may in turn have a new sub-structure. Also, we have different types of documentation areas: The documentation of the architecture containing a technical as well as a functional documentation, and the operating documentation. These areas are all located in the wiki. Related topics are linked to facilitate knowledge exchange and development. All these pages for example explain processes and contain references to technical descriptions in glossary entries or explain the configurations of a module. We also implement specific filters of the issue tracker (Jira) to make relevant bugs or upcoming stories easily visible. Context is simply everything!

Moderator: That sounds elaborate but also interesting. Did the implementation of such a documentation yield any benefit for you?

MW: For sure! We already gain time by being able to refer questions from technical departments, operations or other stakeholders to the corresponding pages. In addition, the documentation structure is the perfect tool for handing over new software versions to operations. We use, for example, special fields in our stories and bugs that we can list in tables in specific release wiki pages. We can present various aspects of the change. On the one hand, we have release notes for the communication to the stakeholders, on the other hand, we us so-called “ops notes”. These allow us to provide targeted information about operating a new function. Of course, they include corresponding links to pages of the operating documentation. As you can see, documentation is used throughout the entire process, from planning to operations. Eventually, we can always provide proof of having handed over changes to the software version completely and that operations have been provided with everything they need to know.

Moderator: Wow, this is a really good example of the benefits documentation can yield in a project. Do you also see any drawbacks that should be considered?

MW: Yes, of course, as always. Complex documentation requires maintenance and care. It must be kept up to date. Outdated, obsolete information must be removed. Also, it is not always easy to adhere to the document structures. Maintaining the content requires the exactly right level of detail to be identified so that only the information actually necessary is provided and that anything dispensable is removed. A cost-benefit analysis is always mandatory, and it greatly depends on the context of the project. With regard to adherence to structure: Actually, the entire team is responsible for the documentation. However, as is often the case, you sometimes need a person in charge to supervise, check and make adjustments. This can be particularly helpful for large projects or wherever a great number of developers is involved to make sure that the documentation follows a straight line. Once all developers have internalised the documentation’s principles and apply them correctly, less control may be exercised. However, this depends greatly on the project, i.e. the team’s structure, capabilities and areas of expertise.

Moderator: This is a good closing statement. Thank you, Sandra and Max, for sharing your insights. In short, we see that a good documentation can pay off for the project, and that the decision for its structure depends on the project’s framework conditions. This unloved topic deserves more attention as it has the potential to save time in the long run and to make team work more efficient. As defined in standard ISO 24765, documentation is an intrinsic aspect of product quality and therefore, underlining its importance, of the quality of the software as well.

In the following articles, we will address other issues from the daily lives of testers and discuss possible solutions for these.

Communication between C# and C++ – A guide

If you need your application written in C# to communicate with a C++ application, perhaps to read sensor data from a hardware component, then you have several options to choose from regarding this communication. This article will look at integration as a COM server. The following will focus on a C++-based COM server from a C# client.

Symbolic image: two hands on a tablet

Requirements

To follow this tutorial, you will need the following:

  • Visual Studio 2019 or a newer version
  • Visual Studio profile .NET desktop development
  • Visual Studio profile desktop development with C++

The profiles can be selected and installed via the Visual Studio installer.

Step-by-step instructions: Integrating a C++ COM server with a C# client

Important: More detailed information can be found in this Github repository.

We will also create a C++ server:

Step 1: Create a C++ ATL project with executable file (.exe) as application type.

Step 2: Please delete the ComServerPS project.

Step 3: Right click on the server and add a new class (ComServerMgr). This should result in the image below:

Screenshot COM server
Figure 1: Adding a new class (ComServerMgr)

Step 4: Add the AddOne() method header in the ComServerMgr.h so that it can be inserted into the class:

public:
	CComServerMgr()
	{
	}

DECLARE_REGISTRY_RESOURCEID(106)


BEGIN_COM_MAP(CComServerMgr)
	COM_INTERFACE_ENTRY(IComServerMgr)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

public:
	STDMETHOD(AddOne)(int value, int* result);


};

OBJECT_ENTRY_AUTO(__uuidof(ComServerMgr), CComServerMgr)

Step 5: Add the AddMethod() in the ComServerMgr.cpp. We will use those later to increment the given value by one:

STDMETHODIMP CComServerMgr::AddOne(int value, int* result)
{
	int res = value + 1;
	if (result != nullptr)
	{
		*result = res;
		return S_OK;
	}

	return S_OK;
}

Step 6: Add the AddMethod() in ComServer.idl as well to make it known:

Screenshot COM server
Figure 2: AddMethod() in ComServer.idl

Step 7: Build the project. Now go to the directory on the hard disk where the source code is located and select the subdirectory Build. ComServer.exe should now be located there. Now open the command prompt as administrator and enter the following command:

ComServer.exe /Regserver

Please note that ComServer is the name of the project. If, for example, the project is called “HelloWorld”, then the command should read: “HelloWorld.exe /Regserver”.

Now we will create the C# client.

The process is simpler than that for the COM server:

Step 1: Create a console application.

Step 2: Add the COM reference.

Screenshot COM server
Figure 3: Adding the COM reference

Step 3: Scroll down until the ComServerLib reference is visible:

Screenshot COM server
Figure 4: ComServerLib reference

Please note that the reference is called ComServerLib because the server project is called ComServer. If, for example, the project is called “HelloWorld”, the reference would be HelloWorldLib.

Step 4: Add the following code that instantiates the COM server when the console application is started and then passes the number 3.

    class Program
    {
        static void Main(string[] args)
        {
            IComServerMgr mgr = new ComServerMgr();
            var x = mgr.AddOne(3);

            Console.WriteLine("Hello World!");
        }
    }

Step 5: It is also possible to run the code in debug mode and with a breakpoint to make this easier to follow. The execution will then stop at the appropriate point.

Code snippet
Figure 5: Running the code in debug mode and with a breakpoint

Summary

Admittedly, the example was very simple, but it demonstrates how to establish a connection between COM servers and C# applications. This is very useful particularly prior to legacy applications, which unfortunately rarely come with any documentation explaining the procedure.

If you have any questions, please feel free to contact me at liviu.sosu@zeiss.com.
Thanks to Florian Seeleitner for his helpful support.

Selecting test automation tools – criteria and methods

The first article presented the general challenges and influencing factors that arise when selecting test automation tools, based on the results of various interviews. It showed that no standard method exists for selecting test automation tools, although there are some initial approaches involving checklists. The purpose of the thesis was therefore to find a simple, productive approach that would support the search for appropriate test automation tools on the basis of a criteria catalogue, taking account of the project application.

The basic requirement in the development of a criteria catalogue is to determine which criteria are actually relevant in the selection of a tool. I will look at this in the second part of the blog series.

Symbolbild: Junger Mann vor dem Bildschirm, zeigt mit dem Finger auf den Desktop und telefoniert

Relevance of the selection criteria

There is extensive discussion in the literature on suitable criteria for determining the quality of software products and, by extension, of test automation tools. The criteria identified for the criteria catalogue were largely developed on the basis of literature research. The sources used are presented briefly below:

The ISO 25010 list of software quality characteristics provides a useful checklist when deciding whether or not to test each criterion. Similar lists of quality characteristics can be found elsewhere (Spillner/Linz 2019, p. 27). In each case, the authors provide guidance that can be used to determine whether the individual quality characteristics have been fulfilled for a project. In the field of test automation, there are lists of criteria in Baumgartner et al. 2021, Lemke/Röttger 2021, Knott 2016 and others. These criteria relate to such factors as the supported technologies, options for test case description and modularisation, target group, integration into the tool landscape and costs. However, the objective here is simply to identify relevant criteria, not to evaluate them. There are additional criteria from the expert interviews and the analysis of the ZDI projects.

The selection criteria identified in this work therefore take findings and experience from existing papers on the subjects of quality, test automation and the creation and review of requirements for test automation tools, and combine them into one approach with practical relevance.

Figure 1: Sources of the criteria catalogue

Classification of criteria

In the selection of test automation tools, influencing factors such as experience, costs or interest groups were mentioned. For many, costs were the key factor. During the course of this work, it was found that criteria such as integration or compliance are defined differently depending on the role, but are included more or less as standard in the list of criteria. And they are unchangeable, regardless of the application undergoing testing. But there is a small proportion of criteria that vary depending on the application being tested. Here is a scenario to illustrate the problem: In the medical technology industry, a new, web-based application is being developed – the frontend with Angular 8 and NodeJS and the backend with Java Microservices. The test automation tool to be selected must primarily be appropriate for the framework conditions specified by the web application undergoing testing. Before an automation tool can be used, the interface technologies of the application must be examined. In practice, test automation tools have specific characteristics and are therefore used for different technologies. Some tend to specialise in web testing while others are more at home in desktop testing. Whether it’s a web application or mobile application, there are always certain expectations that apply to the test automation tool. This means the most critical factor is the test object or the system under test (SuT). This forms the basis for selecting the tool (Baumgartner et al. 2021, p. 45). In summary, the criteria can be classified in two types: the standard proportion and the variable proportion.

table showing the criteria of test automation tools
Figure 2: The two types of criteria

The standard criteria are not dependent on the test object. These criteria have been grouped into four categories based on the quality criteria: features, system, usability and provider-related criteria. By contrast, the variable criteria are dependent on the SuT. The variable criteria may include the supported application types, operating systems, interface technologies, browser and devices.

Variable selection strategy

Variable selection means selecting a number of variables to be included in the list of criteria. To support the selection of variable criteria, a target model with AND/OR decomposition based on GORE (Goal Oriented Requirements Engineering) and the work of Lapouchnian (2005) and Liaskos et al. (2010) was introduced during the course of my work. It had proven to be effective at recording exact alternatives or variabilities (Mylopoulos/Yu 1994, p. 159-168) so that alternative designs can be evaluated during the analysis process (Mylopoulos et al. 2001, p. 92-96). The targets and requirements are linked via AND/OR decomposition. The AND decomposition expresses that fulfilment of the relevant targets or requirements is required. An OR-link means that the fulfilment of one of these targets or requirements is sufficient. In this process, the initial expectations for the tool are formulated in explicit terms and irrelevant requirements are avoided.

Figure 3: Simplified target model for sample project XY 

Approach to tool selection

Based on the types of criteria identified (Spillner et al. 2011), this work designs a structured approach to selecting the appropriate test automation tool. The new approach can be divided into five stages:

  1. Develop the project requirements
  2. Identify the variable criteria using the AND/OR target model
  3. Weight the categories and criteria
  4. Evaluate the different tool solutions
  5. Evaluation and selection

The next blog article looks at how the criteria catalogue has been structured on the basis of the approach outlined above. We will also show how the variable criteria have been included in the catalogue and present the results of the validation of the criteria catalogue.

This article was technically supported by:

Kay Grebenstein

Kay Grebenstein works as a tester and agile QA coach for ZEISS Digital Innovation, Dresden. Over the last few years, he has ensured quality and tested software in projects in various specialist domains (telecommunications, industry, mail order, energy, …). He shares his experiences at conferences, meetups and in publications of various kinds.

Alle Beiträge des Autors anzeigen

Test automation in Angular web projects – What comes next after Protractor?

The King is dead, long live the King! But which king? After the Angular team announced in April that it would stop development of its Protractor e2e testing framework at the end of 2022, many developers have been asking themselves what will happen next. Which test automation tool should be used? The market has a wide range of alternatives, some of which will be discussed in this article.

Symbolic picture: A woman is sitting at a desk with a laptop, tablet and smartphone. The user interfaces show the same dashboards.

The test candidates

Cypress

Cypress is probably the best-known candidate in the test field. According to an Angular Community poll conducted in January 2021, it is the most widely used tool for automated UI testing, with over 60% of the votes. The first stable release was published back in 2017, and the application is currently on version 10. Cypress describes itself as fast, simple and reliable, relying on its own ecosystem of tools that, unlike Protractor, is independent of Selenium and WebDriver. Chrome, Firefox and Edge are currently supported, though not Safari (as yet). The possibility of running tests against various browser versions is offered by either connecting BrowserStack or by swapping the binaries for local execution.

ProContra
+ fast
+ stable
+ large community
+ thorough, easy-to-understand documentation
– still no support for Safari
Table 1: Pros and cons of the Cypress tool

Playwright

Developed by Microsoft since 2020, Playwright is the newest candidate in the field of automation tools. According to its own description, the library is up-to-date, fast, reliable and powerful, thus helping to eliminate common UI testing problems such as flakiness and slow execution speeds. With this aim in mind, it is not surprising that unlike the other testing tools, Playwright is not based on Selenium WebDriver and instead has its own implementation for browser control. The current browser engines from Chromium, Firefox and WebKit are supported on Windows, Linux and MacOS respectively. Older versions can be integrated using older versions of Playwright, and more recently, support has been added for generic Chromium builds (Edge and Chrome). Currently, support for mobile devices is only possible via the emulation of certain device configurations, such as resolution and user agent, and testing on real devices is not possible.

The feature set includes standard operations as well as functions that are missing in other frameworks or which can only be achieved using workarounds. Thus, in addition to clicks, scrolling, selections and so on, drag-and-drop, Shadow DOM interactions and synchronisation with animations are also available.

Im Hinblick auf Performance und Ausführungsgeschwindigkeit verhält sich Playwright wesentlich schneller als In terms of performance and execution speed, Playwright works much faster than Protractor and other Selenium-based testing frameworks. In our tests, we did not detect any problems in terms of flakiness or unexpected crashes, even with several test instances running in parallel. In conclusion, with Playwright, Microsoft provides a modern framework geared towards the requirements of modern UI testing. In its short time on the market, it has already won many advocates and will probably continue to grow in importance in the future.

ProContra
+ fast
+ stable
+ large feature set
– currently only offers limited support for BrowserStack
– no support for real mobile devices
Table 2: Pros and cons of the Playwright tool

Webdriver.io

It is now over seven years since Webdriver.io was first released, making it one of the longest-standing automation tools in the test field. The creators describe the design of their test framework as expandable, compatible and feature-rich, claims that stand up in the face of closer inspection:

Webdriver.io is a Selenium-based test framework that implements the W3C WebDriver API, which is based on it. This ensures compatibility with all modern browsers (and IE) that provide their own driver implementation. It also enables the testing of web apps on mobile devices, as well as native apps.

The further strengths of the framework become apparent in day-to-day use: A wealth of help methods and syntactic sugar makes formulating test steps and expectations much easier and more readable than was usually the case with Protractor. Some points of note include access to ShadowRoot components via shadow$, versatile configuration options (including automatic test repetitions in the event of errors) and the ability to wait for DOM elements to appear or disappear. However, if a function is not available, it can be implemented as a custom command and then used in the same way as the functions provided.

Despite all the praise, one fly in the ointment remains: Compared to other frameworks, test execution is quite slow due to the Selenium-based implementation, but execution can also be done in parallel.

ProContra
+ versatile compatibility
+ excellent documentation
+ numerous support methods and syntactic sugar
– test execution slower than in other frameworks
Table 3: Pros and cons of the Webdriver.io tool

TestCafé

TestCafé is one of the lesser-known candidates in the test field. In the aforementioned Angular community poll, it scored a usage percentage of less than 1%. The first stable release was published in 2018, and the application is currently in version 1.19. Two good reasons to take a closer look included the promise of an easy setup and its independence from WebDriver. Instead, TestCafé uses a rewritten URL proxy called Hammerhead that emulates commands via the DOM API and injects JavaScript into the browser.

All major browsers and the mobile versions of Chrome and Safari are currently supported. Of note is the ability to run tests on real mobile devices across the same network. It is also possible to run tests with BrowserStack. It should also be mentioned at this point that a dedicated development environment (TestCafé Studio) also exists, where you can create and record test cases with just a little programming knowledge.

ProContra
+ fast
+ versatile compatibility (including for mobile browsers and end devices)
+ large feature set
– low circulation
– test recorder tool is only available at a cost
Table 4: Pros and cons of the TestCafe tool

Comparison

When choosing a testing framework, it is firstly important to know your own project requirements. To this end, the following questions may prove useful:

  • Which browsers are to be supported?
  • Are different browser versions to be tested?
  • Is support required for mobile devices?
  • Can the app’s core functions be tested using the framework?

Die folgende Tabelle kann bei der Orientierung der Wahl eines TThe following table can help in selecting a testing framework.

CriterionCypressPlaywrightWebdriver.ioTestCafé
Browser support (and versions)o++ ++ +
Mobile support+ ++ + ++ +
Range of functions+ + ++ ++
Test speed+ + o+
Migration from Protractoroo+ +
Future-proof+ ++ + o
Table 5: Comparison of test tools based on various criteria

Summary

Given the very wide range of testing frameworks available, it is often tough to make the right decision. For projects with low test requirements, for example, testing against a few, exclusively current browsers, where fast test execution is an advantage, we recommend using Playwright.

However, when the project requires migration from Protractor and it is important to test against a wide range of browsers in different versions and on mobile devices, we recommend using Webdriver.io.

Sources

Dieser Beitrag wurde verfasst von:

Stefan Heinze

Since 2011, Stefan Heinze has worked in Dresden as a software developer at ZEISS Digital Innovation. He is currently working on Angular applications and Azure back-end development in the medical field. There is an increased focus on the automation of surface tests to ensure software quality.

Alle Beiträge des Autors anzeigen

Snapshot testing with Angular and Storybook

Storybook is a component-driven tool for creating visual style guides and demonstrating UI components from React, Angular and Vue, as well as web components.

In particular, snapshot testing provides an opportunity to detect and correct unexpected changes to style at an early stage.

Symbolic image: Female hands showing a focus frame gesture on a blue background

Snapshot testing in Storybook

Snapshot tests are a very useful tool if you want to ensure that there are no unexpected changes to your user interface.

A typical snapshot test case renders a UI component and creates a snapshot before comparing this to a reference snapshot file that has been saved alongside the test. If the two snapshots do not match, the test has failed: There has either been an unexpected change or the reference snapshot needs updating to match the new version of the UI component.

Storybook offers several ways to test an application, starting with Chromatic. However, this tool chain assumes that the source code has been versioned in GitHub and is subject to a monthly fee for professional use.

Another option is Storyshots, a streamlined addon that uses the Jest testing framework. It launches in the command line, where it lists instances where components have deviated from their previous state. The programmer must then check whether such changes were intentional or erroneous.

Installation for Angular

This guide assumes that Storybook has already been installed for the Angular application. A setup guide can be found at the following link. Angular comes with the Karma testing framework by default. To migrate the application to Jest, the following steps are required:

Installation of Jest dependencies

To install Jest, simply run the command “npm install jest jest-preset-angular –save-dev” in the command line.

Create Jest setup file

In the root directory of your Angular project, create the new typescript file setupJest.ts with the contents: import ‘jest-preset-angular’.

Adjust package.json

A script for the Jest testing framework must be added to the package.json of your Angular project:

{
 "jest": {
 "preset": "jest-preset-angular",
 "setupFilesAfterEnv": [
 "<rootDir>/setupJest.ts"
 },
}

Außerdem muss die Script-Ausführung für Test angepasst werden. Anstatt “test“: “ngtest“, muss “test“: “jest” In addition, the test script execution must be adapted. Instead of “test”: “ngtest”, “test”: “jest” must be used.

Removing Karma (optional)

Run the following command line to remove Karma:

npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine 
karma-jasmine-html-reporter

Next, the Karma.config.js and test.ts files in the <root>/src directory should be deleted and the section for testing must be removed from the angular.json.

Migrating from Jasmine (optional)

To migrate to Jest, certain adjustments must be made:

• Command line: npm uninstall @types/jasmine

• jasmine.createSpyObj(‘name’, [‘key’]) becomes jest.fn({key: jest.fn()})

• jasmine.createSpy(‘name’) becomes jest.fn()

• spyOn with returnValue() must be changed to jest.spyOn(…).mockReturnValue(…)

• spyOn with callFacke() must be changed to jest.spyOn(…).mockImplementation(…)

• Asymmetric matchers: jasmine.any, jasmine.objectContaining, etc. become expect.any, expect.objectContaining

Installing Storyshots dependencies

Storyshots is now being installed. To install Storyshots, the following two command lines should be run::

npm i -D @storybook/addon-storyshots
npm i -D @storybook/addon-storyshots-puppeteer puppeteer

After installation, the following dependencies should be available in the package.json (as at 12/11/2021; important for the installation workaround under Angular):

"jest": "^27.3.1",
"jest-preset-angular": "^10.0.1",
"@storybook/addon-storyshots": "^6.3.12"
"@storybook/addon-storyshots-puppeteer": "^6.3.12"

Creating Storyshots installation file

After installing Storyshots, the addon still needs to be configured. To do this, the Storyshots.test.js file must be created in the <root>/src directory with the contents:

import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
import path from 'path';

// Function to customize the snapshot location
const getMatchOptions = ({ context: { fileName } }) => {
 // Generates a custom path based on the file name and the custom directory.
 const snapshotPath = path.join(path.dirname(fileName), 'snapshot-images');
 return { customSnapshotsDir: snapshotPath };
};

initStoryshots({
 // your own configuration
 test: imageSnapshot({
 // invoke the function above here
 getMatchOptions,
 }),
});

Expanding tsconfig.json for Storyshots

Moreover, the tsconfig.json must also be adapted. To do so, the compilerOptions section in tsconfig.json must be expanded as follows:

"compilerOptions": { 
 "esModuleInterop": true,

Expanding package.json for Storyshots

Lastly, the section contained in the package.json must be reconfigured for Jest:

"jest": {
 "preset": "jest-preset-angular",
 "setupFilesAfterEnv": [
 "<rootDir>/setupJest.ts"
 ],
 "transformIgnorePatterns": [
 "<rootDir>/node_modules/(?!(@storybook/addon-docs))"
 ],
 "moduleNameMapper": {
 "jest-preset-angular/build/setup-jest": "jest-preset-angular/setup-jest",
 "jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer": "jest-presetangular/build/serializers/no-ng-attributes",
 "jest-preset-angular/build/AngularSnapshotSerializer": "jest-presetangular/build/serializers/ng-snapshot",
 "jest-preset-angular/build/HTMLCommentSerializer": "jest-presetangular/build/serializers/html-comment"
 }
},

These adjustments are specific to the selected version because the folder structure must be remapped in Jest. This may change again in later versions of Storyshots.

Testing components

There is a sample application for the test, which is composed of four individual components. The first component displays the time, including the date and day of the week. The second component shows a chart of the current weather in degrees, as well as the highest and lowest daily temperatures. Another component displays tram departures, using Dresden Striesen as an example. There is one final component, which shows three share prices along with graphs and indicators.

Figure 1: Storybook for an application composed of four components

For example, the source code for the clock component appears as follows:

export default {
 title: 'WidgetMonitor/Clock',
 component: ClockComponent,
 timeIsRunning: false,
} as Meta;

export const Morning = () => {
 return({
 props: {
 timeIsRunning: false,
 time: new Date(2021, 10, 9, 9, 9, 9, 9)
 },
 parameter: {
 time: new Date(2021, 10, 9, 9, 9, 9, 9)
 }
 })
}

export const Afternoon = () => {
 return({
 props: {
 timeIsRunning: false,
 time: new Date(2021, 10, 9, 15, 15, 15, 15)
 }
 })
}

const Template: Story<ClockComponent> = (args: ClockComponent) => ({
 props: args
});

export const Running = Template.bind({});

Running.args = {
 timeIsRunning: true,
};

Running.parameters = {
 storyshots: { disable: true }
};

This includes three states, the first two of which are static points in time. The third state, “Running”, shows the current time, i.e. not static.

Prerequisite for snapshot tests in Storybook

It is important for us to have a static state under Storybook in order to test the application. The “Running” state is not static in the clock component example. This can be omitted by adding the parameter storyshots: { disable: true } (see source code above).

Start testing

Using the npm test command line, the test is launched in the command line of the Angular project directory. The initial snapshot test will now produce a snapshot image of each component state.

Figure 2: Start test in Storybook

To demonstrate an example of an error, the font used on the clock in the clock component has now been changed so that it is smaller and red in the SCSS, and the test has been restarted.

Figure 3: Show errors in Storybook

The result of the snapshot test shows that the two active states of the clock component have failed and a diff image is referenced. This appears as follows:

Figure 4: Result of the snapshot tests

The original state is visible on the left, and the state following the change can be seen on the right. In the middle, you can see how both states overlap. It is now possible to either apply this state or to re-run the test after the application has been adapted.

The npm test — -u command line is used to force-apply the state. This deletes the differential images and creates a new snapshot of the state of the component. The npm test command line should now run again with no errors.

Summary

For Storybook, maintaining a state invariably means that more effort is required in the project. Anyone who is not afraid of tackling this can use Jest and the Storyshots addon to check a specific state in a closed environment. This is particularly helpful for detecting styling bugs at an early stage, as these can be difficult to detect in unit and end-to-end tests and usually only become apparent during manual testing.

Video tutorial: How teams use the QA Navigation Board

The QA Navigation Board enables teams to make targeted and efficient decisions for every software project with regard to aspects of quality assurance, their order of priority and their implementation. We have created a short video tutorial to explain how it works.

Figure 1: QA Navigation Board for practical application

How the QA Navigation Board works

Every software project is characterised by its own individual focus. The resulting quality requirements are equally as specific. For this reason, suitable measures – according to each topic – must be established in order to test these quality requirements. With this in mind, we developed the QA Navigation Board to accurately evaluate the methods and plan the sequences in a meaningful way: The Board is an aid that enables teams to organise testing for software projects in the best possible way. The following questions are taken into account: What needs to be tested, how, to what extent, where and when?

Video Tutorial (German only)

An introduction to the tool is helpful, as it ensures that the Board can be used correctly and without delay. We have therefore explained how it works in a supporting video tutorial. How is it structured? In an ideal world, which test planning steps should be carried out in sequence and why? This enables the user to make the best possible start, step by step.

Experiences using the QA Navigation Board

The QA Navigation Board is already being used consistently and with great success across numerous projects. Teams that have used the Board say that: It is inclusive of every single member of the team and their respective skills. It ensures that no aspect of the software is overlooked and that quality assurance takes place in line with their objectives. Working with the QA Navigation Board therefore ensures clarity, gives a clear focus and allows for collaborative creation across the whole team in a workshop.

Introductory workshop

For teams that want to incorporate the Board into their processes, we are still offering a detailed schedule for running an introductory workshop for the QA Navigation Board. A detailed description of how to complete the Board as well as the meaning behind each individual point can be found and referred back to at any time here.

When it comes to recognising and eliminating typical QA problems and their effects, the Board can be used as a tool for the “case history of the QA strategy for agile teams” – a description of the procedure is available here.

Data science buzzwords and what they mean

A few years ago, Harvard Business Review named “data scientist” the “Sexiest Job of the 21st Century” [1] – not least because data-driven companies such as Google, Amazon and Facebook can generate enormous profits. Since then, modern companies have been working on their data infrastructures and terms such as machine learning, data science and data mining are on everyone’s lips. But what exactly do all these terms mean? What do they have in common, what differentiates them? And what does a data scientist actually do? Read on to find out.

Data scientist in front of monitor with graphs

Buzzwords

We’re going to start by attempting to clarify the meaning of some keywords. But this comes with a word of warning: as this is still an emerging field that is evolving at a rapid pace, many terms and concepts are still in a state of flux and are sometimes used in different ways. We are going to use the example of a fictitious global logistics company called “OrderNow” to illustrate the key terms.

Data science attempts to generate knowledge from data. The method employed by data scientists is comparable with that of natural scientists, who derive general findings from large volumes of measured data. To do this, they use various algorithms that are developed in an academic context and applied in an industrial environment.
An important example of this use of algorithms relates to the prediction of orders. OrderNow’s accounting records indicate which customers ordered what at what time and in what quantity. A data scientist’s algorithm analyses this order data statistically and can then predict when in the future there will be demand for which products and in what quantities. Equipped with this information, OrderNow can place orders with its suppliers in good time and then supply goods to its own customers more quickly.

Big data refers to volumes of data that are too large, too complex, too fast-moving or too unstructured to be evaluated with conventional manual methods of data processing.
In our example, this could refer to the constantly growing volumes of historical order data.

A data lake is a system of data stored in its raw format without a structure. More data is stored than is urgently required. In other words, a data lake is a big data repository.
OrderNow is made up of many subcontractors with their own established structures. The order data is sometimes in the form of Excel files and sometimes it is recorded as entries in SQL databases.

Machine learning algorithms learn – in a similar way to a human – to identify patterns in data on the basis of examples. Once the learning phase has been completed, these patterns can be identified in new data. This is also referred to as the artificial generation of knowledge from experience. The application of these algorithms often involves the use of neural networks.
In the case of OrderNow, this technology is used in the customer app. The user can take photos of objects, the app identifies which product it is and an order can be placed directly. To make this possible, a machine learning algorithm has processed countless categorised image files in order to learn what a particular product looks like and be able to recognise it in new images.

Deep learning is a specialmethod of machine learning which uses neural networks with numerous hidden layers.

Data mining is the attempt to find new interconnections and trends in large databases using statistical methods. As it involves a different approach, data mining is regarded as complementary to machine learning.
OrderNow uses data mining to recommend products to its customers.

What does a data scientist do?

Data science can be regarded as the umbrella term that encompasses the other keywords. A data scientist uses methods such as machine learning or data mining to generate knowledge from data.

Figure 1: Data scientists use knowledge and skills from the fields of computer science, mathematics and project management.

This requires various skills, as summarised in Figure 1. Data scientists often use the programming languages Python or R, understand databases and know how to process data efficiently. They have a good understanding of mathematics and statistics. The scientific part of their work comprises the process of generating knowledge and also involves them formulating the questions that are to be answered with the database. At the same time, data scientists must also be good at project management. They work in a team with experts from the world of data, they have to be able to communicate results effectively within the company and ultimately they help put their findings into practice in order to create added value.

Using data to create added value

What might this added value look like? Findings that contribute to management decisions on the one hand, optimisation of existing products on the other – in many cases, however, the actual goal is to develop new products. For this to succeed, software developers and data scientists need to work together. The future will reveal how well we manage to put this into practice.

References

[1] Davenport and Patil, Havard Business Review, October 2012

Smart Manufacturing at the office desk

factory out of lego bricks on a desk in an office
Figure 1: Overview of the learning factory in Görlitz

While more and more start-ups, mid-sized companies and large corporations are using digitalisation and networking to expand their business, and are developing entirely new business models, the global demand for standardisation and implementation expertise is growing. For example, real-life technologies have long been evolving from phrases that previously didn’t hold a lot of meaning, like “Big Data”, “Internet of Things (IoT)” and “Industry 4.0”; such technologies are driving digital transformation while helping companies to increase their productivity, optimise their supply chains and, ultimately, increase their gross profit margins. They primarily benefit from reusable services from hyperscalers such as Amazon, Microsoft, Google or IBM, but are themselves often unable to implement tailor-made solutions using their own staff. ZEISS Digital Innovation (ZDI) assists and supports its customers in their digital transformation as both a partner and development service provider.

Cloud solutions have long been clunky – especially in the industrial environment. This was due to widespread scepticism regarding data, IT and system security, as well as development and operating costs. In addition, connecting and upgrading a large number of heterogeneous existing systems required a great deal of imagination. For the most part, these basic questions have now been resolved and cloud providers are using specific IoT services to recruit new customers from the manufacturing industry.

In order to illustrate the typical opportunities and challenges borne by IoT environments in the most realistic way possible, an interdisciplinary ZDI team – consisting of competent experts from the areas of business analysis, software architecture, front-end and back-end development, DevOps engineering, test management and test automation – will use a proven agile process to develop a demonstrator that can be used at a later date to check the feasibility of customer-specific requirements.

A networked production environment is simulated in the demonstrator using a fischertechnik Learning Factory and is controlled using a cloud application developed by us. With its various sensors, kinematics, extraction technology and, in particular, a Siemens S7 control unit, the learning factory contains many of the typical elements that are also used in real industrial systems. Established standards such as OPC UA and MQTT are used to link the devices to an integrated IoT gateway, which in turn supplies the collected data via a standard interface to the cloud services that have been optimised for this purpose. Conversely, the gateway also allows controlled access to the production facilities from outside of the factory infrastructure while taking the strict IT and system security requirements into account.

part of the learning factory
Figure 2: Gripping arm with blue NFC workpiece

Establishing and securing connectivity for employees across all ZDI locations after commissioning has occurred is on one hand an organisational requirement, and on the other, already a core requirement for any practical IoT solution with profound effects for the overall architecture. In terms of technology, the team will initially focus on cloud services offered by Microsoft (Azure) and Amazon (AWS), contributing extensive experiences from challenging customer projects in the IoT environment. Furthermore, the focus remains on architecture and technology reviews as well as the implementation of the initial monitoring use cases. Using this as a foundation, more complex use cases for cycle time optimisation, machine efficiency, quality assurance or tracing (track and trace) are in the planning phase.

ZDI is also especially well positioned in the testing services field. Unlike in extremely software-heavy industries such as logistics or the financial sector, however, test managers for numerous production-related use cases were repeatedly confronted with the question of how hardware, software and, in particular, their interaction at the control level can be tested in full and automatically, without requiring valuable machine and system time. In hyper-complex production environments, such as those that ZEISS has come across in the semiconductor and automotive industries, digital twins, which are widely used otherwise, only provide a limited degree of mitigation as relationships are difficult to model and, occasionally, fully unknown influencing factors are involved. This makes it all the more important to design a suitable testing environment that can be used to narrow down errors, reproduce them and eliminate them in the most minimally invasive way possible.

We will use this blog to regularly report on the project’s progress and share our experiences.


YARP – A fast and reliable reverse proxy

Possibilities of the .NET-based open source solution from Microsoft

Routing, load balancing, authentication, authorisation and reliability are important issues in many web projects. Microsoft has a large number of teams that write a reverse proxy for their services themselves or look for solutions to map the tasks mentioned above. This was a good occasion to bring together the different requirements to work on a common solution. YARP was launched – the Microsoft open source project for a reverse proxy in .NET.

Microsoft released the first preview more than a year ago. Ever since, many improvements have been made and YARP has been released in version 1.0 together with the new .NET 6 on 9 November 2021.

In this article we aim to take a closer look at YARP and provide an overview of the configuration options provided to us by Microsoft. Accordingly, we will start by looking at what a reverse proxy actually is and how YARP is positioned. Then we will look at the diverse configuration options and conclude with an outlook.

YARP is written in C# and is built on .NET. It utilises the infrastructure of ASP.NET and .NET. Thus, .NET Core 3.1 and .NET 5 as well as the .NET 6 mentioned above are supported. However, when .NET Core 3.1 is used, some functions are not available, as YARP makes use of some new features and optimisations in the newer .NET versions.

keyboard with open source button

What is a reverse proxy?

A reverse proxy is a type of proxy server that is typically located behind the firewall in a private network and forwards client requests to back-end services. In doing so, the reverse proxy provides an additional abstraction and control layer to ensure the smooth flow of network traffic between clients and servers.

What is YARP?

A classic reverse proxy usually operates on the transport layer (4th layer – TCP/IP) of the ISO/OSI model and routes the requests further and further. In contrast, YARP resides on the 7th layer – here the http layer – and it cuts the incoming connections and creates new ones to the target server. The incoming and outgoing connections are thus independent. This enables remapping of the URL space, i.e. there is a difference between the URLs that are visible from outside and those in the back-end.

The back-end server can be relieved of load by shifting tasks to the reverse proxy.

Why YARP?

The utilisation options of YARP and the many other (classic) reverse proxies vary. A developer in the ASP.NET environment can easily set up, configure and extend the functionality of the reverse proxy in his or her usual programming language. Likewise, the reverse proxy with all its configurations can be versioned with version control, just like any other project. It also has cross-platform capability, i.e. it runs on both Windows and Linux, making it well suited for containerisation.

Functions of YARP

One of the most important requirements is the extensibility and customisability of YARP. For configuration, any source that maps the IConfiguration interface can be connected. Classically, this would be JSON configuration files. The configuration is automatically updated without a restart when changes are made. However, it is also possible to control the configuration dynamically via an API or even on demand per request.

Anatomy of a request

To better understand the functions, it is useful to first get an overview of the pipeline architecture of YARP. Initially, an incoming request lands in the standard ASP .NET middleware (e.g. TLS Termination, Static Files, Routing, Authentication and Authorisation). This is followed by various phases of YARP.

  1. Run through all target servers incl. health check
  2. Session affinity
  3. Load balancing
  4. Passive health checks
  5. Transformation of the request
  6. Forwarding of the request to the target server through a new connection

Routes and clusters

The reverse proxy can be configured for both routes and clusters. The route configuration is an ordered list of route hits with their associated configurations. A route is typically defined by three components: the route ID, cluster ID and a match criterion. Therefore, when an incoming connection arrives, it is compared with the match criterion. In the process, the list of route entries is processed one after the other. If the match criterion is met, the cluster with the specified ID is used for forwarding. However, CORS, transformer, authentication and authorisation can also be configured for a route.

Figure 1 shows an example configuration for routes and clusters.

Unlike the “Routes section, the Clusters section contains an unordered collection of named clusters. A cluster primarily contains a collection of named targets and their addresses, each of which is considered capable of handling requests for a particular route. The proxy processes the request according to the route and cluster configuration to select a target.

{
    "ReverseProxy": {
        "Routes": {
            "minimumroute": {
                "ClusterId": "minimumcluster",
                "Match": {
                    "Path": "{**catch-all}"
                }
            },
            "route2": {
                "ClusterId": "cluster2",
                "Match": {
                    "Path": "/something/{*any}"
                }
            }
        },
        "Clusters": {
            "minimumcluster": {
                "Destinations": {
                    "example.com": {
                        "Address": "http://www.example.com/"
                    }
                }
            },
            "cluster2": {
                "Destinations": {
                    "first_destination": {
                        "Address": "https://contoso.com"
                    },
                    "another_destination": {
                        "Address": "https://bing.com"
                    }
                },
                "LoadBalancingPolicy": "PowerOfTwoChoices"
            }
        }
    }
}

Figure 1: Example configuration with the basic functions (routes, clusters and load balancing)

TLS termination

As mentioned earlier, incoming connections are cut and new ones to the target server are established. Since TLS connections are expensive, this can improve speed for small requests. This can be useful especially if the proxy forwards to servers that are all on the internal network and a secure connection is no longer necessary. The following possibilities are conceivable here:

  • Routing of an incoming HTTPS to HTTP connection
  • Routing of an incoming HTTPS/1 to HTTP/2 connection
  • Routing of an incoming HTTP to HTTPS connection

Session affinity

Session affinity is a mechanism for binding (affinity) a contiguous request sequence to the target that handled the first request when the load is distributed over multiple targets.

It is useful in scenarios where most requests in a sequence deal with the same data and the cost of accessing data is different for different targets handling requests.

The most common example is transient caching (e.g. in-memory). Here, during the first request, data is retrieved from a slower persistent memory into a fast local cache. Subsequent requests can then be processed with the data from the cache, thus increasing throughput.

Load balancing

If multiple healthy targets are available for a route, one of the following load balancing algorithms can be configured:

  • Random
  • Round robin
  • Least requests
  • Power of two choices
  • First

It is also possible to use a self-developed algorithm at this point.

Health checks

The reverse proxy can analyse the health of each node and stop client traffic to unhealthy nodes until they recover. YARP implements this approach in the form of active and passive checks.

Passive

YARP can passively check for successes and failures in forwarding client requests. Responses to proxy requests are intercepted by dedicated passive health checking middleware, which forwards them to a policy configured on the cluster. The policy analyses the responses to determine whether or not the targets that generated them are healthy. It then computes new passive health states, assigns them to the respective targets and rebuilds the cluster’s collection of healthy targets.

Active

YARP can also actively monitor the health of the target servers. This is done by regularly sending requests to predefined state endpoints. This analysis is defined by an active health check policy set for a cluster. At the end, the policy is used to mark each target as healthy or unhealthy.

Unhealthy clusters are automatically blocked through the active and passive checks, and maintenance can be performed without adversely affecting the application.

Transformers

Transformers allow the proxy to modify parts of the request or response. This may be necessary, for example, to meet defined requirements of the target server. The original request object is not changed, only the proxy request. No analysis of the request body is done and no modification of the request and response body takes place. However, this can be achieved via additional middleware – if necessary. It is at this point, for example, where the API gateway Ocelot, which is also based on .NET, could show its strengths. It can perform conversions such as XML to JSON or merge several responses and is primarily aimed at .NET applications with a microservice or service-oriented architecture.

There are some transformers that are enabled by default. These include the protocol (X-Forwarded-Proto), the requested server (X-Forwarded-Host) and the origin IP (X-Forwarded-For).

Accordingly, the origin of the request is still known after the reverse proxy is routed in the back-end via the added header information – this is not the case with classic reverse proxies.

Authentication and authorisation

Authentication and authorisation are possible before forwarding. This allows consistent policies to be mapped across multiple services, eliminating the need to maintain the policies separately. In addition, it leads to a load reduction for the target systems. The authorisation policies are an ASP.NET Core concept. One policy is set per route and the rest is handled by the existing ASP.NET Core authentication and authorisation components.

The following procedures are supported by YARP:

  • Cookie, Bearer, API Keys
  • OAuth2, OpenIdConnect, WsFederation
  • Client certificates

Windows, Negotiate, NTLM and Kerberos authentication, on the other hand, are not supported, as these are usually bound to a specific connection.

Cross-Origin Resource Sharing – CORS

YARP can handle cross-origin requests before they are routed to the target server. This reduces the load on the target servers and ensures consistent policies.

Direct forwarding with IHttpForwarder

If the application does not require the full range of functions, just the IHttpForwarder can be used instead of the full feature set. It serves as a proxy adapter between incoming and outgoing connections.

In this case, the proxy takes over the creation of an HttpRequestMessage from an HttpContext, the sending and forwarding of the response.

The IHttpForwarder supports dynamic target selection, where one defines the target for each request.

Adjustments can be made to the request and response, where the body is excluded. And last but not least, the streaming protocols gRPC and WebSockets as well as error handling are supported.

This minimalistic version does not support routing, load balancing, session affinity and retries – but it does provide some performance benefits.

Outlook

For future releases, the team behind YARP is working on support for HTTP/3, Service Fabric, integration in Kubernetes and further performance improvements.

In addition, Microsoft is trying to develop LLHTTP (Low Level HTTP), an alternative to the current HttpClient, in order to have more control over how requests are made and processed. It is intended to be used especially in scenarios where performance is more important than ease of use. In YARP, it is to be used to gain more control over outgoing connections and for more efficient processing of headers.

Summary

The present article explained the basics of YARP and its extensive features. Using the knowledge gained and the multitude of good code examples in the YARP repository on GitHub, you can now assess whether the functionalities are sufficient for a given use case and create your own reverse proxy.

Since the toolkit is based on the ASP.NET Core stack, it can be run on any environment you have been using for your .NET Core projects.

With YARP, Microsoft delivers a fast and reliable next-generation reverse proxy that will be applied in many projects – not only those of Microsoft.