✅ Test in production
It has always been implied that this was wrong. But what if there is a RIGHT way to do it this?
It is a known joke in the developer community to “test in production”, for a few reasons:
it is too late to test then
the users are testing it also and might have a bad experience
it could break production for the users
However, sometimes we need production data to test our changes properly, and testing in production would be super useful and a much more of a thorough test. Is this possible and if yes, how can this be achieved?
TL;DR
Yes, this is possible and can be achieved by decoupling deployments and releases. This is best done using a feature flag tool. My feature flag project of choice is the Open Source project Flagsmith. By wrapping your new feature in a feature flag, and only showing it to a certain users or groups of users like maintainers, you can confidently and safely test it in production as it won’t be visible or affect any other user on the platform.
Prerequisites
Using NextJS (AppRouter) and Flagsmith, you can self-host Flagsmith or use their cloud platform for free. I have a full guide on how to set this up in a previous blog post:
Hiding features
In the Open Source HealthCheck project we have a new feature where we show stats from the platform. This has been tested locally with example data, but it is not the same as testing with real production data. Therefore we would like to deploy the feature to test with real data. However we don’t want users to use it yet, just in case there is a bug. This can be achieved using Flagsmith by wrapping the feature in a feature flag that we can only enable for certain users, like maintainers for example.
There are two steps to this process: 1. Adding the feature flag to Flagsmith’s dashboard and 2. Adding the code to our new feature.
Flagsmith dashboard
I would recommend starting with Flagsmith’s dashboard. That way we will have some actionable results when we move on to the next step of coding.
At this stage you will already have a free Flagsmith account, possibly with some existing feature flags (please see my blog post mentioned at the beginning on how to set this up if you have not already).
Click “Create Feature”.
Give the new feature a unique name, I will use `platform_stats`.
I will not enable it by default and also not give it a value - this is different to what I usually do, especially compared to the banner text example.
Why am I giving it no value and not enabling the feature? For everyone, I want the feature to be disabled rather than enabled (similar to a default state in a database) and I will only enable it for a specific users or groups of users later on.
Segments
For groups of users there are segment overrides. I already have admin and maintainers in my dashboard, which I pass to Flagsmith when initialising their client and in Flagsmith for this segment I check for the trait `isMaintainer`.
initialise.traits = {
isMaintainer: user.isMaintainer,
};
Identity
I decided for this feature flag to override the feature flag to being enabled for my user only. I can easily change this as any time to include more users or groups (aka Segements), as mentioned above.
Code changes
This is even easier, so this section will probably be the shortest - probably not what you expected?
In your code import Flagsmith:
import { useFlags } from "flagsmith/react";
Then use the flag that matches the name you created in the dashboard - another reason why naming is so important.
const { platform_stats } = useFlags(["platform_stats"]);
Near the top of your component check if the feature flag is enabled:
if (!platform_stats.enabled) {
return;
}
Identity
Depending on how you set this up using Identity or Segments, you will probably need to add more information to the Flagsmith initialisation.
What I have done is send to Flagsmith on intialisation the user id and also if they are a maintainer. Then in the Flagsmith dashboard I can select the appropriate method to enable the feature flag.
if (session) {
initialise.identity = session.user.id;
const user = await prisma.user.findUnique({
where: { id: session.user.id },
});
initialise.traits = {
isMaintainer: user.isMaintainer,
};
}
Conclusion
You can test in production safely! Previously this was used a negative term but with modern development practices, it is actually safe and positive.
You can see this fully implemented in the Open Source HealthCheck repo
https://github.com/EddieHubCommunity/HealthCheck
If you would prefer to watch a video on this topic: