Abstraction of Testing

abdulghofurme

abdulghofurme

Posted on September 26, 2021

Abstraction of Testing

Sebelum kita jauh belajar mengenai testing, mari kita buat contoh sederhana dari 0, agar lebih mudah untuk memahami.

Well, sesuai namanya testing, digunakan untuk memeriksa kode kita,
dan sesegera mungkin mengidentifikasi di mana letak kesalahannya.

Dari kode berikut kita menemukan error

if (result !== expected) throw new Error(`${result} is not equal to ${expected}`)
                         ^

Error: -4 is not equal to 10
    at Object.<anonymous> (/simple.js:6:32)
Enter fullscreen mode Exit fullscreen mode

Separate code & testing

Alih alih menempatkan target testing & testing code kita dalam 1 file, mari kita pisahkan terlebih dahulu.

Kode kita dalam math.js

const sum = (a, b) => a - b;
const subtract = (a, b) => a - b;

module.exports = {
  sum,
  subtract,
};
Enter fullscreen mode Exit fullscreen mode

Dan testing code kita dalam assertion-library.js

const { sum, subtract } = require("./math");

let result, expected;

result = sum(3, 7);
expected = 10;
if (result !== expected)
  throw new Error(`${result} is not equal to ${expected}`);

result = subtract(7, 3);
expected = 4;
if (result !== expected)
  throw new Error(`${result} isn not equal to ${expected}`);
Enter fullscreen mode Exit fullscreen mode

Refactor Assertion Library

Pada testing file, kita melihat kode yang berulang.

if (result !== expected)
  throw new Error(`${result} is not equal to ${expected}`);
Enter fullscreen mode Exit fullscreen mode

Untuk satu/dua testing mungkin tidak masalah.
Namun akan jadi masalah untuk banyak testing.

Mari kita sederhanakan

// assetion-library.js
const { sum, subtract } = require("./math");

let result, expected;

result = sum(3, 7);
expected = 10;
expect(result).toEqual(expected);

result = subtract(7, 3);
expected = 4;
expect(result).toEqual(expected);

function expect(actual) {
  return {
    toEqual(expected) {
      if (actual !== expected)
        throw new Error(`${actual} is not equal to ${expected}`);
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

Anyway, ini juga bertujuan untuk membuat pesan error lebih konsisten.
Dan tentu saja kita dapat menambah fungsi selain toEqual,
seperti toBe, toBeGreaterThan dan lainnya

Mengatasi "failed test menghentikan eksekusi kode"

Sadar atau tidak,
pada kode di atas, apabila kita gagal test, maka test berikutnya tidak dijalankan,
dengan kata lain eksekusi kode berhenti.

Tentu saja, karena kita menggunakan throw new Error()

Mari kita ubah assertion-library untuk mengatasi hal ini.

function test(title, callback) {
  try {
    callback();
    console.log(`✅  ${title}`);
  } catch (error) {
    console.error(`❌ ${title}`);
    console.log(error);
  }
}
Enter fullscreen mode Exit fullscreen mode
  • try catch di atas berfungsi untuk mengatasi throw new Error, dengan begitu, failed test tidak akan menhentikan eksekusi testing file.
  • berfungsi juga untuk merapikan pesan yang tampil kepada kita

Adapun implementasinya

test("sum function", () => {
  const result = sum(3, 7);
  const expected = 10;
  expect(result).toEqual(expected);
});
Enter fullscreen mode Exit fullscreen mode

Maka pesan yang akan kita terima

 sum function
Error: -4 is not equal to 10
    at Object.toEqual (/assertion-library.js:29:15)
    ...
  subtract function
Enter fullscreen mode Exit fullscreen mode

File penuhnya sebagai berikut

// assertion-library.js
const { sum, subtract } = require("./math");

test("sum function", () => {
  const result = sum(3, 7);
  const expected = 10;
  expect(result).toEqual(expected);
});

test("subtract function", () => {
  const result = subtract(7, 3);
  const expected = 4;
  expect(result).toEqual(expected);
});

function test(title, callback) {
  try {
    callback();
    console.log(`✅  ${title}`);
  } catch (error) {
    console.error(`❌ ${title}`);
    console.log(error);
  }
}

function expect(actual) {
  return {
    toEqual(expected) {
      if (actual !== expected)
        throw new Error(`${actual} is not equal to ${expected}`);
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

Support Async Function to Test

Sejauh ini library kita bekerja,
namun apakah juga bekerja untuk fungsi dengan kondisi spesial seperti promise/async function?

mari kita buat fungsi & test-nya

// math.js
...
const sumAsync = (a, b) => Promise.resolve(sum(a, b));

module.exports = {
  ...
  sumAsync,
};
Enter fullscreen mode Exit fullscreen mode
// assertion-library.js
const { ... sumAsync } = require("./math");

...
test("sum async", async () => {
  const result = await sumAsync(3, 7);
  const expected = 10;
  expect(result).toEqual(expected);
})
...
Enter fullscreen mode Exit fullscreen mode

maka pesan yang akan kita dapat adalah

...
  sum async
/assertion-library.js:35
        throw new Error(`${actual} is not equal to ${expected}`);
              ^

Error: -4 is not equal to 10
    at Object.toEqual (/assertion-library.js:35:15)
    at /assertion-library.js:18:18
    ...
Enter fullscreen mode Exit fullscreen mode

Pengecekan berhasil, tapi menunjukkan pesan error? aneh bukan?

Karenanya kita perlu mengubah testing library kita agar bisa support baik pada fungsi biasa ataupun async function

// assertion-library.js
...
async function test(title, callback) {
  try {
    await callback();
    console.log(`✅  ${title}`);
  } catch (error) {
    console.error(`❌ ${title}`);
    console.log(error);
  }
}
...
Enter fullscreen mode Exit fullscreen mode

Dengan kode di atas, pesan yang kita dapat akan seperti berikute

 sum async
Error: -4 is not equal to 10
    at Object.toEqual (/assertion-library.js:35:15)
    at /assertion-library.js:18:18
Enter fullscreen mode Exit fullscreen mode

well, test gagal dengan pesan error, sesuai yang diharapkan.

💖 💪 🙅 🚩
abdulghofurme
abdulghofurme

Posted on September 26, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Abstraction of Testing
javascript Abstraction of Testing

September 26, 2021