Unit test in C# without IDE
Tags: dotnet, csharp, github, testing
Published: 2020-12-27 20:32:59

This lab, we’re working on unit test and CI.

### About unit test

I’ve heard about unit test and did some in internship. However, I never got a chance to really understand what I’m supposed to write in unit tests. This is a good chance for me to study about unit test.

My [link checker project](https://dev.to/yuanleemidori/are-you-a-bad-link-or-a-good-link-fgb) uses C#, therefore, I searched the unit test in dotnet environment. There are several tools such as XUnit, NUnit. However, most of the documentations and tutorial are using Visual Studio and rely on its functionalities. In my case, my OS is Linux Mint which can’t install this IDE. After trying all the unit test tools that I can find, NUnit works perfect for me. Here are the steps for using NUnit with IDE:

#### 1. Create a test directory

Move the original code files and its project file (`.csproj`)that run the application to an independent directory (not in the root), and create a new directory for test files.

For example, I moved the application's project file and relevant `.cs` to `GoodLinkOrBadLink` directory, and created a `GoodLinkOrBadLink.Tests` directory for placing my unit tests.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lr1aowgssa0hbg53twri.png)

#### 2. Create unit test project in test directory

`cd` to your test directory and use this command to create a `.csproj` file and a `.cs` file. The default file name of `.cs` is `UnitTest`, I changed it to `Tests.cs`.
```sh
dotnet new nunit
```
#### 3. Add reference to the test project file

In the test project file, add the application file path as reference. Below is an example in my test project file. The file path in the `Include` points to my application's project file.

```html
  <ItemGroup>
    <ProjectReference Include="..\GoodLinkOrBadLink\OSD600.GoodLinkOrBadLink.csproj" />
  </ItemGroup>
```

#### 4. Modify `UnitTest1.cs` (or whatever test file name you have)

In step 2, a `.cs` file is generated with the command `dotnet new nunit`. By default, there is a line of C# directive `using NUnit.Framework;` for us to use the NUnit testing framework. I modified the class name and include my application's namespace as a C# reference.

By adding `[Test]` code block, we can add the unit test that we want to test our functions. For example,
```C
[Test]
public void Version_ValidOptions_ReturnTrue()
{
    //arrange
    string isVersionOpt_1 = "--v";
    string isVersionOpt_2 = "--version";
    string isVersionOpt_3 = "/v";

    //act
    var underTestT_1 = CLIUsage.Version(isVersionOpt_1);
    var underTestT_2 = CLIUsage.Version(isVersionOpt_2);
    var underTestT_3 = CLIUsage.Version(isVersionOpt_3);

    //assert
    Assert.IsTrue(underTestT_1);
    Assert.IsTrue(underTestT_2);
    Assert.IsTrue(underTestT_3);

}
```
I'm using `arrange, act, assert` pattern to write my unit tests. I'm very new to write unit test, therefore, I will not explain how to write a unit test; I followed [this documentation](https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices) to write my unit tests, it is beginner-friendly.

#### 5. Try to run the test!

Open terminal, move to the test directory and run this command to run the test project:
```sh
dotnet test
```
If your test units are all passed, you'll see something like this,
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1j5prgws4dypp177jy0d.png)
However, if there is any test that didn't pass, you'll see something like the below picture with the number of failed tests with the error message and stack trace.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/06senx7b76d7ieimw4e1.png)

Just like how we debug in a normal bug; use the error message and stack trace to find the issue.

### Create a GitHub Action as [CI](https://en.wikipedia.org/wiki/Continuous_integration)

After having unit tests in your repo, we can include the tests to ensure the new PR pass all the test before we merge it.

GitHub has its own CI service named **Action**. I followed its [documentation](https://docs.github.com/en/free-pro-team@latest/actions/guides/setting-up-continuous-integration-using-workflow-templates) which is very straightforward. You might need to make some changes after what I did in my `dotnet.yml` file.


Writing unit test is critical, however, this is actually the first time that I start a unit test from scratch. I'm now more confident to write testing and will study some good practice to improve my skill.

Thank you for reading my blog!