📜 ⬆️ ⬇️

Gremlins.js - monkey testing library for web applications

NPM version

This is the first of two articles about testing with gremlins.js and grunt-gremlins . The first article is a translation of the official gremlins.js documentation. The second is the experience of introducing gremlins.js into a real project using grunt-gremlins.

Gremlins.js is a monkey testing library written in JavaScript, for Node.js and browsers. With its help, the reliability of web applications is checked under the hordes of gremlins.
')
Kate: What are they, Billy?
Billy Peltzer: They're gremlins, Kate, just like Mr. Futterman said.


image


purpose



Do you foresee all unusual user scripts when developing HTML5 applications? Can you detect and fix possible memory leaks? If not, your application may fail sooner or later. If random actions can put your applications, it is better to find out about the problems at the testing stage, rather than letting the user discover them on their own.

Gremlins.js emulates random user actions: gremlins click anywhere they can get, enter random data into forms, or move the mouse over elements that do not expect it. Their goal: to cause a javascript error or cause the application to fail. If they failed, congratulations! The application is bulletproof enough to show it to real users.

This practice is also known as Monkey testing or Fuzz testing , it is widespread in the world of mobile development (look at the Android Monkey program ). Today, when the interface (MV *, d3.js, Backbone.js, Angular.js, etc.) and the backend (Node.js) is developed entirely in JavaScript, this technology is becoming applicable to web applications.

Basic use



Gremnlin horde is an army of specialized gremlins ready to shake up your application. Release ( unleash ) them to start stress tests:

 var horde = gremlins.createHorde() horde.unleash(); //    ,    10ms, 100  


Gremlins.js provides several types of gremlins: some click in various places, others fill out forms with data, someone will scroll the browser window, etc.

You can observe their behavior in the browser window (they leave traces behind them) or track logs in the console:

 gremlin formFiller input 5 in <input type=​"number" name=​"age">​ gremlin formFiller input pzdoyzshh0k9@o8cpskdb73nmi.r7r in <input type=​"email" name=​"email">​ gremlin clicker click at 1219 301 gremlin scroller scroll to 100 25 ... 


In addition, there are harmless mogwai ( mogwais ). Mogvai only monitor the activity of the application and write a melon in the log. For example, “fps” every 500ms shows the number of frames per second (FPS).

 mogwai fps 33.21 mogwai fps 59.45 mogwai fps 12.67 ... 


Mogwai sometimes report when gremlins did manage to harm the application. For example, if fps drops below 10, fps will display an error in the log:

 mogwai fps 12.67 mogwai fps 23.56 err > mogwai fps 7.54 < err mogwai fps 15.76 ... 


After 10 errors, a special Mogvay Gizmo will stop testing and all released gremlins. In the end, after the first 10 mistakes, you already know what you need to do to make your application more sustainable.

Gremlins, like mogwai, are simple JavaScript functions. If gremlins.js does not provide the gremlins you need, you can quite easily implement them yourself:

 //   ,    .blur()    horde.gremlin(function() { document.activeElement.blur(); }); 


Take a look at the examples folder to better understand how gremlins.js works.

You can configure any component in gremlins.js; extend the functionality and adapt it for your scenarios.

Installation



In the browser, the file gremlins.min.js can be added as a third-party library, after which gremlins will be available in the global namespace:

 <script src="path/to/gremlins.min.js"></script> <script> gremlins.createHorde().unleash(); </script> 


It is possible to connect gremlins.min.js as a RequireJS module, without littering the global namespace:

 require.config({ paths: { gremlins: 'path/to/gremlins.min' } }); require(['gremlins'], function(gremlins) { gremlins.createHorde().unleash(); }); 


Advanced use



Setting gremlinov and mogvaev for use in tests



Initially, all gremlins and mogways have already been added to the regiment ( horde ).

You can also select and add only the gremlins you need with the horde object's gremlin() method:

 gremlins.createHorde() .gremlin(gremlins.species.formFiller()) .gremlin(gremlins.species.clicker().clickTypes(['click'])) .gremlin(gremlins.species.scroller()) .gremlin(function() { window.$ = function() {}; }) .unleash(); 


To add your own Gremlins to the standard ones, use the allGremlins() method:

 gremlins.createHorde() .allGremlins() .gremlin(function() { window.$ = function() {}; }) .unleash(); 


To add mogwa, use the mogwai() and allMogwais() methods in the same way.

At the moment, gremlins.js supplies several gremlins and mogvays:



Gremlins configuration



All gremlins and mogvays supplied in gremlins.js are configurable functions , that is, you can change the logic of their methods.

For example, the gremlin clicker is a function that returns an object that you can call directly:

 var clickerGremlin = gremlins.species.clicker(); clickerGremin(); //     


Gremlin clicker has the following methods for customization:

 gremlins.species.clicker() .clickTypes(['click']) //       .canClick(function(element) { //      bar return $(element).parents('#bar').length; //  canClick  false,      //  ,  maxNbTries    }) .showAction(function(x, y) { //    clicker        //  showAction()       }) 


Each gremlin or mogvay has its own methods for customization, I advise you to study the source code of each of them.

For more information on configurable features, see the article on service closures .

Random Seed Support



If you want your attacks to be replayed, you need to initialize the random number generator. Gremlins.js uses Chance.js to generate random data, so it can be initialized:

 // seed the randomizer horde.seed(1234); 


Code execution before or after attacks



You can execute arbitrary code before testing. Usually useful:



For this, the horde object has a before() method, with a single argument that accepts callback:

 horde.before(function startProfiler() { console.profile('gremlins'); }); 


To clean the test environment, the horde object also provides the after() method:

 horde.after(function stopProfiler() { console.profileEnd(); }); 


Both methods support asynchronous callback calls:

 horde.before(function waitFiveSeconds(done) { window.setTimeout(done, 5000); }); 


Strategy



By default, gremlins will attack your application in random order, separated by 10ms. This attack strategy is called distribution . You can change it using the horde.strategy() method:

 horde.strategy(gremlins.strategies.distribution() .delay(50) //  50ms    .distribution([0.3, 0.3, 0.3, 0.1]) //           ) 


There is an opportunity to use other strategies. A strategy is simply a callback that expects three parameters: an array of gremlins, an object (returned from the unleash() result), and a final callback. Included are two more built-in strategies ( allTogether and bySpecies ) and it should be extremely easy to implement your own strategy for more specific attack scenarios.

Stop testing



To stop the attack in case of an emergency, you can use the method horde.stop() . Gizmo uses this method to prevent a subsequent attack on the application after 10 errors. You can also use this method if you do not want the attack to continue.

Modification of logging



By default, gremlins.js displays all actions of gremlins and mogva observations in the console. If you prefer to use an alternative logging method (for example, store the gremlins activity in localStorage and send them every 10 seconds with AJAX), simply transfer the logger object with four methods (log, info, warn, and error) to the logger() method :

 var customLogger = { log: function(msg) { /* .. */ }, info: function(msg) { /* .. */ }, warn: function(msg) { /* .. */ }, error: function(msg) { /* .. */ } }; horde.logger(customLogger); 


Instead of creating your own logger, look towards Minilog

Links



Source: https://habr.com/ru/post/216805/


All Articles