Повышение достоверности теста при снижении затрат
Писать тесты сложно. 😤
Зачем они вообще нужны? 🤔
Код определяет набор инструкций для выполнения определенной операции. Считайте, что эта функция выполняет четко определенную математическую операцию: y = a + b.
Предполагая, что разработчик понимает основные принципы, он может написать эту правильную реализацию в машинном коде:
//seems about right function Add(a,b) { return a + b; }
Однако шум из-за человеческой ошибки, системных ограничений или других ошибок может повредить код:
function Add(a,b){ return a + ‘ ’ + b; //woops! }
Вот тут-то и нужны тесты. ✨
Тесты описывают операцию на языке «поведение-результат»,
копируя машинный язык кода.
Поврежденный код будет отражаться как сбои теста:
import Add; test(‘add should return the sum of two numbers’, () => { expect(add(2,3)).toBe(5); //error! it is actually ‘2 3’! });
Повышение достоверности при снижении затрат
Математически «обычный» код - это непрерывная функция, а тесты - это дискретные образцы одной и той же операции. Создание и поддержание размера выборки, достаточного для обеспечения правильности, может быть столь же сложной задачей, как и написание самого «обычного» кода. 😞
Так почему бы не использовать существующие тесты повторно, как мы это делаем с нашим «обычным» кодом? 😃
Повторное использование тестов
Я знаю, что повторное использование тестов - ужасный опыт.
Разрабатывать существующий бесконечный переплетенный код достаточно сложно, независимо от того, насколько хорошо он написан.
Если вы когда-нибудь осмеливались переплетать тесты, держу пари, у вас есть головная боль довольно быстро.
Но я могу представить хотя бы один вариант использования, в котором это применимо:
interface IFileSystem { writeFile(path, content); unlink(path) … } //common file-system implementation: class NodeFs implements IFileSystem { … }
Большинство тестов, написанных для NodeFS, можно с небольшой адаптацией написать для IFileSystem! 😯
Другая файловая система могла бы иметь другую реализацию и при этом использовать те же тесты!
// memory-filesystem //——————————————— // in memory file system for fast short and isolated uses. class NodeFs implements IFileSystem { … } //memory-filesystem.test //——————————————— import FileSystemTests import MemFs FileSystemTests.validate(MemFs);
Сможем ли мы сделать это сегодня?
Да! 🥳
Стоимость изоляции кода падает, и даже тесты стоят затраченных усилий.
Одним из самых интересных инструментов в области изоляции кода является Bit (Github). Bit - это инструмент и платформа, которые помогают изолировать код. Bit также предлагает быстрый и простой способ поделиться вашими изолированными компонентами с коллекцией в bit.dev, чтобы другие (и ваше будущее) могли использовать их и даже сотрудничать. Бит обычно используется для компонентов пользовательского интерфейса как способ постепенного создания библиотеки компонентов пользовательского интерфейса, но его можно легко использовать для служебных функций и тестов Node / JS.
- Напишите свой тест:
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. Разделите тест на атомарный компонент с помощью Bit:
§ bit add AssociativeTests.Ts —-id math/tests/associativity § bit add -c bit.envs/compilers/typescript § bit tag math/tests/associativity
3. Вставьте компонент в свою коллекцию в bit.dev:
(узнайте, как создать свою коллекцию Bit здесь)
§ bit export collection.name math/tests/associativity
3. Теперь мы можем легко повторно использовать наш общий многоразовый тестовый компонент:
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); }
Довольно аккуратно! 🤯
Будут ли компоненты pngSnapshot следующей популярной вещью? 🔮
Могли бы мы иметь контрольные списки, такие как поддержка специальных возможностей, квота FPS и отзывчивость экрана?
Как вы думаете? 😍