SentryOne Unit Test Generator—Our Journey: Part 1

Matt Whitfield

Published On: October 10, 2019

Categories: Testing, Engineering 0

SentryOne SVP of Product Engineering, John Welch, recently posted a blog that shared how we are applying software engineering practices to delivering our solutions.

This is the first in a series of blog posts about a new free tool from SentryOne that John shared in his blog, the SentryOne Unit Test Generator extension—a unit test generator supporting C# projects. It’s a bit of a departure from our usual area of business, and while Open Source Software (OSS) is not our primary focus at SentryOne, we felt like this tool saved us a ton of time internally, so we wanted to share it with the community at large!

This first blog post focuses on what the extension does for you and how you can use it. I’ll be following up with another post that outlines why we chose to create the Unit Test Generator extension in the first place, and then finally a post that talks about the code and structure of the tool.

Before we dive into it, I’d like to acknowledge the SentryOne team who contributed to the Unit Test Generator during our recent Innovation Sprint. Thank you to Alex Yumashev, Chris Rock, Niall Maguire, and Billy Batton—you guys rock!

What the SentryOne Unit Test Generator Extension Does

The SentryOne Unit Test Generator extension scaffolds basic tests for classes written in C#. The extension covers several fundamental tests automatically (such as checking for correct property initialization and null constructor parameters) as well as creating basic tests for methods. It supports MSTest, NUnit, and xUnit as test frameworks and NSubstitute, Moq, Rhino Mocks, and FakeItEasy as mocking frameworks. Tests are created in a test project using the same hierarchy defined in the source project, making test project organization simple and automatic.

The extension also supports modifying tests throughout the development life cycle, with simple ways to handle refactoring actions, allowing both the addition and regeneration of tests as required. Added a parameter to your constructor and want to regenerate all the null parameter check tests? No problem. Added a method and want to add a new test for it directly from the editor? We’ve got your back.

How to Use the Extension

Once installed, the extension is accessed through additional entries on two context menus —the Solution Explorer context menu and the Code Editor context menu. The following functions are available:

  • Generate tests—Generates tests for the selected entity
  • Regenerate tests—Will replace existing tests with new ones, which is particularly useful for instances like changes in a constructor signature
  • Go to tests—Will go to the file that contains the tests for the selected object (even if you are selecting a member in the code window)
Code Editor Context Menu
Using the Code Editor context menu
Solution Context Menu
Using the Solution Explorer context menu

By design, the “Regenerate” and “Go to” options are not available at higher levels in the Solution Explorer (for example, when you have a folder or project selected). The “Regenerate” option is usually hidden—seeing as it may remove tests that the user has customised. In order to see the “Regenerate” option you need to hold SHIFT while you enter the context menu. It’s also worth noting that you may need to wait a short time after Visual Studio is loaded for all the available options to work. This behavior is due to packages in Visual Studio being loaded asynchronously and leads to situations where the menu items are displayed before the code for the extension is loaded. As extension developers, we don’t have much control over this. However, clicking on the visible functions will cause the extension to load immediately.

An Example 

Let’s consider this simple class:

Source Class

Although this class doesn’t do anything useful (yet), it serves as a good example—highlighting how the tool generates tests based solely on method signatures. Let’s look at the tests that get generated for this class:

Source Class Tests Annotated

You can see that the dependency for the class has been automatically mocked and injected. We have also generated basic tests for the constructor, checking against null parameters for both constructors and methods. You can also see examples of some of the value strategies producing values required for testing—both initializing a POCO (persistence-ignorant object) using an object initializer, and an immutable class by providing values for it.  

Control Over the Process

In order to give you control over certain aspects of the scaffolded code, the Unit Test Generator extension contains an Options page.

Generation Options

Unit Test Generator Options page

On the Generation side, we can choose the test and mocking frameworks in use, as well as control the naming conventions for test projects, test classes, and file naming. The default for project naming is “{0}.Tests,” so a project called MyProject would be associated with a test project called MyProject.Tests. The default for the class and file naming is “{0}Tests,” so a class called “MyClass” would be associated with a test class called “MyClassTests.”

The other available options control whether test projects are automatically created and whether references are automatically added to test projects when needed. There are also versioning options that control which version of the framework dependencies get used. If the version options are left blank, then the latest version is used. The exception to this is NUnit 2. Because NUnit 2 and NUnit 3 share the same NuGet package name, the NUnit 2 version will always be 2.6.4 if this is left blank. Currently the extension doesn’t support automatically creating test projects for .NET Core apps—it’s fine with .NET framework and .NET standard—so if you’re working with .NET Core apps you will need to create the project yourself.

How to Get the Extension 

You can have a look at the source code for the Unit Test Generator here, or you can just get straight to the testing and install the Visual Studio extension here.

In my next blog post, I’ll talk about why we chose to create the Unit Test Generator extension, and the needs that it addresses from our internal perspective.

Thanks for reading and happy testing!

Matt is a Director of Software Engineering at SentryOne, owning the development activities for the Data DevOps product portfolio. Having spent the first part of his career working in payment and loyalty systems, working with several high volume databases, Matt developed a passion for tooling around database systems. He took some time to develop the tools that eventually became DBA xPress when they were acquired by Pragmatic Works. After working with Pragmatic Works to build out their database tooling, Matt joined SentryOne where he is excited to have the opportunity to take that tooling to the next level.


Comments

Sentryone Monitoring Platform Trial