Otomasi QAPelajaran 2 dari 12
EnglishFondasi pemrograman untuk tester
Variabel, fungsi, async, dan membaca kode orang lain — jalur JS/TS.
18 mntOtomasi QA
Anda tidak sedang menjadi developer
Anda sedang menjadi orang yang bisa membaca dan mengubah kode pengujian tanpa takut kepadanya. Itu sasaran yang jauh lebih kecil daripada "belajar JavaScript", dan ia bisa dicapai dalam dua minggu.
Dua hal mengikutinya. Pertama, yang Anda butuhkan mungkin sepersepuluh bahasanya — sepersepuluh yang ada di halaman ini. Kedua, membaca lebih penting daripada menulis: pekerjaan otomasi pertama nyaris tidak pernah berupa suite dari nol. Ia repositori yang dibangun orang lain, dengan 400 pengujian, tiga helper yang tidak Anda pahami, dan satu job gagal yang tidak dilihat siapa pun sejak Selasa.
Kenapa JavaScript dan TypeScript di sini: ia bahasa milik browser sendiri, ia bahasa penulis Playwright, dan ia hampir pasti sudah ada di repositori tim Anda. Python dengan pytest adalah jalur yang sama terhormatnya dan setiap konsep di bawah bisa dipindahkan — sintaksnya berjarak satu minggu, bukan satu karier.
Yang perlu terpasang
Node.js (LTS terkini) dan sebuah editor — VS Code, kecuali Anda sudah punya pendapat sendiri. Lalu:
node -v
Kalau itu mencetak sebuah versi, Anda selesai. Playwright-nya sendiri datang di pelajaran berikutnya.
Nilai, dan dua kata yang paling sering Anda ketik
const orderId = "ord_8831"; // tidak pernah ditugaskan ulang
let attempts = 0; // yang ini berubah
attempts = attempts + 1;
const sebagai bawaan, let ketika nilainya memang berubah, var jangan
pernah. Menjadikan const bawaan bukan kerewelan gaya — artinya editor Anda
menangkap penugasan ulang yang tak sengaja, dan di kode pengujian itu biasanya
bug yang kalau tidak begitu akan memakan satu jam Anda.
Tipe-tipe yang akan Anda temui: string, number, boolean, array, object, dan dua rasa dari ketiadaan.
const name = "Ada"; // string
const total = 41.5; // number
const isPaid = true; // boolean
const codes = ["A1", "B2"]; // array
const order = { id: "ord_8831", status: "PAID", total: 41.5 }; // object
order.status; // "PAID" — notasi titik
codes[0]; // "A1" — array mulai dari 0
codes.length; // 2
null berarti sengaja dikosongkan; undefined berarti tidak pernah
disetel. Perbedaannya penting karena kolom yang tiba sebagai undefined
padahal Anda mengharapkan null biasanya berarti API-nya sama sekali tidak
mengirimnya — dan itu sebuah temuan, bukan gangguan.
Template string adalah hal lain yang akan terus-menerus Anda ketik, untuk membangun URL dan pesan kegagalan:
const url = `/api/v1/orders/${orderId}`;
Backtick, bukan tanda kutip, dan ${...} untuk apa pun yang ingin Anda
sisipkan.
Destructuring layak sepuluh menit hidup Anda karena API Playwright sendiri memakainya di setiap pengujian:
const { id, status } = order; // dua variabel dari satu objek
Itu persis yang dilakukan async ({ page }) => { ... } di bawah nanti: menarik
page keluar dari objek yang diserahkan Playwright kepada Anda.
Fungsi
// deklarasi
function totalWithTax(amount: number) {
return amount * 1.2;
}
// arrow function — bentuk yang akan Anda lihat di berkas pengujian
const totalWithTax = (amount: number) => amount * 1.2;
Keduanya melakukan hal yang sama di sini. Arrow function mendominasi kode pengujian karena pengujian ditulis dengan cara menyerahkan sebuah fungsi ke sesuatu yang lain:
test("checkout shows a confirmation", async ({ page }) => {
// ...
});
Bacalah itu sebagai: panggil test, serahkan kepadanya sebuah nama dan sebuah
fungsi untuk dijalankan nanti. Fungsinya tidak dieksekusi di baris itu;
Playwright yang menentukan kapan. Begitu itu klik, sebagian besar sintaks
framework pengujian berhenti terlihat seperti sihir.
Perbandingan, dan yang satu ini menggigit
"5" === 5 // false — tipenya berbeda. Pakai yang ini.
"5" == 5 // true — mengonversi dulu. Hindari.
Selalu ===. Yang longgar ada karena alasan sejarah dan menghasilkan persis
kelas kebingungan yang Anda dibayar untuk mencegahnya.
Jebakan yang satunya adalah falsiness. Semua ini "falsy": false, 0, "",
null, undefined, NaN.
if (order.total) { /* ... */ } // dilewati ketika total 0 — bug sungguhan
if (order.total !== undefined) { } // yang sebenarnya Anda maksud
Pesanan gratis dengan total 0 yang lenyap dari sebuah pemeriksaan adalah cacat
di pengujian Anda, dan itu yang paling umum terjadi.
Perulangan dan daftar
for (const code of codes) {
console.log(code);
}
const paid = orders.filter((o) => o.status === "PAID");
const ids = orders.map((o) => o.id);
const one = orders.find((o) => o.id === "ord_8831");
filter, map, dan find mencakup sebagian besar yang akan Anda butuhkan,
dan for...of mencakup sisanya. Pengujian berbasis data dibangun persis dari
ini:
const cases = [
{ input: "abc", valid: false },
{ input: "Abc12345", valid: true },
];
for (const c of cases) {
test(`password "${c.input}" is ${c.valid ? "accepted" : "rejected"}`, async () => {
// ...
});
}
Satu perulangan, N pengujian, masing-masing dengan namanya sendiri — dan itulah bentuk yang Anda inginkan, bukan satu pengujian dengan perulangan di dalamnya. Perulangan di dalam sebuah pengujian berhenti pada kegagalan pertama dan menyembunyikan sisanya.
Async: bagian yang benar-benar penting
Semua yang dilakukan browser memakan waktu, jadi hampir setiap panggilan
Playwright mengembalikan sebuah Promise — sebuah objek yang berarti "nilai
yang belum ada di sini". await berkata "tunggu, lalu berikan hasilnya
kepada saya".
test("checkout", async ({ page }) => { // perhatikan: async
await page.goto("/cart");
await page.getByRole("button", { name: "Checkout" }).click();
await expect(page.getByText("Thank you")).toBeVisible();
});
Aturannya: kalau ia mengembalikan Promise, await. await yang hilang adalah
sumber terbesar kegagalan pengujian yang membingungkan dan kadang-kadang di
ekosistem ini, dan alasannya layak dipahami alih-alih dihafal:
page.getByRole("button", { name: "Checkout" }).click(); // TIDAK di-await
await expect(page.getByText("Thank you")).toBeVisible(); // berlomba dengan klik
Klik-nya dimulai, bukan diselesaikan. Eksekusi langsung berlanjut, asersinya berjalan terhadap halaman yang sedang di tengah navigasi, dan ia gagal mungkin satu dari lima kali jalan — di mesin CI yang lambat, dan tidak pernah di laptop Anda. Lebih buruk lagi, ketika sebuah pengujian berakhir selagi operasi yang tidak di-await masih berjalan, error-nya muncul di pengujian berikutnya, dan itu mengirim Anda men-debug berkas yang tidak rusak.
Dua konsekuensinya:
awaithanya bekerja di dalam fungsi yang ditandaiasync— dan itulah sebabnya setiap callback pengujian Playwright berupaasync ({ page }).- Kalau sebuah pengujian gagal dengan cara yang tidak masuk akal, periksa
awaityang hilang sebelum memeriksa apa pun yang lain. Editor dan linter bisa menandainya; nyalakan itu sejak awal.
Membaca suite milik orang lain
Keahlian yang sesungguhnya, dan ia punya metode:
- Mulai dari nama pengujiannya. Nama yang baik memberi tahu Anda klaim yang sedang dibuat. Kalau namanya buruk, itu temuan pertama Anda tentang suite-nya.
- Temukan asersinya lebih dulu.
expect(...)adalah apa yang diklaim benar oleh pengujiannya; segala yang di atasnya adalah persiapan. Membaca mundur dari asersinya jauh lebih cepat daripada membaca maju dari baris pertama. - Ikuti import-nya.
import { loginAs } from "./helpers/auth"memberi tahu Anda di mana mesin bersamanya tinggal. Buka sekali; Anda akan bertemu ia di setiap berkas. - Jalankan satu pengujian secara terpisah dan tontonlah. Sepuluh detik menonton mengalahkan sepuluh menit membaca.
- Jangan ubah apa pun yang kosmetik di hari pertama. Mengganti nama variabel sesuai selera Anda di suite yang belum Anda pahami menghasilkan diff yang besar, nol informasi, dan seorang peninjau yang kini kurang memercayai Anda.
TypeScript, sebanyak yang Anda butuhkan bulan ini
TypeScript adalah JavaScript dengan tipe yang dilekatkan. Yang ia beli untuk
seorang tester langsung terasa dan praktis: editor memberi tahu Anda apa yang
diterima page.getByRole( sebelum Anda menjalankan apa pun, dan salah ketik
menjadi garis merah alih-alih kegagalan pengujian tiga menit.
const orderId: string = "ord_8831";
function totalWithTax(amount: number): number {
return amount * 1.2;
}
type Order = { id: string; status: "PAID" | "PENDING"; total: number };
Baris ketiga itulah yang layak diperhatikan: status selamanya hanya bisa
berupa salah satu dari dua string, jadi salah ketik seperti "PAId" tertangkap
selagi Anda mengetik. Generic, decorator, dan sisa sistem tipenya bisa menunggu
tanpa batas waktu.
Git, dalam satu paragraf
Anda akan segera berada di repositori yang sama dengan para developer, jadi: buat
sebuah branch, jaga commit tetap kecil, buka pull request, harapkan komentar
tinjauan dan jangan menerimanya secara pribadi. git status sebelum apa pun,
dan jangan pernah meng-commit sebuah .only — satu test.only yang
tertinggal di sebuah berkas mengubah seluruh suite CI menjadi satu pengujian,
hijau tanpa suara.
Error yang akan Anda temui di minggu pertama
| Pesan | Biasanya berarti |
|---|---|
Cannot read properties of undefined (reading 'id') | Hal sebelum titiknya tidak ada — biasanya langkah persiapan yang tidak berjalan, atau await yang hilang |
x is not a function | Salah ketik nama, atau Anda meng-import hal yang keliru |
Timeout 30000ms exceeded waiting for locator | Elemennya tidak pernah muncul: locator keliru, atau halamannya memang rusak — periksa yang mana sebelum "membetulkan" locator-nya |
| Unhandled rejection setelah sebuah pengujian lulus | Sebuah Promise yang tidak di-await siapa pun, di pengujian yang barusan "lulus" |
SyntaxError: Unexpected token | Hampir selalu sebuah kurung atau tanda kutip, di baris yang dilaporkan atau tepat sebelumnya |
Baca error pertama, bukan yang terakhir. Semua sesudahnya biasanya konsekuensi.
Di mana TestForge berperan
Satu keputusan yang sebaiknya diambil sekarang alih-alih nanti: namai pengujian
Anda supaya ia memetakan ke case Anda. Karya penutup di track ini mengunggah
JUnit XML ke /api/v1/junit, dan pencocokannya dilakukan berdasarkan nama
pengujian — jadi pengujian bernama "TC-SHOP-14 checkout with an expired discount code" menjadi sebuah hasil pada case yang sudah Anda tulis, sementara
"test checkout 2" menjadi anak yatim yang harus direkonsiliasi seseorang
dengan tangan.
Polanya adalah TC-<PROJECT>-<nomor>, dengan <PROJECT> adalah slug proyek
Anda (SHOP di atas) dan nomornya adalah nomor case di dalamnya. Slug-nya jadi
bagian darinya karena nomor case hanya berlaku di dalam satu proyek. Karya
penutup membahas detailnya; yang penting sekarang adalah memutuskan untuk membawa
sebuah id sama sekali.
Memutuskan konvensi itu di minggu pertama Anda tidak berbiaya apa pun. Memasangnya belakangan ke 400 pengujian berbiaya satu sprint.
Selanjutnya: memasang Playwright dan menulis pengujian pertama — lalu memahami setiap baris dari yang baru saja Anda tulis.
Uji pemahaman Anda
3 pertanyaan. Tidak perlu akun, dan tidak ada yang dikirim ke mana pun selain ke pemeriksa jawaban.
1. Sebuah pengujian lulus di laptop Anda dan gagal kira-kira satu dari lima kali jalan di CI, dan error-nya kadang muncul di pengujian berikutnya. Apa yang Anda periksa lebih dulu?
2. Anda diserahi suite 400 pengujian yang asing dan diminta mencari tahu apa yang sebenarnya diperiksa oleh satu pengujian yang gagal. Apa langkah pertama yang tercepat?
3. Mana di antara ini yang merupakan kebiasaan sehat ketika bekerja di sebuah repositori pengujian untuk pertama kalinya?(pilih semua yang sesuai)