I want to learn unit test.
I studied it a little when I earned my ISTQB CTFL certification. The textbook said
Component testing (also known as unit testing) focuses on testing components in isolation. It often requires specific support, such as test harnesses or unit test frameworks. Component testing is normally performed by developers in their development environments.
That makes sense-but does it mean I can just start writing unit tests? Could I start to unit test? I don’t think so.
I had three broad questions.
- What is “unit”? Is it a class or it depends on the type of application(e.g., Windows application or Web application)
- Why are unit test necessary at all?
- How do we write them, especially for Windows application case.
So, I started researching these questions by reading this book. As the reviews reviews, it is helpful for me. I recommend it.
I’m not a experienced expert (so, the title is automation kid), but I’ll try to answer the above questions.
Why does unit test necessary?
The goal is to enable sustainable growth of the software project.
The term sustainable is key. It’s quite easy to grow a project, especially when you start from scratch.
It’s much harder to sustain this growth over time.Khorikov 2020
This makes it clear: applications naturally become complicated-due to limited resources, lack of developer skills, less documentation and so on.
The author argues that unit test can contribute significantly to an application’s maintainability.
I agree. I once worked on an application I had developed, and when I planed to add another functionality, I wished I had test documentation and automated tests.
I believe that the more complex an application becomes, the more valuable test documentation and automation become.
Other articles from Geekflare and How-to-geek also express similar views.
What is “Unit”?
A unit test is an automated test that
- Verifies a small piece of code
- Does it quickly
- And does it in an isolated manner
Khorikov 2020
The author also explains tow main schools of thought about test isolation. This helped answer my first question.
- The London school states that the units under test should be isolated from each other. A unit under test is a unit of code, usually a class.
- The classical school states that the unit tests need to be isolated from each other, not units. Also, a unit under test is a unit of behavior, not a unit of code.
Khorikov 2020
I find the London school’s approach clearer—it leaves little room for confusion. The Classical school feels more ambiguous to me, so I want to study it further with examples and understand the characteristics of both.
Unit test requires unit testable code
I had thought I need to learn only unit testing framework like NUnit, xunit and best practices like anti-patterns. Now, I think that idea is wrong. I took a online course Unit Testing for C# Developers by Mosh Hamedani and I found that better unit test requires unit testable code.
For example, there is a method which reads text file including book information and returns book’s title (below code).
class BookService
{
public string ReadBookTitle()
{
var str = File.ReadAllText("book1Info.txt");
Book book1 = JsonSerializer.Deserialize<Book>(str);
if(book1 == null)
{
return "Error parsing the book.";
}
return book1.Title;
}
}
public class Book
{
public int Id;
public string Title;
}
When you wanna unit test for ReadBookTitle(), there are some issues.
First, you need to prepare book1Info.txt that requires time and domain knowledge like what text file is used in the real case like “how many lines are there?”, “The end of the line can be “,” or “\r\n” ?”, and it becomes more difficult to read more complicated file as you know. Unit testing requires fast and isolated, so a above example violates it.
To make it unit testable, there are some refactoring points which I’m learning.
I think making code loosely-coupled help it unit testable.
class BookService
{
public string ReadBookTitle(IFileReader fileReader)
{
var str = fileReader.ReadInfoFile("book1Info.txt");
~~~
}
}
public class Book
{
~~~
}
class FileReader : IFileReader
{
public string ReadInfoFile(string path)
{
return File.ReadAllText(path);
}
}
public interface IFileReader
{
string ReadInfoFile(string path);
}
I changed some points for helping it loosely-coupled and to give stub (as belows).
- Extract a part accessing external resources (ReadInfoFile method),
- Implement a interface (IFileReader).
- Prepare a argument for receiving IFileReader.
I’m learning how to refactor code for unit test, so there are more techniques for improving unit testability.
Conclusions and my future plan
I’ve read Chapters 1 and 2 of the book, which answered most of my questions-except for third one.
I’ve learned :
- Why unit tests are important
- That there are two main schools of unit test isolation
But now I have more specific questions:
- What exactly is unit of behavior in Classical schools? (with example)
- How do we design tests? What information is needed to write a good test case?
- When is the right time to start writing unit test?
Finally, I want to actually write test cases and automation tests.
Next, I’ll dive into these topics.
Reference
- Khorikov, Vladimir. Unit Testing Principles, Practices, and Patterns: Effective testing styles, patterns, and reliable automation for unit testing, mocking, and integration testing with examples in C# (English Edition) . Manning. Kindle 版.
- Geekflare, Unit Testing Explained: What It Is, Why It’s important, and How to Get Started, Last updated: January, 20, 2025
- How-To Geek, What Is Unit Testing and Why Is It important?, Read at April, 13, 2025
コメント