[OSD600 Series] Lab 08 - Automated Testing for SSG

Photo by Minku Kang on Unsplash

[OSD600 Series] Lab 08 - Automated Testing for SSG

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