Apakah layak menguji unit klien API?

38

Ini adalah sesuatu yang mengganggu saya untuk sementara waktu sekarang. Apakah layak menguji unit klien API?

Katakanlah Anda membuat kelas kecil untuk abstrak-jauh panggilan ke API REST petshop. Petshop adalah API yang sangat sederhana, dan memiliki serangkaian metode dasar:

  • listProducts()
  • getProductDetails(ProductID)
  • addProduct(...)
  • removeProduct(ProductID)

Dalam menguji ini, kita harus membuat layanan tiruan atau mengejek tanggapan. Tapi itu tampaknya berlebihan; Saya mengerti bahwa kami ingin memastikan bahwa metode kami tidak berhenti bekerja melalui kesalahan ketik / sintaks, tetapi karena kami sedang menulis fungsi yang memanggil metode jarak jauh dan kemudian kami membuat tanggapan palsu dari metode jarak jauh itu, sepertinya buang-buang usaha dan kita sedang menguji sesuatu yang tidak bisa benar-benar gagal. Lebih buruk lagi, jika metode jarak jauh mengubah pengujian unit kami akan berlalu sementara penggunaan produksi gagal.

Saya cukup yakin saya kehilangan sesuatu, atau saya mendapatkan ujung tongkat yang salah, atau saya tidak melihat kayu untuk pepohonan. Bisakah seseorang membuat saya di jalur yang benar?

Phillip B Oldham
sumber
1
Jika ini bukan API sederhana dengan metode dasar, apakah Anda akan merasa berbeda? Bahkan sebuah gubuk harus berdiri di atas salju.
JeffO

Jawaban:

31

Tugas klien API jarak jauh adalah mengeluarkan panggilan tertentu - tidak lebih, tidak kurang. Karena itu, pengujiannya harus memverifikasi bahwa ia mengeluarkan panggilan-panggilan itu - tidak lebih, tidak kurang.

Tentu, jika penyedia API mengubah semantik tanggapan mereka, maka sistem Anda akan gagal dalam produksi. Tapi itu bukan kesalahan kelas klien Anda; itu sesuatu yang hanya bisa ditangkap dalam tes integrasi. Dengan mengandalkan kode yang tidak di bawah kendali Anda, Anda telah menyerahkan kemampuan untuk memverifikasi kebenaran melalui pengujian internal - itu adalah trade-off, dan ini adalah harganya.

Yang mengatakan, menguji kelas yang hanya terdiri dari delegasi ke kelas lain mungkin berprioritas rendah, karena ada sedikit risiko kesalahan kompleks. Tapi itu berlaku untuk setiap kelas yang hanya terdiri dari satu-liner seragam, itu tidak ada hubungannya dengan memanggil kode vendor lain.

Kilian Foth
sumber
Mmm, tidak yakin saya setuju. Anda dapat menguji yang foo()dipanggil sebelumnya bar(), tetapi itu tidak berarti menelepon foo()sebelumnya bar()adalah hal yang benar untuk dilakukan; unit test seperti itu akan lulus bahkan jika kodenya salah. Dan jika hanya itu yang dilakukan klien, menyiapkan tiruan yang memeriksa apakah foo()dipanggil sebelumnya bar()relatif merepotkan untuk sesuatu yang dapat diverifikasi dengan melihat kode klien secara sepintas.
Doval
1
Anda dapat menguji bahwa suatu add()metode menambahkan dua angka dengan benar, tetapi itu tidak berarti bahwa menambahkan adalah hal yang benar untuk dilakukan pada titik ini dalam algoritma - add()unit test akan berhasil walaupun program Anda salah. Jika itu adalah hal yang salah, maka levenshteinDistance()metode Anda yang harus disalahkan, bukan add()metodenya. Ini persis sama. Inti dari pemisahan kode menjadi metode adalah bahwa setiap metode hanya perlu peduli untuk memperbaiki satu hal.
Kilian Foth
3
Sekarang saya melihat di mana kita tidak setuju! Jika Anda mengandalkan toko hewan peliharaan eksternal, bagi saya ini berarti bahwa sistem Anda berakhir pada batas HTTP, oleh karena itu panggilan REST yang dikeluarkan adalah keluaran dan dapat diuji. Jika Anda menganggap toko hewan peliharaan bagian dari modul ini, maka ya, pola panggilan yang dikeluarkan adalah detail implementasi, dan tes unit tidak memiliki bisnis yang menentukan apa pun tentang mereka.
Kilian Foth
2
"Oleh karena itu, pengujiannya harus memverifikasi bahwa ia mengeluarkan panggilan-panggilan itu" Saya pikir itulah perspektif yang gagal saya lihat. Terima kasih!
Phillip B Oldham
1
Jadi misalnya pengujian unit saya dapat memeriksa bahwa, mengingat parameter tertentu, isi permintaan tentang eksekusi adalah yang benar?
Maria Ines Parnisari
9

Jawaban singkat:

Semua metode harus diuji unit.

Jawaban panjang:

Iya nih. Itu sangat berharga.

Ini adalah beberapa hal yang harus diuji oleh unit test pada metode pemanggilan API tersebut:

  • Bahwa Anda memberikan parameter yang dibuat dengan baik atau benar ke panggilan API.
  • Bahwa Anda merespons sesuai dengan tipe data tertentu yang dikembalikan oleh API (diejek atau tidak), misalnya mungkin ketika API mengembalikan string kosong, metode Anda harus mengembalikan nilai default (hanya contoh)
  • Bahwa metode penelepon berperilaku dengan benar ketika panggilan API menghasilkan kesalahan

Itu adalah hal-hal yang dilakukan metode yang dapat diisolasi saya mengejek layanan API, dan bahwa dengan menguji mereka dengan baik, meyakinkan Anda bahwa kesalahan tidak berasal dari kesalahan dalam kode klien yang memanggil API.

Tulains Córdova
sumber
Anda mengatakan "diejek atau tidak" ... jadi apakah boleh untuk menguji terhadap API yang asli? Dapatkah saya menyebutnya tes integrasi meskipun sepertinya Tes Unit? Atau adakah hal lain untuk menyebutnya? Saya ingin menguji bahwa pembungkus API saya melakukan apa yang dikatakannya, entah bagaimana ...
Dan Rosenstark
1
@DanRosenstark Saya kira dalam hal layanan API tidak diejek, ini adalah tes integrasi.
Tulains Córdova
Tidakkah Anda tahu dalam 5 detik jika Anda mendapatkan data kembali dengan benar ketika Anda membuat panggilan aktual ke API? Karena tiruan API bukan panggilan sungguhan, satu-satunya cara mereka gagal adalah jika mereka mengubah API ... dalam hal ini tes tiruan Anda akan berlalu tetapi panggilan sebenarnya akan gagal. Sepertinya tidak ada gunanya
MattE
5

Ini tidak akan menjadi unit test karena Anda menguji input dan output sistem Anda, lebih seperti tes integrasi terbatas.

Berhati-hatilah ketika Anda mengatakan "itu tampak seperti usaha yang sia-sia dan kami sedang menguji sesuatu yang tidak bisa benar-benar gagal" - itu bisa gagal, itu akan gagal, itu mungkin akan gagal dengan cara yang tidak dapat Anda antisipasi, kegagalan akan lebih buruk jika Anda tidak memiliki tes di tempat.

Kesalahan yang Anda lakukan di sini adalah terkait dengan penemuan roda: Melakukan panggilan ke layanan jarak jauh dan API adalah skenario yang sangat umum sehingga ada beberapa alat yang cukup bagus untuk membantu Anda mengujinya. Terakhir kali saya mengerjakan aplikasi yang terhubung ke layanan jarak jauh saya menggunakan SoapUIyang dapat melihat layanan dan melakukan panggilan palsu ke layanan itu atau berperilaku sebagai salinan lokal dari server yang Anda dapat membuat panggilan uji terhadap dan melacak melalui permintaan dan tanggapan. Butuh beberapa menit untuk mengatur dan juga sangat cepat untuk memperbarui jika antarmuka jarak jauh berubah. Saya belum menggunakannya dalam skenario REST, tetapi bahkan jika itu tidak bekerja dengan baik untuk itu (atau mungkin seseorang membaca jawaban ini di masa depan ketika ada alat yang lebih baik) Anda harus dapat menemukan alat yang dapat mengejek layanan untuk Anda dan ketika tiba saatnya untuk menyebarkan kode Anda, Anda akan senang bahwa Anda melakukannya.

glenatron
sumber