[OSD600 Series] Lab 08 - Automated Testing for SSG

by Andrew N.T.

Hero image

Photo by Hans Reniers

Table of Contents

  1. Setup MS Test
  2. Writing test cases
  3. Ending note
  4. Additional Resources

Setup MS Test

According to .NET documentation for testing, there are three most popular .NET testing frameworks: xUnit, NUnit and MSTest. I don't have much knowledge about any of these, but I chose MSTest because it is the "Microsoft test framework". I hoped it would ease the setup and integrate smoothly with my current project.

That's to say, still quite a lots of reorganized stuffs I had to do. First of all, I then needed to put my test code and my main code into separate project packages (i.e. two different .csproj). Was quite the hassle as I remembered a bunch of my build scripts (and even logic) depended on the project root folder. To minimize the pain, I moved the whole current project into a folder, and gradually moved unnecessary files outside while running the build script at each step to make sure everything was still working.

After that, I followed the documation for setting up.

  1. Add a new soluntion at the root of the project (if you haven't done so)
dotnet new sln
  1. Add MainProject to solution
dotnet sln add ./path/to/MainProject/your-project.csproj
  1. Initialize a new MSTest project named TestProject
dotnet new mstest -o TestProject
  1. Add a reference from TestProject to MainProject
cd TestProject
dotnet add reference ../MainProject/your-project.csproj 
  1. Add TestProject to solution
dotnet sln add ./path/to/TestProject/your-project.csproj
  1. Run test
# Build MainProject and run tests in TestProject
dotnet test

# Only run tests in TestProject
dotnet test TestProject

Writing test cases

This was the lab that got me thinking "Huh, I'd happily get that 4% deduction".

Initially, I tried to mimick the manual build steps for testing, which involves reading files from current working directory. For hours, I searched for a way to copy files into the test run environment. Embedding resources, DeloymentItem, etc. none worked for me.

I was ready to gave in, but then I realized I didn't need to read text from the current working directory, I could just created a new file on the fly, and read directly from that file.

  this.txtFilePath = Path.GetRandomFileName() + ".txt";
  using (System.IO.FileStream fs = System.IO.File.Create(this.txtFilePath))
  {
    fs.Write(Encoding.ASCII.GetBytes("Title\n\n\nHello World"));
  }

  this.mdFilePath = Path.GetRandomFileName() + ".md";
  using (System.IO.FileStream fs = System.IO.File.Create(this.mdFilePath))
  {
    fs.Write(Encoding.ASCII.GetBytes("#Title\nHello World"));
  }

After that, just need to pass those paths to the generator

  [TestMethod]
  public void RunWithMultipleFiles()
  {
    string[] args = { "-i", this.txtFilePath, this.mdFilePath, "-o", this.distPath, "-s", this.styleSheetUrl };
    var generator = new Generator(args);
    generator.Run();

    Assert.IsTrue(Directory.Exists(this.distPath));
    Assert.IsTrue(File.Exists(this.txtFileDistPath));
    Assert.IsTrue(File.Exists(this.mdFileDistPath));
  }

Ending note

Admittedly, it was not as fun and easy as testing websites (cypress), but it was a rewarding experience regardless. I did have to do some small tweaks to make the code testable.

I feel like architecting tests is also a piece of art. It takes great efforts to write tests that are loose enough not to break on every deployment, but strict enough to give confidence to developers.

Additional Resources