Python - doctest vs unittest [ditutup]

160

Saya mencoba untuk memulai dengan pengujian unit di Python dan saya bertanya-tanya apakah seseorang dapat menjelaskan kelebihan dan kekurangan dari doctest dan unittest.

Kondisi apa yang akan Anda gunakan untuk masing-masing?

Sean
sumber

Jawaban:

178

Keduanya berharga. Saya menggunakan kedua doctest dan hidung mengambil tempat unittest. Saya menggunakan doctest untuk kasus-kasus di mana tes ini memberikan contoh penggunaan yang sebenarnya berguna sebagai dokumentasi. Secara umum saya tidak membuat tes ini komprehensif, hanya bertujuan untuk informatif. Saya secara efektif menggunakan doctest secara terbalik: bukan untuk menguji kode saya benar berdasarkan pada doctest saya, tetapi untuk memeriksa bahwa dokumentasi saya benar berdasarkan pada kode.

Alasannya adalah bahwa saya menemukan dokumen komprehensif akan mengacaukan dokumentasi Anda terlalu banyak, sehingga Anda akan berakhir dengan dokumen yang tidak dapat digunakan, atau pengujian yang tidak lengkap.

Untuk benar-benar menguji kode , tujuannya adalah untuk menguji secara menyeluruh setiap kasus, daripada menggambarkan apa yang dilakukan dengan contoh, yang merupakan tujuan berbeda yang menurut saya lebih baik dipenuhi oleh kerangka kerja lain.

Brian
sumber
29
Ada boilerplate jauh lebih sedikit, dan saya menemukan tes lebih mudah untuk menulis (dan membaca) Biaya awal yang rendah untuk menulis tes (yaitu hanya menulis fungsi "test_foo ()" dan pergi) juga membantu melawan godaan untuk melakukan bit kode yang menarik sebelum melakukan tes Anda.
Brian
6
Saya pikir ini adalah jawaban yang fantastis.
James Brady
Kerangka kerja pengujian apa lagi yang Anda gunakan? Atau hanya hidung?
Joe
6
Mengingat usia jawaban ini, mungkin perlu disebutkan bahwa sebagian besar "boilerplate" versi lama dari unittest sebagian besar hilang. Saya masih suka Hidung lebih baik juga, tapi itu cukup banyak.
Adam Parkin
1
Hidung FYI telah berada dalam "mode pemeliharaan" selama beberapa tahun terakhir dan kemungkinan akan menghentikan semua pengembangan (tidak ada intervensi pihak ketiga). Pengelolanya menyarankan proyek baru menggunakan alternatif.
Enam
48

Saya menggunakan unittest hampir secara eksklusif.

Sekali-sekali, saya akan meletakkan beberapa barang di docstring yang dapat digunakan oleh doctest.

95% dari kasus uji adalah yang paling bebas.

Mengapa? Saya suka menyimpan dokumen agak lebih pendek dan lebih tepatnya. Kadang-kadang kasus uji membantu memperjelas dokumen. Sebagian besar waktu, kasus uji aplikasi terlalu panjang untuk didokumentasikan.

S.Lott
sumber
Akan keren untuk melihat contoh, apa yang menurut Anda cocok untuk docstringdan apa yang tidak. Saya sebenarnya suka docstring dalam istilah yang secara eksplisit menunjukkan cara menggunakan antarmuka, tetapi menggunakannya baik untuk itu dan pengujian unit mungkin tidak cocok.
user1767754
33

Keuntungan lain dari doctesting adalah Anda bisa memastikan kode Anda melakukan apa yang menurut dokumentasi Anda. Setelah beberapa saat, perubahan perangkat lunak dapat membuat dokumentasi dan kode Anda melakukan hal yang berbeda. :-)

Jason Baker
sumber
6
+1 dari saya - titik luar biasa
doug
28

Saya bekerja sebagai ahli bioinformatika, dan sebagian besar kode yang saya tulis adalah skrip "satu kali, satu tugas", kode yang akan dijalankan hanya sekali atau dua kali dan yang menjalankan satu tugas khusus.

Dalam situasi ini, menulis unittests besar mungkin berlebihan, dan doctests adalah kompromi yang bermanfaat. Mereka lebih cepat untuk menulis, dan karena mereka biasanya dimasukkan dalam kode, mereka memungkinkan untuk selalu mengawasi bagaimana kode harus berperilaku, tanpa harus membuka file lain. Itu berguna saat menulis skrip kecil.

Juga, dokumen berguna ketika Anda harus menyerahkan skrip Anda kepada seorang peneliti yang tidak ahli dalam pemrograman. Beberapa orang merasa sangat sulit untuk memahami bagaimana unittests disusun; di sisi lain, dokumen adalah contoh sederhana penggunaan, sehingga orang dapat menyalin dan menempelkannya untuk melihat cara menggunakannya.

Jadi, untuk melanjutkan jawaban saya: dokumen berguna ketika Anda harus menulis skrip kecil, dan ketika Anda harus meneruskannya atau menunjukkannya kepada peneliti yang bukan ilmuwan komputer.

dalloliogm
sumber
6
"Dokumen berguna ketika Anda harus menulis skrip kecil, dan ketika Anda harus menyerahkannya atau menunjukkannya kepada peneliti yang bukan ilmuwan komputer." Poin luar biasa. Saya melakukan hal yang sama dan programmer non-python selalu kagum bahwa dokumentasi dapat dieksekusi.
Daniel Canas
14

Jika Anda baru memulai dengan ide pengujian unit, saya akan memulainya doctestkarena sangat mudah digunakan. Ini juga secara alami menyediakan beberapa tingkat dokumentasi. Dan untuk pengujian yang lebih komprehensif doctest, Anda dapat menempatkan tes dalam file eksternal sehingga tidak mengacaukan dokumentasi Anda.

Saya menyarankan unittestjika Anda berasal dari latar belakang telah menggunakan JUnit atau yang serupa, di mana Anda ingin dapat menulis unit test pada umumnya dengan cara yang sama seperti yang Anda lakukan di tempat lain.

Greg Hewgill
sumber
4
Saya didorong ke arah ini ( doctestuntuk mulai dengan), tetapi akhirnya menyesalinya. Untuk kasus uji non-sepele, saya kehilangan penyorotan sintaksis dan penyelesaian otomatis editor saya. Ketika tes berada di file terpisah, saya tidak bisa lagi menjalankannya langsung dari editor - saya harus mengubah konteks kembali ke file sumber yang sesuai setiap waktu.
Oddthinking
7

Saya menggunakan unittest secara eksklusif; Saya pikir doctest mengacaukan modul utama terlalu banyak. Ini mungkin ada hubungannya dengan menulis tes menyeluruh.

Tony Arkles
sumber
7

Menggunakan keduanya adalah opsi yang valid dan agak sederhana. The doctestmodul menyediakan DoctTestSuitedanDocFileSuite metode yang membuat testsuite unittest-kompatibel dari modul atau file, masing-masing.

Jadi saya menggunakan keduanya dan biasanya menggunakan doctest untuk tes sederhana dengan fungsi yang memerlukan sedikit atau tanpa pengaturan (tipe sederhana untuk argumen). Saya benar-benar berpikir beberapa tes doctest membantu mendokumentasikan fungsi, daripada mengurangi darinya.

Tetapi untuk kasus yang lebih rumit, dan untuk serangkaian kasus uji yang lebih komprehensif, saya menggunakan unittest yang memberikan lebih banyak kontrol dan fleksibilitas.

davidavr
sumber
7

Saya tidak menggunakan doctest sebagai pengganti unittest. Meskipun sedikit tumpang tindih, kedua modul tidak memiliki fungsi yang sama:

  • Saya menggunakan unittestsebagai kerangka kerja pengujian unit, yang berarti membantu saya menentukan dengan cepat dampak dari modifikasi apa pun pada sisa kode.

  • Saya menggunakan doctestsebagai jaminan bahwa komentar (yaitu docstrings) masih relevan dengan versi kode saat ini.

Manfaat yang didokumentasikan secara luas dari pengembangan yang didorong oleh tes yang saya dapatkan unittest. doctestmemecahkan bahaya yang jauh lebih halus karena komentar yang ketinggalan zaman menyesatkan pemeliharaan kode.

rahmu
sumber
4

Saya hampir tidak pernah menggunakan dokumen. Saya ingin kode saya menjadi dokumentasi diri, dan dokumen menyediakan dokumentasi kepada pengguna. IMO menambahkan ratusan baris tes ke modul membuat dokumen jauh lebih mudah dibaca. Saya juga menemukan tes unit lebih mudah untuk dimodifikasi saat diperlukan.

JimB
sumber
4

Doctestbeberapa kali dapat menyebabkan hasil yang salah. Terutama ketika output berisi urutan melarikan diri. Sebagai contoh

def convert():
    """
    >>> convert()
    '\xe0\xa4\x95'
    """
    a = '\xe0\xa4\x95'
    return a
import doctest
doctest.testmod()

memberi

**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
    convert()
Expected:
    'क'
Got:
    '\xe0\xa4\x95'
**********************************************************************
1 items had failures:
   1 of   1 in __main__.convert
***Test Failed*** 1 failures. 

Juga tidak memeriksa jenis output. Itu hanya membandingkan string output. Misalnya ia telah membuat beberapa tipe rasional yang mencetak seperti integer jika bilangan bulat. Maka anggaplah Anda memiliki fungsi yang mengembalikan rasional. Jadi, doctest tidak akan membedakan jika outputnya bilangan bulat rasional atau bilangan bulat.

Keras
sumber
5
Anda dapat menggunakan dokumen mentah ( r""" ... """) untuk memperbaiki masalah pertama.
icktoofay
Bekerja dengan baik di Python 3.4. Untuk membuatnya bekerja di Python 2.7 juga, gunakan '\\xe0\\xa4\\x95'di docstring Anda.
Cees Timmerman
Saya juga menemukan bahwa unicode literal juga tidak berfungsi dengan doctests (bahkan dengan baris komentar 'coding utf-8' yang tepat di bagian atas file. Secara umum doctests tidak didukung dengan baik sebagai tes yang belum dikirim, jadi ada beberapa bug itu tidak diperbaiki
RichVel
2

Saya lebih suka sistem berbasis penemuan ("hidung" dan "py.test", menggunakan mantan saat ini).

doctest bagus ketika tes juga baik sebagai dokumentasi, jika tidak mereka cenderung terlalu banyak mengacaukan kode.

lazy1
sumber
hidung terlihat sangat bermanfaat; Saya belum mendapatkan kesempatan untuk menggunakannya, tapi saya punya harapan tinggi :)
Tony Arkles
Hidung adalah kerangka uji yang paling mudah digunakan, IMO. Itu membuat menulis dan menjalankan test case sangat mudah.
Kamil Kisiel