Simple and powerful assertion library power assert

Posted by aldernon on Sat, 05 Mar 2022 15:42:17 +0100

power-assert

What is power assert

Answer in official terms

  • It is the implementation of the concept of "Power Assert" in JavaScript.
  • Descriptive assertion messages are provided through the standard assertion interface.
  • No API is the best API. With power assert, you don't need to learn many assertion library APIs (in most cases, all you need to remember is an assert(any_expression) function)
  • Stop memorizing a large number of assertion API s. Simply create an expression that returns or does not return a real value, and power assert will display it to you as part of the failure message on the screen, and you do not need to enter a message at all.
  • The core value of power assert is absolute simplicity and stability. In particular, power assert adheres to the simplest form of testing

    github address: power-assert

    preface

    The last update of this library in github was 6 months ago, and the last update in npm was 3 years ago, so it is not recommended to use it in recommended enterprise projects. It is recommended to use it only in personal or small projects. If you need a test library that is stable enough and can be used in production, you might as well have a look Jest

Compared with many common assertion libraries, power assert is simple and powerful. It does not provide many APIs. It is very simple to start and easy to migrate
This article will cover the basic browser and nodejs examples of power assert, not the complex examples

Basic example

Call assert() to pass in an expression and an error message (optional). If the expression value is true, there will be no action. If the value is false, the error message passed in by the second parameter and some useful expression information will be displayed
Let's write a failed test at random

const assert = require("assert");

const obj = { a: {c: 4} };
const arr = [1,2,34,6,7, {a: [5,7]}]

assert(obj.a.c === arr[5].a[1], "assertion failure ");

Power assert only needs to import the assert module directly
Before running, it needs some processing (it will be automatically converted to power assert). It will be explained in detail below. Let's take a look at the output results first

/root/RemoteWorking/powerAssert_/node_modules/empower/index.js:80
            throw e;
            ^

AssertionError [ERR_ASSERTION]: assertion failure    # ./test/index.js:7
  
  assert(obj.a.c === arr[5].a[1], "assertion failure ")
         |   | | |   |  |   ||               
         |   | | |   |  |   |7               
         |   | | |   |  |   [5,7]            
         |   | | |   |  Object{a:#Array#}    
         |   | | |   [1,2,34,6,7,#Object#]   
         |   | 4 false                       
         |   Object{c:4}                     
         Object{a:#Object#}                  
  
  [number] arr[5].a[1]
  => 7
  [number] obj.a.c
  => 4
  
    at Decorator._callFunc (/root/RemoteWorking/powerAssert_/node_modules/empower-core/lib/decorator.js:114:29)
    at Decorator.concreteAssert (/root/RemoteWorking/powerAssert_/node_modules/empower-core/lib/decorator.js:103:17)
    at decoratedAssert (/root/RemoteWorking/powerAssert_/node_modules/empower-core/lib/decorate.js:49:30)
    at powerAssert (/root/RemoteWorking/powerAssert_/node_modules/empower-core/index.js:63:32)
    at Object.<anonymous> (/root/RemoteWorking/powerAssert_/test/assert.js:41:1)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
  generatedMessage: false,
  code: 'ERR_ASSERTION',
  actual: false,
  expected: true,
  operator: '==',
  powerAssertContext: {
    source: {
      content: 'assert(obj.a.c === arr[5].a[1], "assertion failure ")',
      filepath: './test/index.js',
      line: 7
    },
    args: [
      {
        value: false,
        events: [
          { value: [Object], espath: 'arguments/0/left/object/object' },
          { value: [Object], espath: 'arguments/0/left/object' },
          { value: 4, espath: 'arguments/0/left' },
          {
            value: [Array],
            espath: 'arguments/0/right/object/object/object'
          },
          {
            value: [Object],
            espath: 'arguments/0/right/object/object'
          },
          { value: [Array], espath: 'arguments/0/right/object' },
          { value: 7, espath: 'arguments/0/right' },
          { value: false, espath: 'arguments/0' }
        ]
      }
    ]
  }
}

It can be seen that power assert will output the value of each part of the expression, and more detailed context information of the expression is also output below, which provides information of great reference value. In many cases, we no longer need to print information manually like other test libraries

Get started quickly

Quick experience

You can use the official example to quickly experience power assert
nodejs example: power-assert-node-seed
Browser example: power-assert-karma-seed

Recommended usage

nodejs

nodejs can be used if there are few files to test espower-cli Direct conversion code
Just install espower cli first
Then: espower source file > output target file
Then run the converted code
Like below

npm install espower-cli
espower ./test/some_test.js > ./build/test/some_test.js
node ./build/test/some_test.js

You can also configure some tools for simple automation
For use in the project, it is recommended babel-preset-power-assert Convert the code and then run the test. You can use special test tools, such as mocha in the official example, or configure the test yourself

Browser use

Because power assert itself is a nodejs module, it does not support browsers
So the official provided espowerify To support the use of power assert in browsers
When the browser interrupts to say an error, the error feedback will be printed on the browser console, which is more convenient for viewing and debugging than nodejs

Recommended Practice

The recommended practice is slightly cumbersome in the early stage, but it can be applied to situations other than many official examples

Since we won't use browse in most cases, we can make a general power assert module for the browser according to the official example, so that it can be imported and used anywhere, leaving babel configuration babel-preset-power-assert Convert code to use
The following is the detailed steps for making the browser power assert module (if you don't want to make it yourself, you can move to the end of the article to download the completed module)

power-assert Official documents mention the adoption of espowerify Support browser
 We can package it as a module that can be imported directly by the browser for us to use in different projects
 about assert Methods we directly import the self packaged browser support power-assert Just the module
 We only need to convert the corresponding test code power-assert

Packaging steps
    1. adopt browserify + espowerify take power-assert Packaged as a module available to the browser (Installation required browserify, espowerify, power-assert)
        1.The module writes this directly // power-assert.js
            const assert = require("assert");
            module.exports = assert;
        2. use browserify Package this module, that is, package contains power-assert Module of,browserify Will convert some node Built in module to,use polyfill In browser(power-assert Yes util, buffer, assert Three node Built in module)
            Run command conversion: 
                browserify -t espowerify File address above > Export address
            After this step, you get the packaged file, but brwoserify The module is not exported, so you need to export it manually
    2. Add manually esm Module export in format(Last step after package modification)
        1.Add at the top:
            let assert;
            Bottom found require('power-assert'),there require Not at all node Instead of a native function, it is a custom function,Available power-assert modular
        2.take: 
                const assert = require("assert");
                module.exports = assert;
            Replace these two lines with: 
                assert = require("assert");
            Thus, the module is assigned to the module defined above assert variable
        3. Add at the bottom:
                export default assert;
            Thus, the module we need is exported. So far, the packaging has been completed and the module is available in the browser (it can be freely imported and exported)
    3. Compression processing [recommended] (optional),Compress the code with your favorite tools
        Because the file is frequently used later, it is not used rollup + terser Compress code to make it smaller
            reference resources rollup to configure:
                // Compressed code
                import { terser } from 'rollup-plugin-terser';

                // rollup.config.js
                export default {
                    input: 'File address',
                    output: {
                        file: 'Export address',
                        format: 'esm'
                    },
                    plugins: [
                        terser(),
                    ]
                };
            You can also use other tools, which are recommended here esbuild Fast compression
            Execution: 
                esbuild File path --minify --outfile=export path
            The file can be generated
        Pro test rollup Compressed file 273 KB,but esbuild Compressed out is 280 KB,If you want to use it frequently, it is recommended to rollup + terser Compressed code

Through the above steps, we have made a general browser power assert module
Later, we can import and use it in our own projects
Just like below

import assert from "Module address";
assert("expression");

The only difference from the above code is the top import
For the transcoding part, we configure babel to complete it
In this way, we can also use power assert in webpack, rollup, parcel or other tools

last

The above example is cumbersome to use in the browser
You can Direct download The finished module is used for the browser
Because there are few tools related to power assert, it may be troublesome to use. Do a good job in the early stage and use it happily later

Topics: Javascript Front-end Back-end Testing