27

Reusing JavaScript Tests

 4 years ago
source link: https://blog.bitsrc.io/reusing-javascript-tests-483288d3f733
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Increase test validity while decreasing costs

Nov 27 ·4min read

Mb2EVvz.jpg!web

Writing tests is hard. :triumph:

Why do we need them in the first place?

Code defines a set of instructions to perform a specific operation. Consider this function as performing the well-defined mathematical operation:

y = a + b.

Assuming the developer understands the underlying principles, he can write this correct implementation in machine code:

//seems about rightfunction Add(a,b) {
 return a + b;
}

However, noise from human error, system constraints, or other bugs may damage the code:

function Add(a,b){
 return a + ‘ ’ + b; //woops!
}

This is where tests come in. :sparkles:

Tests describe the operation in behavior-outcome language,

mirroring the code’s machine language.

Damaged code would be reflected as test failures:

import Add;test(‘add should return the sum of two numbers’, () => {
  expect(add(2,3)).toBe(5); //error! it is actually ‘2 3’!
});

Increase validity while decreasing costs

Mathematically, “regular” code is a continuous function, while tests are discrete samples of the same operation. Writing and maintaining a sample size big enough to ensure correctness could be just as difficult as writing the ‘regular’ code itself. :disappointed:

So why not reuse existing tests, as we do with our “regular” code? :smiley:

rqQnYv7.png!web

Reusing tests

I know, reusing tests is an awful experience.

Developing in existing endless interwoven code is hard enough, no matter how well-written it is.

If you ever dared to interweave tests, I bet you got a headache pretty quick.

But, I can imagine at least one use case where this would be applicable:

interface IFileSystem {
  writeFile(path, content);
  unlink(path)
  …
}//common file-system implementation:
class NodeFs implements IFileSystem {
  …
}

Most tests written for NodeFS, could, with little adaptation, be written for IFileSystem! :hushed:

Another file system could have another implementation, and still, use the same tests!

// memory-filesystem
//———————————————// in memory file system for fast short and isolated uses.
class NodeFs implements IFileSystem {
 …
}//memory-filesystem.test
//———————————————
import FileSystemTests
import MemFsFileSystemTests.validate(MemFs);

Can we do it today?

Yes!

The cost of code isolation is falling,and even tests worth the effort.

One of the most exciting tools in the domain of code isolation is Bit ( Github ). Bit is a tool and platform that helps you isolate code. Bit also offers a quick and easy way to share your isolated components to a collection in bit.dev , so that others (and your future-self) may use and even collaborate on. Bit is usually used for UI components, as a way to gradually build a UI component library but, it can easily be used for Node/JS utility functions and tests.

aI77Nju.jpg Example: Shared components in bit.dev
  1. Write your test:
import expect from ’chai’; //you gotta get it somewhere
import { IBinaryOperation } from ’math-functions’;
import { toPairs } from ’combinatorics’;function validateAssociativity<T>(
  operation: IBinaryOperation<T>,
  values: T[]) {  toPairs(values).forEach((x, y) => {
      expect(binaryOperation(x, y))
    .toEqual(binaryOperation(y, x));
  }
}export validateAssociativity;

2. Isolate the test into an atomic component using Bit :

§ bit add AssociativeTests.Ts —-id math/tests/associativity
§ bit add -c bit.envs/compilers/typescript
§ bit tag math/tests/associativity

3. Push your component to your collection in bit.dev :

(learn how to create your Bit collection here )

§ bit export collection.name math/tests/associativity

3. Now we can easily reuse our shared reusable test component:

import add from ’./add.js’;
import { validateAssociativity } from ’@bit/collection.name.math.tests.associativity’;test(‘add associativity’, () => {const sample = [1, 5, 3, 1000, 0.3, -17];
  // or maybe.. math/samples/realNumbers ..?validateAssociativity(add, sample);}

Pretty neat!

Will pngSnapshot components be the next hot thing? :crystal_ball:

Could we have checklists like Accessibility support, FPS quota, and screen responsiveness?

What do you think? :heart_eyes:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK