-
Notifications
You must be signed in to change notification settings - Fork 95
Basic usage
Josh Hiles edited this page Dec 23, 2023
·
1 revision
Let's pretend you're changing the way you handle permissions in a large web app. Tests can help guide your refactoring, but you really want to compare the current and refactored behaviors under load.
using GitHub;
...
public bool CanAccess(IUser user)
{
return Scientist.Science<bool>("widget-permissions", experiment =>
{
experiment.Use(() => IsCollaborator(user)); // old way
experiment.Try(() => HasAccess(user)); // new way
}); // returns the control value
}Wrap a Use block around the code's original behavior, and wrap Try around the new behavior. Invoking Scientist.Science<T> will always return whatever the Use block returns, but it does a bunch of stuff behind the scenes:
- It decides whether or not to run the
Tryblock, - Randomizes the order in which
UseandTryblocks are run, - Measures the durations of all behaviors,
- Compares the result of
Tryto the result ofUse, - Swallows (but records) any exceptions raised in the
Tryblock, and - Publishes all this information.
The Use block is called the control. The Try block is called the candidate.
If you don't declare any Try blocks, none of the Scientist machinery is invoked and the control value is always returned.
- Publishing results
- Controlling comparison
- Adding context
- Expensive setup
- Keeping it clean
- Ignoring mismatches
- Enabling or disabling experiments
- Ramping up experiments
- Running candidates in parallel (asynchronous)
- Testing
- Handling errors
- Designing an experiment
- Finishing an experiment
Sometimes scientists just gotta do weird stuff. We understand.