During my days at university, I took a course on high level programming. We learned about Python and Bash scripts, and we also had a short introduction to Regex. I’ve hardly touched Bash and Python since I took that course, but Regex is a tool that has proven to be incredibly useful the few times I’ve needed it. Describing a set of strings with a string, and also being able to capture parts, is very useful. It is not that useful when processing files, but it can be a lifesaver when you have to refactor a lot of code. Doing this manually is very tedious and is something that often can be done in batches using regex.
Assert
Unit tests are often written using the Assert class in the test framework. It works fine, but it becomes very hard to read. Tests can also become very inconsistent over time lifetime of a project, it gets even worse with multiple contributers and lacking guidelines. I personally prefer using FluentAssertions, which makes tests easier to write and also much easier to read.
A test written using Assert:
[Fact] public async Task CreateCustomer_ValidCustomer_ShouldBeAddedToDb() { var customerRepo = new CustomerRepository(); var expected = new Customer { FirstName = "John", LastName = "Smith", Email = "John.Smith@test.com" }; var actualId = await customerRepo.CreateCustomer(expected); Assert.NotEqual(Guid.Empty, actualId); var actualCustomer = await customerRepo.GetCustomer(actualId); Assert.Equal(expected, actualCustomer); Assert.True(customerRepo.customers.Count == 1); // Yes I have seen stuff like this, and it makes me sad. }
Using FluentAssertions:
[Fact] public async Task CreateCustomer_ValidCustomer_ShouldBeAddedToDb() { var customerRepo = new CustomerRepository(); var expected = new Customer { FirstName = "John", LastName = "Smith", Email = "John.Smith@test.com" }; var actualId = await customerRepo.CreateCustomer(expected); actualId.Should().NotBeEmpty(); var actualCustomer = await customerRepo.GetCustomer(actualId); actualCustomer.Should().Be(expected); customerRepo.customers.Should().HaveCount(1); }
Refactoring legacy code is a nightmare
Are we developers because we are lazy, or are we lazy because we are developers? Regardless of the answer we often seek the easiest path. Which is why being lazy is not inherently bad. Laziness breeds ingenuity, and worming your way out of manual work saves you time and your employer money.
Recently I had the pleasure of refactoring a thousand tests from nunit to xUnit, we decided that migrating from Assert to FluentAssertions was a prerequisite for this. The only issue is that there were about a thousand tests spread over five test projects, and all of them used Assert, and often without any consistency. This turned out to be a small nightmare, as there were about five thousand assertions that were waiting for me to refactor them. I could probably have spent a couple of days doing this manually, but luckily I know a bit of regex.
Even with my limited experience with this tool, I managed to save about two days of manually refactoring legacy tests. It is such a good tool, and requires little experience to save a lot of time, so I think developer should know some regex.