<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:discourse="http://discourse.org/rss/modules/discourse/"><channel><title>Testing on DevBlog</title><link>https://devblog.criticalmanufacturing.com/categories/testing/</link><description>Recent content in Testing on DevBlog</description><image><url>https://devblog.criticalmanufacturing.com/uploads/og.webp</url><link>https://devblog.criticalmanufacturing.com/uploads/og.webp</link></image><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>A template by [Heksagon](https://www.heksagon.net). Implemented for [Critical Manufacturing](https://www.criticalmanufacturing.com/).</copyright><lastBuildDate>Mon, 07 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://devblog.criticalmanufacturing.com/categories/testing/index.xml" rel="self" type="application/rss+xml"/><item><title>Running .NET Tests on Linux</title><link>https://devblog.criticalmanufacturing.com/blog/20260907_running_dotnet_tests/</link><pubDate>Mon, 07 Sep 2026 00:00:00 +0000</pubDate><dc:creator>Sofia Rodrigues dos Santos</dc:creator><guid>https://devblog.criticalmanufacturing.com/blog/20260907_running_dotnet_tests/</guid><description>Our development environment has been on Linux for a while, but the .NET tests still required Windows to run correctly. This blog post describes how I fixed that.</description><content:encoded><![CDATA[<p>I&rsquo;m going to start with a disclaimer: I only joined Critical Manufacturing after the switch to WSL for local development. Therefore, for me, WSL (or Linux in general) is the default dev environment. This means that, when I have to run end-to-end (E2E) tests and I&rsquo;m told to use Visual Studio on Windows, my workflow gets disrupted.</p>
<p>If this &ldquo;cross-platform&rdquo; workflow was smooth and without issues, I probably wouldn&rsquo;t be writing this blog post. Alas, if you have ever run MES or Platform tests in Visual Studio, you know this isn&rsquo;t the case. Permission errors, LBO errors, build errors, I&rsquo;m sure you&rsquo;ve encountered at least one of these.</p>
<p>Recently, I went on a quest to try and fix this issue. My goal was to have a seamless testing workflow. Ideally, I would select a test or a list of tests, press a button, and they would just run. If you just want to know what I did, and how you can do it too, skip to the &ldquo;My Solution&rdquo; section. However, if you&rsquo;re interested in the whole process and not just the result, you should read the whole blog post. It&rsquo;s 100% human-written by me. 😁</p>
<h2 id="visual-studio">Visual Studio</h2>
<p>In order to fix this problem, I first had to understand it.</p>
<p>Why did Visual Studio fail so much?</p>
<p>There&rsquo;s no <strong>one</strong> answer, but there <em>is</em> an explanation for most of the issues. If you took an Operating Systems class in university, you already know that Windows and Linux use different instruction sets in their machine code.</p>
<p>For everyone else, the only thing you need to know is that, when a program is compiled, it&rsquo;s converted to machine code. Computers don&rsquo;t &ldquo;speak&rdquo; code in the way we write it, the compiler converts it to a simpler format that the CPU can understand and execute as binary instructions. Different operating systems, and even different CPU brands, use different instruction sets. Therefore, an executable compiled for Windows cannot run in Linux and vice-versa.</p>
<p>What does this mean for us? It means that, when we compile our tests, since we run the command in Linux, they are compiled for Linux, not Windows. It means that we need to compile them again on Windows (that&rsquo;s why you need to build — sometimes with a clean or full rebuild — your Visual Studio solution when you open it).</p>
<p>This isn&rsquo;t the only problem. The <code>localenv</code> WSL only has one user: root. When build files are generated, their owner is <code>root</code>. Sometimes, Windows may need to overwrite some of these build files when compiling the solution in Visual Studio. However, since they have a different owner from the current Windows user, you may get a permission error. Windows can&rsquo;t overwrite files that it doesn&rsquo;t own or have permission to write.</p>
<hr>
<p>Okay, Visual Studio doesn&rsquo;t seem to be the best option for our current workflow. Why don&rsquo;t we use VS Code instead then?</p>
<h2 id="visual-studio-code-vs-code">Visual Studio Code (VS Code)</h2>
<p>VS Code has native WSL support, which means that we can compile and run our tests without having to switch to a Windows program. This gets us very close to the ideal solution I mentioned earlier. Unfortunately, VS Code also has its fair share of issues.</p>
<p>If you have never used VS Code to run .NET tests, you&rsquo;re not aware of its limitations, so I&rsquo;ll briefly go over them.</p>
<p>First, VS Code is a text editor, not an IDE, so it needs extensions that implement a test explorer, a debugger, etc. Microsoft has an extension for this purpose — <strong>C# Dev Kit</strong> — but it lacks many of Visual Studio&rsquo;s features. For example, you can&rsquo;t use a <code>.playlist</code> file to filter tests. If you didn&rsquo;t know, our <code>cmf-product</code> command can generate a <code>.playlist</code> file with the tests that are failing in the latest CD / Nightly environment. If you use VS Code to run tests, this is worthless.</p>
<p>Additionally, the native test search feature is very limited. You can&rsquo;t search tests by class or project in the same way you can in Visual Studio. You can&rsquo;t filter tests by their status (technically you can select an option to only display the failed or executed tests, but that&rsquo;s it; there&rsquo;s no way to only see passing tests, skipped tests, etc.).</p>
<hr>
<p>This makes VS Code a possible replacement for Visual Studio, but a severely lacking one. However, its biggest weakness is also its biggest strength. Since features can just be implemented using extensions, why not create an extension to bridge the gap between VS Code and Visual Studio? That&rsquo;s exactly what I did!</p>
<h2 id="my-solution">My Solution</h2>
<p>Let me introduce you to <strong>.NET Testing+</strong>, a new VS Code extension that makes running .NET tests on Linux not just possible, but even easier and better than on Windows. I know this is a bold claim, but I think you will agree with me after trying it out. I&rsquo;ve been using it for the past few weeks, and I haven&rsquo;t opened Visual Studio since. All of my work is done in VS Code now.</p>
<p>If you just want to use it, you can install it from <a href="https://marketplace.visualstudio.com/items?itemName=RisingFisan.dotnet-testing-plus" target="_blank" rel="noopener">here</a>, but as you&rsquo;ve come this far on this blog post, I suggest you finish reading it first.</p>
<p>
<img src="/blogPosts/posts/20260907_running_dotnet_tests/dotnet_testing_plus.png" alt=".NET Testing&#43; VS Code extension header" />

</p>
<p><strong>.NET Testing+</strong> implements every feature that we need (and some that we didn&rsquo;t even knew we needed) in order to run .NET tests using VS Code. Since everything runs in VS Code, this means that our workflow doesn&rsquo;t need to leave WSL now. Everything lives and runs within our <code>localenv</code>.</p>
<p>
<img src="/blogPosts/posts/20260907_running_dotnet_tests/dotnet_testing_plus_view.png" alt=".NET Testing&#43; VS Code view. Most settings are visible, as well as the test explorer with a custom filter applied." />

</p>
<p>First and foremost, .NET Testing+ lets you have more than one solution open at a time. Yes, you read that correctly. This means that you can run integration and E2E tests, MES and Platform tests, or tests from any other .NET project, all at the same time, without having to switch solutions or open new windows. Each solution uses its own .runsettings file, so that they can have their own configuration without interfering with each other.</p>
<p>You can also read <em>and</em> write <code>.playlist</code> files. If you have a custom filter applied to run specific tests and you want to share it with others, or just save it for later, put those tests in a <code>.playlist</code> file. You (or someone else) can then open it and see those exact tests.</p>
<p>Speaking of filters, you can also search through tests by class or project. .NET Testing+&rsquo;s search bar allows you to write something like <code>(Project:Dashboards &amp; Class:UIPage) | Class:ActionBar</code>, which would show only the tests from the <code>Dashboards</code> project that are defined in a class with <code>UIPage</code> in its name, or tests from any project, as long as their classes have <code>ActionBar</code> in their name. You even have toggles to show only the passing, failing, skipped or not run tests, as well as any combination of these attributes.</p>
<p>Two other features that are still a work in progress, but are already functional, are the &ldquo;Override Runsettings&rdquo; and &ldquo;Export Screenshot&rdquo; features.</p>
<p><strong>Override runsettings</strong> lets you run tests with custom runsettings options, without having to modify the file. This allows for quick changes, like making multiple tests run in parallel, with minimal effort.</p>
<p><strong>Export screenshot</strong> generates an image with the tests that have run in the current session. With this feature, you no longer have to mess with the explorer tab in order to make it big enough to take a screenshot, or take multiple screenshots because the list of tests is too big. Just press the button (with options to customize the screenshot) and you have an image ready to paste in the PR description.</p>
<p>These features may have some bugs, so if something is not working correctly, feel free to warn me, or fix it yourself. The code is open-source and can be viewed on <a href="https://github.com/RisingFisan/vscode-dotnet-testing-plus" target="_blank" rel="noopener">the extension&rsquo;s GitHub page</a>.</p>
<p>To address the elephant in the room: yes, this project was developed mostly by GenAI — &ldquo;vibe-coded&rdquo;, as they say. Writing all of this code by hand would take a lot of time, more than I have to give, unfortunately, and since this extension is not an official CMF product, its existence is more valuable than the quality of its code. Every feature has been human-tested and validated, but there may be some kinks that haven&rsquo;t been discovered yet.</p>
<hr>
<p>So&hellip; problem solved, right? Kinda, but not really.</p>
<p>Now we can run tests on Linux, but just because they CAN run, it doesn&rsquo;t mean that they SHOULD run.</p>
<h2 id="other-issues">Other Issues</h2>
<p>We fixed the workflow, but the work itself hasn&rsquo;t changed. The tests are still designed to run in Windows.</p>
<p>For most of them, this doesn&rsquo;t really mean anything. However, some tests use Windows-specific features, most notably file share paths, carriage returns and backslashes.</p>
<p>For those of you who didn&rsquo;t study this in university (or didn&rsquo;t pay attention), here&rsquo;s the gist of it:</p>
<ul>
<li>
<p>Paths in Windows work differently from Linux. Linux (and other Unix systems, for that matter, including MacOS) use forward slashes (<code>/</code>) to separate folder/directory names in file paths. Windows, on the other hand, can also use backslashes (<code>\</code>) in file paths. If a test contains a path with backslashes, it will only work on Windows.</p>
</li>
<li>
<p>File shares, like <code>\\files</code>, in addition to this problem, have the additional obstacle that they must be mounted. In <code>localenv</code>, the <code>files</code> share is mounted in <code>/src/files</code>, which means that, if a test needs to access a file that&rsquo;s available there, it needs a different path to access the file share.</p>
</li>
<li>
<p>Carriage returns are a vestigial artifact from the typewriter days. If you have never used one (I haven&rsquo;t 😅), all you need to know is that, when you finished writing a line, you couldn&rsquo;t just switch to the line below it, you also had to return the carriage (the thing that holds the paper) back to the left of the typewriter, otherwise you would start writing at the end of the next line, instead of at the start. Windows systems still use the carriage return symbol (<code>\r</code>) when switching to a new line. If you&rsquo;ve never seen it, that&rsquo;s because your computer hides it automatically. It&rsquo;s a control character, so it doesn&rsquo;t need to be displayed. The problem with this is that Linux doesn&rsquo;t use carriage returns when switching to a new line, computers don&rsquo;t need them for this purpose, Windows just kept them for backwards compatibility. This means that text that spans multiple lines will use this character or not, depending on which OS you&rsquo;re using.</p>
</li>
</ul>
<p>I have already merged a PR that aims to fix these issues and make every test cross-platform. Some may have slipped by, so keep an eye out for them and, if you come across one, you can try to fix it yourself.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If you&rsquo;re reading this sentence, thank you for putting up with me for this long, unless you just skipped to the conclusion&hellip;</p>
<p>The main point of this post was to share my extension and the reasons why I created it. I love Linux and the Free and Open-Source Software (FOSS) philosophy, and I hope that, moving forwards, we can rely less and less on Windows for our work.</p>
<p>If you have any ideas on how to improve <strong>.NET Testing+</strong>, I hope you&rsquo;ll reach out to me or give a go at implementing it yourself.</p>
<p>Happy coding! 😊</p>
<h2 id="about-me">About me</h2>
<p>Hi, I&rsquo;m Sofia (she/her)! I joined Critical Manufacturing in 2025 (and again in 2026 after a brief &ldquo;sabbatical&rdquo;). Currently I&rsquo;m working as a Software Engineer in the MES White Squad.</p>
<p>You can visit <a href="https://www.sofiars.com" target="_blank" rel="noopener">my website</a> to learn more about me and read more of what I&rsquo;ve written.</p>
]]></content:encoded></item></channel></rss>