Add a test project
Now that we have a basic understanding of how to create a command line parser we should probably introduce a test project. This will help us to better keep track of the various scenarios we create and ensure they are still working as expected.
The first thing we will do is create a new directory called SimpleCmdLine in the src directory and create another directory called SimpleCmdLine.Tests.
We need to move the existing files for SimpleCmdLine into the new subdirectory src/SimpleCmdLine.
In order to make it easier to run dotnet commands we need to also add a solution file.
$ dotnet new sln --name SimpleCmdLine
The template "Solution File" was created successfully.
$ dotnet sln add SimpleCmdLine
Project `SimpleCmdLine/SimpleCmdLine.csproj` added to the solution.
$ cd SimpleCmdLine.Tests
/SimpleCmdLine.Tests$ dotnet new xunit
The template "xUnit Test Project" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/SimpleCmdLine.Tests.csproj...
Determining projects to restore...
Restored /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/SimpleCmdLine.Tests.csproj (in 2.11 sec).
Restore succeeded.
/SimpleCmdLine.Tests$
Write the first test
The xunit template creates two file for us. The first is the csproj file and the other is called UnitTest1.cs. Under most projects you will want to rename the UnitTest1.cs file to something that better reflects the tests being performed. I am going to leave it named UnitTest1.cs for now.
Just want to point out that the tests we are running are not not unit tests. These are more like functional, system or end-to-end tests.
Add Project Reference
Before we can run any tests we need to be able to access the SimpleCmdLine application. This requires that we make a slight modification to the csproj file that was created for us.
Open SimpleCmdLine.Tests.csproj and add the following lines just before the </Project>
tag.
<ItemGroup>
<ProjectReference Include="..\SimpleCmdLine\SimpleCmdLine.csproj" />
</ItemGroup>
This tells the test project where to find the project for the console application.
Modify UnitTest1.cs
Now that we have a reference to the console application we need to add a reference to it in the Unit test file.
Add using SimpleCmdLine;
to the top of the file.
The file contains a single class called UnitTest1
. Inside of the class is a single method called Test1()
. The [Fact]
attribute is what tells Xunit that this is a test case.
The initial method is blank and serves as a simple template.
Remove the Test1()
method from the file and add the following code inside of the UnitTest1
class.
[Fact]
public void NoArgs_ReturnsFail()
{
string[] args = new string[]{};
var result = Program.Main(args);
Assert.Equal(0, result);
}
In the spirit of TDD (yes I know we didn't create the test first!) we are going to write a red (failing) test first. I am doing this for a couple of reasons. The primary is that I want to make sure that I can properly detect a failure.
Run the test
Save the changes to UnitTest1.cs
. Your file should now look like this.
using System;
using Xunit;
using SimpleCmdLine;
namespace SimpleCmdLine.Tests
{
public class UnitTest1
{
[Fact]
public void NoArgs_ReturnsFail()
{
string[] args = new string[]{};
var result = Program.Main(args);
Assert.Equal(0, result);
}
}
}
While in your src
directory for the repository run dotnet test
. This will compile the SimpleCmdLine project and the SimpleCmdLine.Tests project. It will then run all of the tests that are discovered by Xunit.
The results should look something like the following:
$ dotnet test
Determining projects to restore...
All projects are up-to-date for restore.
SimpleCmdLine -> /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine/bin/Debug/net5.0/SimpleCmdLine.dll
SimpleCmdLine.Tests -> /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/bin/Debug/net5.0/SimpleCmdLine.Tests.dll
Test run for /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/bin/Debug/net5.0/SimpleCmdLine.Tests.dll (.NETCoreApp,Version=v5.0)
Microsoft (R) Test Execution Command Line Tool Version 16.9.4
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
... (You may see output from the application here)
[xUnit.net 00:00:00.52] SimpleCmdLine.Tests.UnitTest1.NoArgs_ReturnsFail [FAIL]
Failed SimpleCmdLine.Tests.UnitTest1.NoArgs_ReturnsFail [85 ms]
Error Message:
Assert.Equal() Failure
Expected: 0
Actual: 1
Stack Trace:
at SimpleCmdLine.Tests.UnitTest1.NoArgs_ReturnsFail() in /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/UnitTest1.cs:line 14
Failed! - Failed: 1, Passed: 0, Skipped: 0, Total: 1, Duration: 85 ms - /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/bin/Debug/net5.0/SimpleCmdLine.Tests.dll (net5.0)
We can see from the results that our test failed. This is exactly what we wanted.
Now edit the test to change the expected value from 0
to 1
.
If we run dotnet test
again we can see that the test is now passing.
Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: 80 ms - /Users/iesoftwaredeveloper/repos/SimpleCmdLine/src/SimpleCmdLine.Tests/bin/Debug/net5.0/SimpleCmdLine.Tests.dll (net5.0)
In this case, a one means that the application exited with an unsuccessful result. Our test confirms that if you do not provide the required arguments that the application will fail.
You must be logged in to see the comments. Log in now!