🔬 A JavaScript interpretation of the Ruby library Scientist, a library for carefully refactoring critical paths.
Install
npm install scientist.jsLet'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 capture the current and refactored behaviours under load.
ES6 Sample
import {Experiment, Result} from 'scientist.js';
import Permission from './permission';
import Model from './model';
class MyWidget {
constructor() {
this.model = new Model();
}
allows(user) {
var experiment = new Experiment("widget-permissions");
experiment.use(() => this.model.checkUser(user).valid); // old way
experiment.try(() => user.can(Permission.Read, this.model)); // new way
return experiment.run();
}
}Use use(..) to wrap the existing original behaviour, and use try(..) to wrap the new behaviour. experiment.run(); will always return the result of the use block, but it does a bunch of stuff behind the scenes:
- It decides whether or not to run the
tryblock - Randomises order to execute
tryanduseblocks - Measures the duration of both behaviours
- Swallows (but records) any exceptions raised in the
tryblock and - Set a condition to filter calls to
try
Upcoming features (these already exist in the Ruby library):
- Compares the result of
tryto the result ofuse, - Publishes all this information.
The use block is called the control. The try block is called the candidate.