I've been making my way through the Enterprise Skills Initiative, a program from Microsoft that my current employer has access to, and that has a lot of training material for Azure DevOps. You can check out my other posts or just read my last one here:
This week I moved on to the next learning path, running tests as part of a pipeline. In other words they run automatically, which is an important part of any CI build process.
The value of a good suite of tests can't be overstated! I've written before about modifying your code to support testing by mocking static classes and other dependencies, and how you can even test a WinForms app using MVP. The longer I've been writing code, the more important I think it is, and the more I try to get them in there where I can. (Much easier on new projects than decades-old ones.)
A little excerpt from the lesson, which may be helpful if you're relatively new to testing and ended up on this post for reasons unknown.
Automated tests serve as a type of contract. That is, you specify the inputs and the expected results. When you have a set of passing tests, you're better able to experiment and refactor your code. When you make a change, all you need to do is run your tests and verify that they continue to pass. After you've met your refactoring goals, you can submit your change to the build pipeline so that everyone can benefit, but with a lower risk of something breaking.
Unfortunately the lesson suffered a bit, because someone updated the SpaceGame.Web project to .NET 6.0, but forgot to update anything else - the test suite, the yml file used for the devops build, maybe the NuGet packages too (not sure). I started to upgrade it all, but that led to one error after another, so a simple downgrade of the main project back to .NET 5.0 did the trick.
Once you've got it setup to run your test suite though, wow.. Azure DevOps will show your tests results all over. Some of it just happens, while others (like the dashboard) need a little configuration.
They briefly touch on the topic of "code coverage" too, which I think can be a good thing, something to spur the team on and maybe even a good indicator that some new piece of code is missing tests (when the number drops). But it can also easily become part of an effort to achieve "100% code coverage", which I personally think is a waste of time. There's no need to make sure every last piece of code is tested, especially if a method is only calling something in a third-party library or in the .NET Framework, which likely already has its own tests. It's just one of those things, like everything else, that can be abused and warrants discussion among a team, as to what their end goal is.
The author of the lesson had this to say though, which I guess is what I'm trying to say too.
What makes a good test?
Don't test for the sake of testing: Your tests should serve a purpose beyond being a checklist item to cross off. Write tests that verify that your critical code works as intended and doesn't break existing functionality.
Aside from the error I mentioned above, there were a few other errors too - the build issue with .NET 6 I mentioned, a command for "coverlet" that was throwing an error (module test path not found) until I removed the
--no-build switch, and a 500 error when trying to add the "Code Coverage" widget to my dashboard.
The 500 actually ended up being because my account is protected by 2FA, and the auth token had apparently expired, so I needed to logout and back in. Not the author's fault, but dinging Microsoft for it because I wasted time trying to figure out. This was the error the marketplace gave me. So helpful.
All in all though, another decent lesson. It's nice to see that, once a team goes through the effort of running their tests, DevOps makes sure you see it all over the place!