Skip to main content

Command Palette

Search for a command to run...

Clean Code Tip: Tests should be even more well-written than production code

Published
2 min read
Clean Code Tip: Tests should be even more well-written than production code
D

I’m a Principal Backend Developer with more than 10 years of professional experience. I’ve been working with Microsoft platforms and frameworks since 2014.

I’ve worked with many tools and frameworks, such as Azure, MongoDB, Docker, and, of course, .NET and C#. I love learning new things, and I think that the best way to learn is to share: that’s why I started my journey as a content creator and conference speaker.

You surely take care of your code to make it easy to read and understand, right? RIGHT??

Well done! 👏

But most of the developers tend to write good production code (the one actually executed by your system), but very poor test code.

Production code is meant to be run, while tests are also meant to document your code; therefore there must not be doubts about the meaning and the reason behind a test. This also means that all the names must be explicit enough to help readers understand how and why a test should pass.

This is a valid C# test:

[Test]
public void TestHtmlParser()
{
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml("<p>Hello</p>");
    var node = doc.DocumentNode.ChildNodes[0];
    var parser = new HtmlParser();

    Assert.AreEqual("Hello", parser.ParseContent(node));
}

What is the meaning of this test? We should be able to understand it just by reading the method name.

Also, notice that here we are creating the HtmlNode object; imagine if this node creation is present in every test method: you will see the same lines of code over and over again.

Thus, we can refactor this test in this way:

 [Test]
public void HtmlParser_ExtractsContent_WhenHtmlIsParagraph()
{
    //Arrange
    string paragraphContent = "Hello";
    string htmlParagraph = $"<p>{paragraphContent}</p>";
    HtmlNode htmlNode = CreateHtmlNode(htmlParagraph);
    var htmlParser = new HtmlParser();

    //Act
    var parsedContent = htmlParser.ParseContent(htmlNode);

    //Assert
    Assert.AreEqual(paragraphContent, parsedContent);
}

This test is definitely better:

  • you can understand its meaning by reading the test name
  • the code is concise, and some creation parts are refactored out
  • we've well separated the 3 parts of the tests: Arrange, Act, Assert (we've already talked about it [here](https://www.code4it.dev/cleancodetips/aaa-pattern-for-tests/ "AAA pattern for tests: why is it important?"))

Wrapping up

Tests are still part of your project, even though they are not used directly by your customers.

Never skip tests, and never write them in a rush. After all, when you encounter a bug, the first thing you should do is write a test to reproduce the bug, and then validate the fix using that same test.

So, keep writing good code, for tests too!

Happy coding!

🐧

10 views

More from this blog

C

Code4IT

78 posts

Code4IT, by Davide Bellone, is a blog for backend developers covering .NET, Azure, Software Architecture, Testing strategies, tools, and more, all with a straight-to-the-point approach.