Introducing Shience: What it is and how to use it

Introducing Shience: What it is and how to use it

Shience is a .NET library for carefully refactoring critical paths. It is built on .NET Core, currently targets .NET 4.5.1 and DNX Core 5.0, and is available on Github and Nuget.

Keep in mind that it's early, and the API is subject to change.

What is a critical path?

A critical path is a section of code that is not only important, but critically important to the functionality of your application. Good examples are permission checking, transactions in bank software, or pull request merges at Github.

These sections of code are often the code that gets ignored. Not because they're not important, but rather that they're too important. If you're maintaining an application for bank transactions, you want to be absolutely sure the code that deducts money from an account calculates the deduction accurately and consistenly - no rounding errors, no overflows, no issues. The code is so critical that developers are often afraid to touch it. If no one touches it, no performance enhancements can be implemented and any previous technical debt will never be never paid off.

Why is Shience needed?

Development testing and QA are good first steps towards ensuring quality of your code, but as all developers know bugs can easily fall through. This is why unit tests are created.

And unit tests are great. They help drive the develoment process and find bugs, and help in refactorings, but they don't cover all test cases. They can't cover all test cases. And when refactoring critical code, you need to make sure there are no regressions. But how do you do that if you can't cover all test cases?

What if you could run the code side by side and compare the results? This is what Shience does, and it does it, in production, on real world data.

The Github post I linked above is a great case study on why this can be so helpful. They wanted to refactor pull request merges, but it is physically impossible to not only write enough tests to cover all cases, but test it on enough repositories to ensure no regressions were added. The ability to run both merges together, in production, on real repositories, on all requests allowed them to be 100% confident in their refactor. Which, on an application with millions of users, is a huge, huge deal.

How do I use it?

Grab the latest on Nuget, of course. The latest version is 0.0.1-beta5, but we are releasing rather quickly so by the time anyone reads this it might be out of date.

The readme has plenty of examples, but here's a quick starter.

var experiment = Science.New<bool>("my-test-code");
var result = experiment.Test(() => FirstMethod(),
                             () => SecondMethod())
                       .PublishTo((e) => Console.WriteLine(e.Matched))
                       .Execute();

Shience will run both the Test methods (the first is the control, the second is the candidate) in a random order. It will record the results in an ExperimentResult and provide that to you in the PublishTo method, and will then return the result of the control method.

When is 1.0?

I don't know, but we're moving fast. We should get to 1.0 by the time Episode 8 is out at least.