Reader small image

You're reading from  Software Architecture with C# 12 and .NET 8 - Fourth Edition

Product typeBook
Published inFeb 2024
PublisherPackt
ISBN-139781805127659
Edition4th Edition
Right arrow
Authors (2):
Gabriel Baptista
Gabriel Baptista
author image
Gabriel Baptista

Gabriel Baptista has been working with software development since the beginning of .NET. Today, his main contributions are managing numerous projects for retail and industry. He is an Azure Platform-as-a-Service (PaaS) solution specialist, teaches at Computing Engineering universities, and helps tech startups as a mentor.
Read more about Gabriel Baptista

Francesco Abbruzzese
Francesco Abbruzzese
author image
Francesco Abbruzzese

Francesco Abbruzzese dedicates his life to his two great passions: software and powerlifting. He is the author of the MVC Controls Toolkit and the Blazor Controls Toolkit libraries. He has contributed to the diffusion and evangelization of the Microsoft web stack since the first version of ASP.NET. His company, Mvcct Team, offers web applications, tools, and services for web technologies. He has moved from AI systems, where he implemented one of the first decision support systems for financial institutions, to top-10 video game titles such as Puma Street Soccer.
Read more about Francesco Abbruzzese

View More author details
Right arrow

Testing Your Enterprise Application

When developing software, it is essential to ensure that an application is as bug-free as possible and that it satisfies all requirements. This can be done by testing all the modules while they are being developed or when the overall application has been either completely or partially implemented. This need has become more and more compelling in today’s agile and DevOps-driven software development landscape, where integrating testing at every stage of the development process is essential for the continuous delivery of reliable software.

While most of the key concepts covered by this chapter apply to a wide range of applications and environments, this chapter focuses on essential testing strategies for enterprise-level applications in C# and .NET environments.

Performing all the tests manually is not a feasible option since most of the tests must be executed each time the application is modified, and, as explained throughout this...

Technical requirements

This chapter requires the Visual Studio 2022 free Community Edition or better, with all database tools installed. The code for this chapter is available at https://github.com/PacktPublishing/Software-Architecture-with-C-Sharp-12-and-.NET-8-4E.

Understanding unit and integration tests

Testing is an essential part of software development since it verifies both that the software is bug-free and that it conforms to the agreed specification. Delaying application testing until immediately after most of the application’s functionalities have been implemented in their entirety must be avoided for the following reasons:

  • If a class or module has been incorrectly designed or implemented, it might have already influenced the way other modules were implemented. Therefore, at this point, fixing the problem might have a very high cost.
  • The possible combination of input that is needed to test all possible paths that execution can take grows exponentially with the number of modules or classes that are tested together. Thus, for instance, if the execution of a class method A can take three different paths, while the execution of another method B can take four paths, then testing A and B together would require 3 x...

Understanding the basics of test-driven development

Test-driven development (TDD) is a software development methodology that gives a central role to unit tests. According to this methodology, unit tests are a formalization of the specifications of each class, so they must be written before the code of the class. Actually, a full test that covers all code paths univocally defines the code behavior, so it can be considered a specification for the code. It is not a formal specification that defines the code behavior through some formal language but a specification based on examples of behavior.

The ideal way to test software would be to write formal specifications of the whole software behavior and to verify with some wholly automatic tools whether the software that was actually produced conforms to them. In the past, some research effort was spent defining formal languages for describing code specifications, but expressing the behavior the developer has in mind with similar languages...

Functional tests

These tests use the same techniques and tools as unit and integration tests but differ from them in that they are run only at the end of each sprint. They have the fundamental role of verifying that the current version of the entire software complies with its specifications.

Since functional tests also involve the UI, they need further tools to simulate, somehow, how the user acts in the UI. The need for extra tools is not the only challenge the UI brings with it because UIs also see frequent and major changes. Thus, we mustn’t design tests that depend on the UI’s graphical details, or we might be forced to rewrite all the tests completely at each UI change. We will discuss both the tools and the best practices for optimizing UI tests in the Automating functional tests in C# section.

Anyway, it is worth pointing out that sometimes it is better to renounce automated testing for some UI-related features and fall back to manual tests because the...

Behavior-Driven Development (BDD)

BDD conforms to the rules of TDD we already described but focuses mainly on business value and client-side behavior.

We discussed that the strength of unit tests is as follows: “It is very unlikely that when describing a behavior in two completely different ways, that is, with code and with examples, we might make exactly the same errors, so errors are discovered with a probability that is close to 100%.”

BDD uses the same approach, but the examples used in TDD must not depend on the specific way the functionality might be implemented. That is, examples must be as close as possible to pure specifications. This way, we are sure tests can’t influence the way functionality is implemented and vice versa; we are not influenced by pure technical facilities or constraints when writing specifications but focus mainly on the user needs.

Moreover, tests should use a vocabulary that can be understood by stakeholders. For these...

Defining C# test projects in Visual Studio

The .NET SDK contains project templates for three types of unit testing frameworks: MSTest, xUnit, and NUnit. When starting the new project wizard in Visual Studio, if you want to see the compatible versions of these testing frameworks for .NET C# applications, set the Project type to Test, the Language to C#, and the Platform as Linux. This configuration will allow you to identify and select the appropriate versions of MSTest, xUnit, and NUnit for your project.

The following screenshot shows the selection that should appear:

Graphical user interface, text, application, email  Description automatically generated

Figure 9.2: Adding a test project

All the preceding projects automatically include the NuGet package for running all the tests in the Visual Studio test user interface (Visual Studio test runner). However, they do not include any facility for mocking interfaces, so you need to add the Moq NuGet package, which contains a popular mocking framework.

All these test projects must contain a reference to...

Automating functional tests in C#

Automated functional tests use the same test tools as unit and integration tests. That is, these tests can be embedded in the same xUnit, NUnit, or MSTest projects that we described in the previous section. However, in this case, we must add further tools that can interact with and inspect the UI.

In the remainder of this chapter, we will focus on web applications since they are the main focus of this book. Accordingly, if we are testing web APIs, we just need HttpClient instances since they can easily interact with web API endpoints in both XML and JSON.

In the case of applications that return HTML pages, the interaction is more complex since we also need tools for parsing and interacting with the HTML page DOM tree.

The Selenium toolset is a great solution since it has drivers for simulating user interaction in all mainstream browsers and for programmatically accessing the browser DOM.

There are two basic options for testing a web...

Summary

In this chapter, we explained why it is worth automating software tests, and then we focused on the importance of unit tests. We also listed the various types of tests and their main features, focusing mainly on unit tests and functional tests. We analyzed the advantages of TDD and how to use it in practice. With this knowledge, you should be able to produce software that is both reliable and easy to modify.

Then, this chapter analyzed when it is worth automating some or all functional tests and described how to automate them in ASP.NET Core applications.

Finally, we analyzed the main test tools available for .NET projects, focusing on xUnit, Moq, Microsoft.AspNetCore.Mvc.Testing, and Selenium, and showed how to use them in practice with the help of the book’s use case.

Chapter 21, Case Study, applies all the test concepts described in this chapter to the book’s case study.

Questions

  1. Why is it worth automating unit tests?
  2. What is the main reason why TDD is able to discover most bugs immediately?
  3. What is the difference between the [Theory] and [Fact] attributes of xUnit?
  4. Which xUnit static class is used in test assertions?
  5. Which methods allow the definition of the Moq mocked dependencies?
  6. Is it possible to mock async methods with Moq? If so, how?
  7. Is it always worth automating UI functional tests in the case of quick CI/CD cycles?
  8. What is the disadvantage of subcutaneous tests for ASP.NET Core applications?
  9. What is the suggested technique for writing code-driven ASP.NET Core functional tests?
  10. What is the suggested way of inspecting the HTML returned by a server?

Further reading

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Software Architecture with C# 12 and .NET 8 - Fourth Edition
Published in: Feb 2024Publisher: PacktISBN-13: 9781805127659
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Authors (2)

author image
Gabriel Baptista

Gabriel Baptista has been working with software development since the beginning of .NET. Today, his main contributions are managing numerous projects for retail and industry. He is an Azure Platform-as-a-Service (PaaS) solution specialist, teaches at Computing Engineering universities, and helps tech startups as a mentor.
Read more about Gabriel Baptista

author image
Francesco Abbruzzese

Francesco Abbruzzese dedicates his life to his two great passions: software and powerlifting. He is the author of the MVC Controls Toolkit and the Blazor Controls Toolkit libraries. He has contributed to the diffusion and evangelization of the Microsoft web stack since the first version of ASP.NET. His company, Mvcct Team, offers web applications, tools, and services for web technologies. He has moved from AI systems, where he implemented one of the first decision support systems for financial institutions, to top-10 video game titles such as Puma Street Soccer.
Read more about Francesco Abbruzzese